-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Expand file tree
/
Copy pathadminplugins.ts
More file actions
140 lines (115 loc) · 4.47 KB
/
Copy pathadminplugins.ts
File metadata and controls
140 lines (115 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
'use strict';
import {ArgsExpressType} from "../../types/ArgsExpressType";
import {ErrorCaused} from "../../types/ErrorCaused";
import {QueryType} from "../../types/QueryType";
import {getAvailablePlugins, install, search, uninstall} from "../../../static/js/pluginfw/installer";
import {PackageData, PackageInfo} from "../../types/PackageInfo";
import semver from 'semver';
import log4js from 'log4js';
import {MapArrayType} from "../../types/MapType";
const pluginDefs = require('../../../static/js/pluginfw/plugin_defs');
const logger = log4js.getLogger('adminPlugins');
exports.socketio = (hookName:string, args:ArgsExpressType, cb:Function) => {
const io = args.io.of('/pluginfw/installer');
io.on('connection', (socket:any) => {
// @ts-ignore
const {session: {user: {is_admin: isAdmin} = {}} = {}} = socket.conn.request;
if (!isAdmin) return;
const checkPluginForUpdates = async () => {
let results: MapArrayType<PackageInfo>
try {
results = await getAvailablePlugins(/* maxCacheAge:*/ 60 * 10);
} catch (error) {
console.error('Error checking for plugin updates:', error);
return [];
}
return Object.keys(pluginDefs.plugins).filter((plugin) => {
if (!results[plugin]) return false;
const latestVersion = results[plugin].version;
const currentVersion = pluginDefs.plugins[plugin].package.version;
return semver.gt(latestVersion, currentVersion);
})
}
socket.on('getInstalled', async (query: string) => {
// send currently installed plugins
const installed =
Object.keys(pluginDefs.plugins).map((plugin) => pluginDefs.plugins[plugin].package);
const updatable = await checkPluginForUpdates();
installed.forEach((plugin) => {
plugin.updatable = updatable.includes(plugin.name);
})
socket.emit('results:installed', {installed});
});
socket.on('checkUpdates', async () => {
// Check plugins for updates
try {
const updatable = checkPluginForUpdates();
socket.emit('results:updatable', {updatable});
} catch (err) {
const errc = err as ErrorCaused
console.warn(errc.stack || errc.toString());
socket.emit('results:updatable', {updatable: {}});
}
});
socket.on('getAvailable', async (query:string) => {
try {
const results = await getAvailablePlugins(/* maxCacheAge:*/ false);
socket.emit('results:available', results);
} catch (er) {
console.error(er);
socket.emit('results:available', {});
}
});
socket.on('search', async (query: QueryType) => {
try {
if (query.searchTerm) logger.info(`Plugin search: ${query.searchTerm}'`);
const results = await search(query.searchTerm, /* maxCacheAge:*/ 60 * 10);
let res = Object.keys(results)
.map((pluginName) => results[pluginName])
.filter((plugin) => !pluginDefs.plugins[plugin.name]);
res = sortPluginList(res, query.sortBy, query.sortDir)
.slice(query.offset, query.offset + query.limit);
socket.emit('results:search', {results: res, query});
} catch (err: any) {
logger.error(`Error searching plugins: ${err}`);
socket.emit('results:searcherror', {error: err.message, query});
}
});
socket.on('install', (pluginName: string) => {
install(pluginName, (err: ErrorCaused) => {
if (err) console.warn(err.stack || err.toString());
socket.emit('finished:install', {
plugin: pluginName,
code: err ? err.code : null,
error: err ? err.message : null,
});
});
});
socket.on('uninstall', (pluginName:string) => {
uninstall(pluginName, (err:ErrorCaused) => {
if (err) console.warn(err.stack || err.toString());
socket.emit('finished:uninstall', {plugin: pluginName, error: err ? err.message : null});
});
});
});
return cb();
};
/**
* Sorts a list of plugins by a property
* @param {Object} plugins The plugins to sort
* @param {Object} property The property to sort by
* @param {String} dir The directory of the plugin
* @return {Object[]}
*/
const sortPluginList = (plugins:PackageData[], property:string, /* ASC?*/dir:string): PackageData[] => plugins.sort((a, b) => {
// @ts-ignore
if (a[property] < b[property]) {
return dir ? -1 : 1;
}
// @ts-ignore
if (a[property] > b[property]) {
return dir ? 1 : -1;
}
// a must be equal to b
return 0;
});