hfs 3.3.1 → 3.3.3
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/admin/assets/{AccountsPage-Cvi9DSc1.js → AccountsPage-C_ayTmn7.js} +1 -1
- package/admin/assets/{ArrayField-ChS9pNra.js → ArrayField-B20NUH0C.js} +1 -1
- package/admin/assets/{ConfigFilePage-6jCYVkbr.js → ConfigFilePage-Dw0-gus3.js} +1 -1
- package/admin/assets/{CustomHtmlPage-DaEXsEcQ.js → CustomHtmlPage-CLGyZfZ8.js} +1 -1
- package/admin/assets/{DataTable-Cf5S5yWr.js → DataTable-BwyFEGxv.js} +1 -1
- package/admin/assets/{DateTimeField--mTsSB1l.js → DateTimeField-ZUy9IBhM.js} +1 -1
- package/admin/assets/{EventManager-BJWba-fL.js → EventManager-DomWgRty.js} +1 -1
- package/admin/assets/{FileField-B0WhrAuk.js → FileField-Bj3P7JUc.js} +1 -1
- package/admin/assets/{InternetPage-BICQDG_K.js → InternetPage-CGMQCcBM.js} +3 -3
- package/admin/assets/{LangPage-D42UPSxC.js → LangPage-DGFrOItT.js} +1 -1
- package/admin/assets/{LogsPage-DQTrf5GE.js → LogsPage-CvCYNhID.js} +1 -1
- package/admin/assets/{MenuButton-DDfB3119.js → MenuButton-BTRAUH7H.js} +1 -1
- package/admin/assets/{MonitorPage-CH06c8aW.js → MonitorPage-CVa2ILH2.js} +1 -1
- package/admin/assets/{OptionsPage-BvXLA_R0.js → OptionsPage-C3cprG9u.js} +1 -1
- package/admin/assets/PluginsPage-CIOnncph.js +1 -0
- package/admin/assets/{Tabs-CGfV3BK0.js → Tabs-zcHwsK2s.js} +1 -1
- package/admin/assets/{TextEditor-Df9LSzm6.js → TextEditor-CDOjRy40.js} +1 -1
- package/admin/assets/{VfsPathField-6Kyy5vuQ.js → VfsPathField-DHifSPJi.js} +1 -1
- package/admin/assets/{agentIcons-DwT9U-lh.js → agentIcons-DB1m4pGa.js} +1 -1
- package/admin/assets/{baseUrl-D7S0KsqZ.js → baseUrl-Bt9R8Da2.js} +2 -2
- package/admin/assets/{icons-DWkdo8hc.js → icons-DR_Rvxtn.js} +1 -1
- package/admin/assets/index-B3difDBD.js +477 -0
- package/admin/assets/{routing-CxxvyWME.js → routing-CBrDVeFB.js} +1 -1
- package/admin/index.html +1 -1
- package/central.json +3 -0
- package/frontend/assets/{dist-legacy-zQdkj0Z9.js → dist-legacy-CSuZ0eoA.js} +1 -1
- package/frontend/assets/index-legacy-tk5ZmBDE.js +1 -0
- package/frontend/assets/{lib-legacy-CRrFEEqm.js → lib-legacy-I77jyH6j.js} +1 -1
- package/frontend/assets/{sha512-legacy-BB7Mdt0y.js → sha512-legacy-DxvM1xc4.js} +1 -1
- package/frontend/index.html +1 -1
- package/npm-shrinkwrap.json +56 -56
- package/package.json +2 -2
- package/src/api.auth.js +4 -4
- package/src/api.net.js +2 -1
- package/src/api.vfs.js +10 -5
- package/src/auth.js +2 -2
- package/src/const.js +1 -1
- package/src/cross.js +1 -2
- package/src/middlewares.js +6 -2
- package/src/nat.js +10 -7
- package/src/outboundProxy.js +1 -1
- package/src/update.js +11 -2
- package/src/updateChangelog.js +31 -0
- package/src/upload.js +5 -2
- package/src/util-os.js +12 -4
- package/admin/assets/PluginsPage-CyaVJZkM.js +0 -1
- package/admin/assets/index-BDdPG215.js +0 -477
- package/frontend/assets/index-legacy-B8EvbIOB.js +0 -1
package/src/middlewares.js
CHANGED
|
@@ -114,6 +114,7 @@ const prepareState = async (ctx, next) => {
|
|
|
114
114
|
// calculate these once and for all
|
|
115
115
|
ctx.state.connection = (0, connections_1.socket2connection)(ctx.socket);
|
|
116
116
|
// explicit credentials and existing sessions must take precedence, so a matching IP cannot override a chosen account
|
|
117
|
+
let via;
|
|
117
118
|
let a = await urlLogin() || await getHttpAccount() || !s?.username && autoLogin();
|
|
118
119
|
const loggedInNotBySession = a;
|
|
119
120
|
ctx.state.account = a ||= (0, perm_1.getAccount)(s?.username, false); // with least precedence, we consider session
|
|
@@ -123,12 +124,12 @@ const prepareState = async (ctx, next) => {
|
|
|
123
124
|
else if (loggedInNotBySession) {
|
|
124
125
|
try {
|
|
125
126
|
if (a.username)
|
|
126
|
-
await (0, auth_1.setLoggedIn)(ctx, a.username);
|
|
127
|
+
await (0, auth_1.setLoggedIn)(ctx, a.username, via);
|
|
127
128
|
}
|
|
128
129
|
catch (e) {
|
|
129
130
|
events_1.default.emit('failedLogin', { ctx, username: a.username, via: ctx.query.login ? 'url' : ctx.get('authorization') ? 'header' : undefined });
|
|
130
131
|
ctx.status = const_1.HTTP_UNAUTHORIZED;
|
|
131
|
-
ctx.body = String(e);
|
|
132
|
+
ctx.body = e instanceof Error ? e.message : String(e);
|
|
132
133
|
return;
|
|
133
134
|
}
|
|
134
135
|
ctx.headers['x-username'] = a.username; // give an easier way to determine if the login was successful
|
|
@@ -137,6 +138,7 @@ const prepareState = async (ctx, next) => {
|
|
|
137
138
|
(0, connections_1.updateConnectionForCtx)(ctx);
|
|
138
139
|
await next();
|
|
139
140
|
function urlLogin() {
|
|
141
|
+
via = 'url';
|
|
140
142
|
const { login } = ctx.query;
|
|
141
143
|
if (!login)
|
|
142
144
|
return;
|
|
@@ -145,6 +147,7 @@ const prepareState = async (ctx, next) => {
|
|
|
145
147
|
return u && (0, auth_1.clearTextLogin)(ctx, u, p, 'url');
|
|
146
148
|
}
|
|
147
149
|
function getHttpAccount() {
|
|
150
|
+
via = 'header';
|
|
148
151
|
const b64 = allowAuthorizationHeader.get() && ctx.get('authorization')?.split(' ')[1];
|
|
149
152
|
if (!b64)
|
|
150
153
|
return;
|
|
@@ -157,6 +160,7 @@ const prepareState = async (ctx, next) => {
|
|
|
157
160
|
catch { }
|
|
158
161
|
}
|
|
159
162
|
function autoLogin() {
|
|
163
|
+
via = 'net';
|
|
160
164
|
// keep the mask direct so group inheritance cannot make identity depend on account order
|
|
161
165
|
return Object.values(perm_1.accounts.get()).find(a => (0, perm_1.accountCanLogin)(a) && a.auto_login_net && (0, misc_1.netMatches)(ctx.ip, a.auto_login_net, true));
|
|
162
166
|
}
|
package/src/nat.js
CHANGED
|
@@ -82,24 +82,25 @@ exports.getPublicIps = (0, debounceAsync_1.debounceAsync)(async () => {
|
|
|
82
82
|
return ret;
|
|
83
83
|
}, { retain: 10 * cross_1.MINUTE });
|
|
84
84
|
exports.getNatInfo = (0, debounceAsync_1.debounceAsync)(async () => {
|
|
85
|
+
const MAPPINGS_TIMEOUT = 15_000; // routers enumerate rules sequentially; a few dozen mappings can take over 5 seconds
|
|
85
86
|
const upnp = await exports.upnpEnabled.getWhenReady() ? getUpnpClient() : null;
|
|
86
87
|
const gatewayIpPromise = findGateway().catch(() => undefined);
|
|
87
88
|
const gw = upnp && await (0, cross_1.haveTimeout)(10_000, upnp.getGateway()).catch(() => null);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.debug(gw ? "Mappings found:" : "Mappings not queried:", mappings?.map(x => x.description).join(', ') || (gw ? "none" : upnp ? "gateway not found" : "UPnP disabled"));
|
|
89
|
+
let mappings = gw && await (0, cross_1.haveTimeout)(MAPPINGS_TIMEOUT, upnp.getMappings())?.catch(() => null);
|
|
90
|
+
console.debug(gw ? "Mappings found:" : "Mappings not queried:", lodash_1.default.uniq(mappings?.map(x => x.description)).join(', ') || (gw ? "none" : upnp ? "gateway not found" : "UPnP disabled"));
|
|
91
91
|
const localIps = await (0, listen_1.getIps)(false);
|
|
92
92
|
const gatewayIp = await gatewayIpPromise;
|
|
93
93
|
const localIp = gw?.address || (gatewayIp ? lodash_1.default.maxBy(localIps, x => (0, cross_1.inCommon)(x, gatewayIp)) : localIps[0]);
|
|
94
|
+
const status = await (0, listen_1.getServerStatus)();
|
|
94
95
|
const internalPort = status?.https?.listening && status.https.port || status?.http?.listening && status.http.port || undefined;
|
|
95
96
|
let mapped = lodash_1.default.find(mappings, x => x.private.host === localIp && x.private.port === internalPort);
|
|
96
97
|
if (upnp && mappings && localIp && internalPort && !mapped && exports.mappedPort.get())
|
|
97
98
|
// restore the HFS-created mapping after routers that forget UPnP state across reboots
|
|
98
99
|
await (0, cross_1.haveTimeout)(5_000, upnp.createMapping(upnpMappingParam(internalPort, exports.mappedPort.get()))).then(async () => {
|
|
99
100
|
// confirm router state after restore instead of trusting the AddPortMapping result
|
|
100
|
-
mappings = await (0, cross_1.haveTimeout)(
|
|
101
|
+
mappings = await (0, cross_1.haveTimeout)(MAPPINGS_TIMEOUT, upnp.getMappings());
|
|
101
102
|
mapped = lodash_1.default.find(mappings, x => x.private.host === localIp && x.private.port === internalPort);
|
|
102
|
-
}).catch(e => console.warn('UPnP mapping restore failed:', e?.message || String(e)));
|
|
103
|
+
}).catch(e => console.warn('UPnP mapping restore failed:', e?.message || e?.errorDescription || String(e)));
|
|
103
104
|
const externalPort = mapped?.public.port;
|
|
104
105
|
if (localIp)
|
|
105
106
|
exports.defaultBaseUrl.localIp = localIp;
|
|
@@ -134,9 +135,11 @@ function getUpnpClient() {
|
|
|
134
135
|
throw Error("UPnP disabled");
|
|
135
136
|
if (!upnpClient) {
|
|
136
137
|
upnpClient = new nat_upnp_1.Client({ timeout: 4_000 });
|
|
137
|
-
const originalMethod = upnpClient.getGateway;
|
|
138
138
|
// other client methods call getGateway too, so this will ensure they reuse this same result
|
|
139
|
-
upnpClient
|
|
139
|
+
(0, cross_1.patchKey)(upnpClient, 'getGateway', was => (0, debounceAsync_1.debounceAsync)(() => was.apply(upnpClient), { retain: cross_1.HOUR, retainFailure: 30_000 }));
|
|
140
|
+
const f = (0, cross_1.patchKey)(upnpClient, 'getMappings', was => (0, debounceAsync_1.debounceAsync)(() => was.apply(upnpClient), { retain: cross_1.MINUTE }));
|
|
141
|
+
for (const k of ['createMapping', 'removeMapping']) // these methods must invalidate the cache
|
|
142
|
+
(0, cross_1.patchKey)(upnpClient, k, (was) => (...args) => was.apply(upnpClient, args).finally(f.clearRetain));
|
|
140
143
|
}
|
|
141
144
|
return upnpClient;
|
|
142
145
|
}
|
package/src/outboundProxy.js
CHANGED
|
@@ -44,7 +44,7 @@ config_1.configReady.then(async (startedWithoutConfig) => {
|
|
|
44
44
|
// it can be like "IP:PORT" or "http=IP:PORT;https=IP:PORT;ftp=IP:PORT"
|
|
45
45
|
const url = (0, cross_1.prefix)('https://', /https=([\d:.]+)/.exec(out)?.[1]) // prefer https
|
|
46
46
|
|| (0, cross_1.prefix)('http://', /http=([\d:.]+)/.exec(out)?.[1])
|
|
47
|
-
|| !read.includes('=') && 'http://' + read; // simpler form
|
|
47
|
+
|| !read.includes('=') && (read.includes('://') ? read : 'http://' + read); // simpler form
|
|
48
48
|
if (!url)
|
|
49
49
|
return;
|
|
50
50
|
outboundProxy.set(url);
|
package/src/update.js
CHANGED
|
@@ -28,6 +28,7 @@ const persistence_1 = require("./persistence");
|
|
|
28
28
|
const lodash_1 = __importDefault(require("lodash"));
|
|
29
29
|
const argv_1 = require("./argv");
|
|
30
30
|
const promises_2 = require("stream/promises");
|
|
31
|
+
const updateChangelog_1 = require("./updateChangelog");
|
|
31
32
|
const updateToBeta = (0, config_1.defineConfig)(misc_1.CFG.update_to_beta, false);
|
|
32
33
|
const autoCheckUpdate = (0, config_1.defineConfig)(misc_1.CFG.auto_check_update, true);
|
|
33
34
|
const lastCheckUpdate = persistence_1.storedMap.singleSync('lastCheckUpdate', 0);
|
|
@@ -69,14 +70,17 @@ function prepareRelease(r) {
|
|
|
69
70
|
assets: r.assets.map((a) => lodash_1.default.pick(a, ReleaseAssetKeys))
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
|
-
async function getVersions(filter, max = 30) {
|
|
73
|
+
async function getVersions(filter, max = 30, stopAtCurrent = false) {
|
|
73
74
|
const ret = [];
|
|
74
75
|
for await (const x of (0, github_1.apiGithubPaginated)(`repos/${const_1.HFS_REPO}/releases`)) {
|
|
75
76
|
if (x.name.endsWith('-ignore'))
|
|
76
77
|
continue;
|
|
77
78
|
const rel = prepareRelease(x);
|
|
78
|
-
if (rel.versionScalar === curV)
|
|
79
|
+
if (rel.versionScalar === curV) {
|
|
80
|
+
if (stopAtCurrent)
|
|
81
|
+
break; // stop at the installed release, not at older maintenance releases published more recently
|
|
79
82
|
continue;
|
|
83
|
+
}
|
|
80
84
|
if (!filter || filter(rel))
|
|
81
85
|
ret.push(rel);
|
|
82
86
|
if (ret.length >= max)
|
|
@@ -93,6 +97,11 @@ async function getUpdates(strict = false) {
|
|
|
93
97
|
const betas = !includeBetas ? [] : await getVersions(x => x.prerelease && x.versionScalar > stable.versionScalar && (!strict || x.isNewer));
|
|
94
98
|
if (stable.isNewer || const_1.RUNNING_BETA && !strict)
|
|
95
99
|
betas.push(stable);
|
|
100
|
+
if (stable.isNewer && stable.body) {
|
|
101
|
+
const history = await getVersions(r => !r.prerelease && r.isNewer && r.versionScalar <= stable.versionScalar, Infinity, true)
|
|
102
|
+
.catch(() => []); // missing history must not prevent installing an available update
|
|
103
|
+
stable.body = (0, updateChangelog_1.updateChangelog)(stable, history, curV);
|
|
104
|
+
}
|
|
96
105
|
return betas;
|
|
97
106
|
}
|
|
98
107
|
const LOCAL_UPDATE = 'hfs-update.zip'; // update from file takes precedence over net
|
|
@@ -0,0 +1,31 @@
|
|
|
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.updateChangelog = updateChangelog;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
+
function updateChangelog(destination, releases, currentVersion) {
|
|
9
|
+
const newer = lodash_1.default.sortBy(lodash_1.default.uniqBy([destination, ...releases], 'tag_name')
|
|
10
|
+
.filter(r => !r.prerelease && r.versionScalar > currentVersion && r.versionScalar <= destination.versionScalar), r => -r.versionScalar);
|
|
11
|
+
const level = Math.max(...newer.map(releaseLevel));
|
|
12
|
+
const seen = new Set();
|
|
13
|
+
const sections = newer.filter(r => releaseLevel(r) === level).map(r => {
|
|
14
|
+
let body = r.body.trim();
|
|
15
|
+
if (level === 0) {
|
|
16
|
+
// deduplicate complete entries, preserving continuation lines and nested lists
|
|
17
|
+
body = body.replace(/\r\n/g, '\n').split(/\n{2,}|\n(?=[*+-] )/).filter(entry => {
|
|
18
|
+
const key = entry.trim().replace(/^[*+-] /, '');
|
|
19
|
+
if (!key || seen.has(key))
|
|
20
|
+
return false;
|
|
21
|
+
seen.add(key);
|
|
22
|
+
return true;
|
|
23
|
+
}).join('\n\n');
|
|
24
|
+
}
|
|
25
|
+
return { tag: r.tag_name, body };
|
|
26
|
+
}).filter(r => r.body);
|
|
27
|
+
return sections.map(r => r.tag === destination.tag_name ? r.body : `**${r.tag}**\n\n${r.body}`).join('\n\n') || destination.body;
|
|
28
|
+
function releaseLevel(r) {
|
|
29
|
+
return r.versionScalar % 1E6 === 0 ? 2 : r.versionScalar % 1E3 === 0 ? 1 : 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/upload.js
CHANGED
|
@@ -125,11 +125,14 @@ function uploadWriter(base, baseUri, filename, ctx) {
|
|
|
125
125
|
if (firstCreated) {
|
|
126
126
|
setUploadMeta(dir, ctx);
|
|
127
127
|
// recursive mkdir returns the first created directory; existing ancestors must not receive ownership
|
|
128
|
-
const
|
|
128
|
+
const firstCreatedPath = (0, path_1.toNamespacedPath)((0, path_1.resolve)(firstCreated)); // Node 24 mkdir can return a namespace-prefixed Windows path
|
|
129
129
|
let source = (0, path_1.resolve)(dir);
|
|
130
130
|
let uri = path_1.posix.dirname(vfsUri);
|
|
131
|
-
while (
|
|
131
|
+
while (true) {
|
|
132
132
|
createdFolders.push({ uri, source });
|
|
133
|
+
// stop before the existing parent: namespaced drive and UNC roots can differ in their trailing separator
|
|
134
|
+
if ((0, path_1.toNamespacedPath)(source) === firstCreatedPath)
|
|
135
|
+
break;
|
|
133
136
|
source = (0, path_1.dirname)(source);
|
|
134
137
|
uri = path_1.posix.dirname(uri);
|
|
135
138
|
}
|
package/src/util-os.js
CHANGED
|
@@ -23,8 +23,12 @@ const const_1 = require("./const");
|
|
|
23
23
|
const promises_1 = require("node:fs/promises");
|
|
24
24
|
const DF_TIMEOUT = 2000;
|
|
25
25
|
function getDiskSpaceSync(path) {
|
|
26
|
-
while (path && !(0, misc_1.isWindowsDrive)(path) && !(0, fs_1.existsSync)(path))
|
|
27
|
-
|
|
26
|
+
while (path && !(0, misc_1.isWindowsDrive)(path) && !(0, fs_1.existsSync)(path)) {
|
|
27
|
+
const parent = (0, path_1.dirname)(path);
|
|
28
|
+
if (parent === path)
|
|
29
|
+
break; // an unavailable root has no other parent to try
|
|
30
|
+
path = parent;
|
|
31
|
+
}
|
|
28
32
|
const res = (0, fs_1.statfsSync)(path);
|
|
29
33
|
return { free: res.bavail * res.bsize, total: res.blocks * res.bsize, name: path };
|
|
30
34
|
}
|
|
@@ -35,8 +39,12 @@ function cmdEscape(par) {
|
|
|
35
39
|
return `"${par.replaceAll('"', '\\"')}"`;
|
|
36
40
|
}
|
|
37
41
|
async function getDiskSpace(path) {
|
|
38
|
-
while (path && !(0, misc_1.isWindowsDrive)(path) && !await (0, misc_1.exists)(path))
|
|
39
|
-
|
|
42
|
+
while (path && !(0, misc_1.isWindowsDrive)(path) && !await (0, misc_1.exists)(path)) {
|
|
43
|
+
const parent = (0, path_1.dirname)(path);
|
|
44
|
+
if (parent === path)
|
|
45
|
+
break; // an unavailable root has no other parent to try; this test covers UNC as well
|
|
46
|
+
path = parent;
|
|
47
|
+
}
|
|
40
48
|
const res = await (0, promises_1.statfs)(path);
|
|
41
49
|
return { free: res.bavail * res.bsize, total: res.blocks * res.bsize, name: path };
|
|
42
50
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-CacB07dV.js";import{a as t,i as n,r,t as i}from"./DataTable-Cf5S5yWr.js";import{t as a}from"./DateTimeField--mTsSB1l.js";import{a as o,t as s}from"./Tabs-CGfV3BK0.js";import{t as c}from"./VfsPathField-6Kyy5vuQ.js";import{$i as l,Bn as u,Bt as d,C as f,Da as p,E as ee,Ea as m,H as te,K as h,L as ne,Ma as g,Mn as re,Pa as ie,Rr as ae,Rt as oe,S as _,Ta as v,Tn as se,U as ce,Ut as le,W as ue,Xt as de,Zn as fe,_ as pe,_n as me,_t as y,ai as b,ar as he,bt as ge,c as _e,ea as x,er as ve,fr as ye,ft as be,ga as S,gt as C,ha as w,ht as T,ia as xe,ir as E,it as Se,j as D,l as O,lr as k,ma as A,mn as j,mt as Ce,na as M,nn as we,o as N,oa as P,pr as Te,rr as F,s as Ee,tr as De,tt as Oe,u as ke,un as I,v as L,va as Ae,wi as je,xt as Me,y as R,zt as z}from"./index-BDdPG215.js";import{$ as Ne,K as Pe,R as Fe,a as Ie,et as Le,g as Re,i as ze,n as Be,o as Ve,r as He,rt as Ue,s as We,t as Ge}from"./icons-DWkdo8hc.js";import{t as B}from"./ArrayField-ChS9pNra.js";import{t as Ke}from"./routing-CxxvyWME.js";import{t as qe}from"./FileField-B0WhrAuk.js";function Je(e){return w(`MuiTable`,e)}A(`MuiTable`,[`root`,`stickyHeader`]);var V=e(ie(),1),H=Ae();p();var Ye=[`className`,`component`,`padding`,`size`,`stickyHeader`],Xe=e=>{let{classes:t,stickyHeader:n}=e;return P({root:[`root`,n&&`stickyHeader`]},Je,t)},Ze=M(`table`,{name:`MuiTable`,slot:`Root`,overridesResolver:(e,t)=>{let{ownerState:n}=e;return[t.root,n.stickyHeader&&t.stickyHeader]}})(x(({theme:e})=>({display:`table`,width:`100%`,borderCollapse:`collapse`,borderSpacing:0,"& caption":m(m({},e.typography.body2),{},{padding:e.spacing(2),color:(e.vars||e).palette.text.secondary,textAlign:`left`,captionSide:`bottom`}),variants:[{props:({ownerState:e})=>e.stickyHeader,style:{borderCollapse:`separate`}}]}))),U=`table`,Qe=V.forwardRef(function(e,n){let r=l({props:e,name:`MuiTable`}),{className:i,component:a=U,padding:o=`normal`,size:s=`medium`,stickyHeader:c=!1}=r,u=v(r,Ye),d=m(m({},r),{},{component:a,padding:o,size:s,stickyHeader:c}),f=Xe(d),p=V.useMemo(()=>({padding:o,size:s,stickyHeader:c}),[o,s,c]);return(0,H.jsx)(t.Provider,{value:p,children:(0,H.jsx)(Ze,m({as:a,role:a===U?null:`table`,ref:n,className:S(f.root,i),ownerState:d},u))})});function $e(e){return w(`MuiTableBody`,e)}A(`MuiTableBody`,[`root`]),p();var et=[`className`,`component`],tt=e=>{let{classes:t}=e;return P({root:[`root`]},$e,t)},nt=M(`tbody`,{name:`MuiTableBody`,slot:`Root`})({display:`table-row-group`}),rt={variant:`body`},W=`tbody`,it=V.forwardRef(function(e,t){let r=l({props:e,name:`MuiTableBody`}),{className:i,component:a=W}=r,o=v(r,et),s=m(m({},r),{},{component:a}),c=tt(s);return(0,H.jsx)(n.Provider,{value:rt,children:(0,H.jsx)(nt,m({className:S(c.root,i),as:a,ref:t,role:a===W?null:`rowgroup`,ownerState:s},o))})});function at(e){return w(`MuiTableRow`,e)}var G=A(`MuiTableRow`,[`root`,`selected`,`hover`,`head`,`footer`]);p();var ot=[`className`,`component`,`hover`,`selected`],st=e=>{let{classes:t,selected:n,hover:r,head:i,footer:a}=e;return P({root:[`root`,n&&`selected`,r&&`hover`,i&&`head`,a&&`footer`]},at,t)},ct=M(`tr`,{name:`MuiTableRow`,slot:`Root`,overridesResolver:(e,t)=>{let{ownerState:n}=e;return[t.root,n.head&&t.head,n.footer&&t.footer]}})(x(({theme:e})=>({color:`inherit`,display:`table-row`,verticalAlign:`middle`,outline:0,[`&.${G.hover}:hover`]:{backgroundColor:(e.vars||e).palette.action.hover},[`&.${G.selected}`]:{backgroundColor:e.alpha((e.vars||e).palette.primary.main,(e.vars||e).palette.action.selectedOpacity),"&:hover":{backgroundColor:e.alpha((e.vars||e).palette.primary.main,`${(e.vars||e).palette.action.selectedOpacity} + ${(e.vars||e).palette.action.hoverOpacity}`)}}}))),K=`tr`,lt=V.forwardRef(function(e,t){let r=l({props:e,name:`MuiTableRow`}),{className:i,component:a=K,hover:o=!1,selected:s=!1}=r,c=v(r,ot),u=V.useContext(n),d=m(m({},r),{},{component:a,hover:o,selected:s,head:u&&u.variant===`head`,footer:u&&u.variant===`footer`});return(0,H.jsx)(ct,m({as:a,ref:t,className:S(st(d).root,i),role:a===K?null:`row`,ownerState:d},c))}),q=e(ye());p();var ut=[`type`,`defaultValue`,`frontend`,`showIf`],dt=[`value`,`onChange`,`multiple`,`groups`];function ft(e,t){return J.apply(this,arguments)}function J(){return J=g(function*(e,t){let{id:n}=e,{config:r}=yield k(`get_plugin`,{id:n}),i=q.default.some(I(e.config,r),{type:`array`})?`min(100%, ${t})`:void 0,a=!!e.config,o=yield ue({title:a?`Options for ${n}`:`Log for ${n}`,form:(t,{submit:n})=>({before:e.description&&(0,V.createElement)(b,{sx:{mx:2,mb:2}},e.description),fields:Y(I(e.config,t)||{},t),save:a?{children:`Save and close`}:!1,barSx:{gap:1},onError:te,addToBar:[(0,V.createElement)(R,{variant:`outlined`,onClick:()=>n(s)},`Save`)]}),values:r,dialogProps:q.default.merge({maxWidth:`md`,sx:{m:`auto`}},e.configDialog,{maxWidth:!1,sx:{maxWidth:null}}),Wrapper({children:e}){let{list:r,setList:o}=L(`get_plugin_log`,{id:n},{map(e){e.ts=new Date(e.ts)}}),s;return(0,V.createElement)(_,{alignItems:`stretch`,justifyContent:`center`,flexWrap:`wrap`,flexDirection:a?void 0:`column`},(0,V.createElement)(b,{sx:{maxWidth:t,width:i,minWidth:`min-content`}},e),(0,V.createElement)(je,{elevation:1,sx:{position:`relative`,fontFamily:`monospace`,flex:1,minWidth:`min(40em, 90vw)`,minHeight:`20em`,px:.5}},(0,V.createElement)(b,{sx:{my:.5,pb:.5,borderBottom:`1px solid`,display:`flex`,alignItems:`center`,justifyContent:`space-between`}},`Output`,(0,V.createElement)(R,{size:`small`,sx:{p:0},onClick(){o([])}},`Clear`)),(0,V.createElement)(b,{ref:de(r),sx:{position:`absolute`,bottom:0,top:`31px`,left:0,right:0,overflowY:`auto`}},!r.length&&(0,V.createElement)(b,{sx:{p:1}},`Log is empty`),(0,V.createElement)(b,{sx:{textIndent:`-1em`,pl:`1em`,position:`absolute`,width:`calc(100% - 1.2em)`,ml:`2px`,pt:`.2em`}},r.map(e=>{j(e.ts);let t=j(e.ts);return(0,V.createElement)(V.Fragment,{key:e.id},t!==s&&(s=t),(0,V.createElement)(b,{},(0,V.createElement)(b,{title:t,sx:{display:`inline`,color:`text.secondary`,mr:1}},me(e.ts)),d(e.msg,/https?:\/\/\S+/,e=>(0,V.createElement)(ae,{href:e[0],target:`_blank`},e[0]))))})))))}});if(o&&!q.default.isEqual(r,o))return s(o);function s(e){return c.apply(this,arguments)}function c(){return c=g(function*(e){yield k(`set_plugin`,{id:n,config:e}),Object.assign(r,e),h(`Configuration saved`)}),c.apply(this,arguments)}}),J.apply(this,arguments)}function Y(e,t){return Object.entries(e).map(([e,n])=>{if(!n)return;let{type:r,defaultValue:i,frontend:a,showIf:o}=n,s=v(n,ut);try{if(s.getError=X(s.getError),typeof o==`string`&&(n.showIf=o=X(o)),o&&!o(t))return}catch(e){}s.helperText&&(s.helperText=z(s.helperText,{html:!1}));let c=Z[r];if(t===!1&&r===`date_time`&&(s.$type=`dateTime`),c===B){let{fields:e}=s;typeof e==`string`&&(e=X(e)),s.valuesForAdd=re(I(e,!1),e=>e.defaultValue),s.details!=null||(s.details=!1),s.fields=t=>q.default.map(Y(I(e,t),t),(e,t)=>e&&m(m({k:t},e),{},{defaultValue:void 0})).filter(Boolean)}return i!==void 0&&r===`boolean`&&(s.placeholder=`Default value is ${JSON.stringify(i)}`),m({k:e,comp:c},s)})}function X(e){return(0,eval)(e)}var Z={string:y,number:Ce,boolean:be,select:C,multiselect:T,array:B,real_path:qe,vfs_path:c,username:pt,color:mt,show_html:({html:e})=>(0,V.createElement)(oe,{},String(e)),date_time:a,net_mask:ee};Z.showHtml=Z.show_html;function pt(e){let{value:t,onChange:n,multiple:r,groups:i}=e,a=v(e,dt),{data:o,element:s,loading:c}=pe(`get_accounts`),l=(0,V.useMemo)(()=>o&&q.default.sortBy(o.list,[e=>!e.isGroup,e=>!e.adminActualAccess,`username`]),[o]);return(!c||!o)&&s||(0,V.createElement)(r?T:C,m({value:t,onChange:n,options:l==null?void 0:l.filter(e=>i===void 0||i===e.isGroup).map(e=>({value:e.username,label:e.username,a:e})),renderOption:e=>{if(!e.a)return(0,V.createElement)(`span`,{style:{textDecoration:`line-through`}},e.label);let t=e.a.isGroup&&(0,V.createElement)(Le)||e.a.adminActualAccess&&D(Ne,`Can login into Admin`);return t?(0,V.createElement)(`span`,{},(0,V.createElement)(`span`,{style:{marginLeft:-8,marginRight:8}},t),e.label):e.label}},a))}function mt(e){return(0,V.createElement)(y,m({inputProps:m({type:`color`,style:{marginRight:24}},!e.value&&{value:`#888888`,style:{zIndex:1,opacity:.1}}),InputProps:{endAdornment:e.value?(0,V.createElement)(R,{icon:He,size:`small`,sx:{position:`absolute`,right:0,bottom:3},title:`Clear`,onClick(t){e.onChange(null,{was:e.value,event:t})}}):(0,V.createElement)(b,{sx:{position:`absolute`,width:`100%`,bottom:2,pt:`3px`,textAlign:`center`,color:`#fff`,background:`repeating-linear-gradient(45deg, #333, #333 10px, #444 10px, #444 20px)`}},`default`)},typing:!0},e))}p();function Q({updates:e}){let{list:t,error:n,setList:a,initializing:o}=L(e?`get_plugin_updates`:`get_plugins`,{},{map(e){e.config&&(e.config=fe(e.config,e=>X(`()=>(`+e+`)`)()))}}),[s,c]=(0,V.useState)(0);(0,V.useEffect)(()=>{a(e=>q.default.sortBy(e,e=>{var t;return(e.error?0:e.started?1:e.badApi?2:3)+_e(((t=e.repo)==null?void 0:t.split(`/`).reverse().join(`/`))||e.id).toLowerCase()}))},[t.length,s]);let l=`small`,{pause:d,pauseButton:p}=ne(`plugins`,()=>ht(E.suspend_plugins).then(e=>!e),{onClick(){return g(function*(){yield k(`set_config`,{values:{[E.suspend_plugins]:!d}}),d&&(yield ve(2e3),c(Date.now()))})()}}),ee=xe();return(0,V.createElement)(i,{error:se(n)?F(n,N):q.default.map(n,(e,t)=>`Error ${t} for: ${e.join(`, `)}`).join(`; `),rows:t.length?t:[],fillFlex:!0,initializing:o,disableColumnSelector:!0,quickFilter:!e,actionsHeader:!e&&p,getRowHeight:e&&(({model:e})=>e.changelog?`auto`:50),noRows:e&&`No updates available. Only plugins available on "search online" are checked.`,columns:[{field:`id`,headerName:`name`,flex:.3,minWidth:150,renderCell:O,valueGetter(e,t){return t.repo||t.id},mergeRender:{[e?`changelog`:`description`]:{sx:{fontSize:`x-small`}}}},{field:`version`,width:70,hideUnder:`sm`,cellInnerProps:{className:he},mergeRender:{installedVersion:{sx:{fontSize:`x-small`}}}},_t,m(m({},gt),{},{flex:1,hideUnder:`sm`}),{field:`installedVersion`,hideUnder:!0,dialogHidden:!0,renderCell:({value:e})=>e&&`Yours ${e}`},{field:`changelog`,headerName:`Change log`,flex:2,hideUnder:!e||`sm`,sx:{flexDirection:`column`,alignItems:`flex-start`},renderCell({value:e,row:t}){return Array.isArray(e)?(0,V.createElement)(Qe,{sx:{td:{p:0}}},(0,V.createElement)(it,{},q.default.uniq(q.default.sortBy(e,`version`).filter(e=>q.default.isString(e.message)&&e.message&&e.version>t.installedVersion)).map((e,t)=>(0,V.createElement)(lt,{key:t},(0,V.createElement)(r,{sx:{whiteSpace:`pre`,verticalAlign:`top`}},`• ${e.version}: `),(0,V.createElement)(r,{},z(e.message,{html:!1})))))):null}}],actions:({row:t,id:n})=>e?[(0,V.createElement)(f,{icon:ze,title:t.downloading?`Downloading`:t.updated?`Already updated`:`Update`,disabled:t.updated,progress:t.downloading,size:l,onClick(){return g(function*(){yield k(`update_plugin`,{id:n},{timeout:!1}).catch(e=>{var t;throw e.code===424?Error(`Failed dependencies: `+((t=e.cause)==null?void 0:t.map(e=>u(`plugin "`,e.id||e.repo,`" `)+e.error).join(`; `))):e}),h(`Plugin updated`)})()}})]:[(0,V.createElement)(f,t.started?{icon:Ie,title:(0,V.createElement)(b,{"aria-hidden":!0},`Stop ${n}`,(0,V.createElement)(`br`),`Started `+new Date(t.started).toLocaleString()),"aria-label":`Stop ${n}`,size:l,color:`success`,doneAnimation:!0,onClick:()=>k(`stop_plugin`,{id:n})}:{icon:ge,title:`Start ${n}`,disabled:d&&`All plugins are paused – Click the Resume button below`,size:l,onClick:()=>ke(n)}),(0,V.createElement)(f,{icon:t.config||!t.started||!t.log?Te:Ve,title:t.config||!t.log?`Options`:`Log`,size:l,disabled:!t.started&&`Start plugin to access options`||!t.config&&!t.log&&`No options and no log for this plugin`,onClick(){var e;let n=t.configDialog,r=ee.breakpoints.values[n==null?void 0:n.maxWidth]||(n==null||(e=n.sx)==null?void 0:e.maxWidth)||F(n==null?void 0:n.maxWidth,{xs:0})||432;return typeof r==`number`&&(r+=`px`),ft(t,r)}}),(0,V.createElement)(f,{icon:Ue,title:`Uninstall`,size:l,onClick(){return g(function*(){let e=yield ce(`${n}: delete configuration too?`,{trueText:`Yes`,falseText:`No`,after:({onClick:e})=>(0,V.createElement)(R,{variant:`outlined`,onClick(){e(void 0)}},`Abort`)});e!==void 0&&(yield k(`uninstall_plugin`,{id:n,deleteConfig:e}),h(`Plugin uninstalled`))})()}})]})}function ht(e){return k(`get_config`,{only:[e]}).then(t=>t[e])}var gt={field:`description`,mergeRender:{isTheme:{}},mergeRenderSx:{float:`left`}},_t={field:`isTheme`,headerName:`is theme`,hideUnder:!0,dialogHidden:!0,type:`boolean`,renderCell({value:e}){return e&&D(We,q.default.isString(e)?`${e} theme`:`theme`,{fontSize:`1.2rem`,mr:`.3em`})}};p();function vt(){let[e,t]=(0,V.useState)(``),{list:n,error:r,initializing:a}=L(`get_online_plugins`,{text:we(e,1e3)}),o=Se();return(0,V.createElement)(V.Fragment,{},(0,V.createElement)(y,{value:e,onChange:t,start:(0,V.createElement)(Fe),typing:!0,label:`Search text`}),(0,V.createElement)(i,{error:r&&Me(F(r,N)),rows:n.length?n:[],noRows:`No compatible plugins have been found`,fillFlex:!0,initializing:a,columnVisibilityModel:o.onlinePluginsColumns,onColumnVisibilityModelChange:e=>Oe.onlinePluginsColumns=e,columns:[{field:`id`,headerName:`name`,flex:1,renderCell:O,mergeRender:{description:{sx:{fontSize:`x-small`}}}},{field:`version`,width:70},{field:`pushed_at`,headerName:`last update`,valueGetter:e=>new Date(e).toLocaleDateString()},{field:`license`,width:80},_t,m(m({},gt),{},{flex:3,hideUnder:`sm`}),{field:`stargazers_count`,width:50,headerName:`stars`,align:`center`,hideUnder:`sm`}],actions:({row:e,id:t})=>[(0,V.createElement)(f,{icon:Pe,title:`Install`,progress:e.downloading,disabled:e.installed&&`Already installed`,tooltipProps:{placement:`bottom-end`},onClick:()=>Ee(e)}),(0,V.createElement)(f,{icon:Re,disabled:!e.preview,onClick:()=>le({title:t,Content:()=>(0,V.createElement)(yt,{imgs:De(e.preview)})})})]}))}function yt({imgs:e}){let[t,n]=(0,V.useState)(0);return(0,V.createElement)(_,{vert:!0,flex:1},(0,V.createElement)(_,{vert:!0,center:!0,height:0,flex:`auto`,minHeight:`50vh`,minWidth:`50vw`},(0,V.createElement)(`img`,{src:e[t],style:{margin:`auto`,maxWidth:`100%`,maxHeight:`100%`}})),e.length>1&&(0,V.createElement)(_,{center:!0},(0,V.createElement)(f,{icon:Be,disabled:!t,onClick:()=>n(t-1)}),(0,V.createElement)(f,{icon:Ge,disabled:t>=e.length-1,onClick:()=>n(t+1)})))}var $=[{label:`Installed`,path:`installed`,Pane:Q},{label:`Get more`,path:`get`,Pane:vt},{label:`Check updates`,path:`updates`,Pane:()=>(0,V.createElement)(Q,{updates:!0})}],bt=$.map(e=>e.path);function xt(){let[e,t]=Ke(`plugins`,bt),{Pane:n}=$[e];return(0,V.createElement)(V.Fragment,{},(0,V.createElement)(s,{value:e,onChange(e,n){t(n)}},$.map(e=>(0,V.createElement)(o,{key:e.path,label:e.label}))),(0,V.createElement)(n))}export{xt as default};
|