node-pluginsmanager 2.3.9 → 2.4.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/lib/cjs/PluginsManager.d.ts +38 -0
- package/lib/cjs/PluginsManager.js +442 -0
- package/lib/cjs/checkers/checkAbsoluteDirectory.d.ts +1 -0
- package/lib/cjs/checkers/checkAbsoluteDirectory.js +20 -0
- package/lib/cjs/checkers/checkDirectory.d.ts +1 -0
- package/lib/cjs/checkers/checkDirectory.js +24 -0
- package/lib/cjs/checkers/checkFunction.d.ts +1 -0
- package/lib/cjs/checkers/checkFunction.js +16 -0
- package/lib/cjs/checkers/checkNonEmptyArray.d.ts +1 -0
- package/lib/cjs/checkers/checkNonEmptyArray.js +19 -0
- package/lib/cjs/checkers/checkNonEmptyString.d.ts +1 -0
- package/lib/cjs/checkers/checkNonEmptyString.js +19 -0
- package/lib/cjs/checkers/checkOrchestrator.d.ts +1 -0
- package/lib/cjs/checkers/checkOrchestrator.js +36 -0
- package/lib/cjs/cmd/cmd.d.ts +1 -0
- package/lib/cjs/cmd/cmd.js +37 -0
- package/lib/cjs/cmd/git/gitInstall.d.ts +1 -0
- package/lib/cjs/cmd/git/gitInstall.js +42 -0
- package/lib/cjs/cmd/git/gitUpdate.d.ts +1 -0
- package/lib/cjs/cmd/git/gitUpdate.js +18 -0
- package/lib/cjs/cmd/npm/npmCmd.d.ts +1 -0
- package/lib/cjs/cmd/npm/npmCmd.js +18 -0
- package/lib/cjs/cmd/npm/npmInstall.d.ts +1 -0
- package/lib/cjs/cmd/npm/npmInstall.js +14 -0
- package/lib/cjs/cmd/npm/npmUpdate.d.ts +1 -0
- package/lib/cjs/cmd/npm/npmUpdate.js +14 -0
- package/lib/cjs/cmd/stdToString.d.ts +1 -0
- package/lib/cjs/cmd/stdToString.js +16 -0
- package/lib/cjs/createPluginByDirectory.d.ts +2 -0
- package/lib/cjs/createPluginByDirectory.js +61 -0
- package/lib/cjs/extractGithub.d.ts +1 -0
- package/lib/cjs/extractGithub.js +20 -0
- package/lib/cjs/initSortedPlugins.d.ts +2 -0
- package/lib/cjs/initSortedPlugins.js +56 -0
- package/lib/cjs/loadSortedPlugins.d.ts +2 -0
- package/lib/cjs/loadSortedPlugins.js +74 -0
- package/lib/cjs/main.cjs +8 -0
- package/lib/cjs/main.d.cts +2 -0
- package/package.json +30 -12
- package/lib/checkers/isAbsoluteDirectory.js +0 -27
- package/lib/checkers/isDirectory.js +0 -34
- package/lib/checkers/isFunction.js +0 -18
- package/lib/checkers/isNonEmptyArray.js +0 -21
- package/lib/checkers/isNonEmptyString.js +0 -21
- package/lib/checkers/isOrchestrator.js +0 -41
- package/lib/cmd/cmd.js +0 -44
- package/lib/cmd/git/install.js +0 -49
- package/lib/cmd/git/update.js +0 -23
- package/lib/cmd/npm/cmd.js +0 -23
- package/lib/cmd/npm/install.js +0 -15
- package/lib/cmd/npm/update.js +0 -15
- package/lib/cmd/stdToString.js +0 -17
- package/lib/createPluginByDirectory.js +0 -70
- package/lib/index.d.ts +0 -81
- package/lib/initSortedPlugins.js +0 -96
- package/lib/loadSortedPlugins.js +0 -132
- package/lib/main.js +0 -743
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from "events";
|
|
3
|
+
import { Orchestrator, tLogger, iIncomingMessage, iServerResponse } from "node-pluginsmanager-plugin";
|
|
4
|
+
import { Server as WebSocketServer } from "ws";
|
|
5
|
+
import { Server as SocketIOServer } from "socket.io";
|
|
6
|
+
interface iPluginManagerOptions {
|
|
7
|
+
"directory"?: string;
|
|
8
|
+
"externalRessourcesDirectory"?: string;
|
|
9
|
+
"logger"?: tLogger | null;
|
|
10
|
+
}
|
|
11
|
+
declare type tBeforeAllMethodCallback = (...data: any) => Promise<void> | void;
|
|
12
|
+
export default class PluginsManager extends EventEmitter {
|
|
13
|
+
protected _beforeLoadAll: tBeforeAllMethodCallback | null;
|
|
14
|
+
protected _beforeInitAll: tBeforeAllMethodCallback | null;
|
|
15
|
+
protected _logger: tLogger | null;
|
|
16
|
+
protected _orderedPluginsNames: Array<string>;
|
|
17
|
+
directory: string;
|
|
18
|
+
externalRessourcesDirectory: string;
|
|
19
|
+
plugins: Array<Orchestrator>;
|
|
20
|
+
constructor(options: iPluginManagerOptions);
|
|
21
|
+
getPluginsNames(): Array<string>;
|
|
22
|
+
setOrder(pluginsNames: Array<string>): Promise<void>;
|
|
23
|
+
getOrder(): Array<string>;
|
|
24
|
+
checkAllModules(): Promise<void>;
|
|
25
|
+
checkModules(plugin: Orchestrator): Promise<void>;
|
|
26
|
+
appMiddleware(req: iIncomingMessage, res: iServerResponse, next: Function): void;
|
|
27
|
+
socketMiddleware(server: WebSocketServer | SocketIOServer): void;
|
|
28
|
+
beforeLoadAll(callback: tBeforeAllMethodCallback): Promise<void>;
|
|
29
|
+
loadAll(...data: any): Promise<void>;
|
|
30
|
+
destroyAll(...data: any): Promise<void>;
|
|
31
|
+
beforeInitAll(callback: tBeforeAllMethodCallback): Promise<void>;
|
|
32
|
+
initAll(...data: any): Promise<void>;
|
|
33
|
+
releaseAll(...data: any): Promise<void>;
|
|
34
|
+
installViaGithub(user: string, repo: string, ...data: any): Promise<Orchestrator>;
|
|
35
|
+
updateViaGithub(plugin: Orchestrator, ...data: any): Promise<Orchestrator>;
|
|
36
|
+
uninstall(plugin: Orchestrator, ...data: any): Promise<string>;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,442 @@
|
|
|
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
|
+
// deps
|
|
7
|
+
// natives
|
|
8
|
+
const events_1 = __importDefault(require("events"));
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const os_1 = require("os");
|
|
11
|
+
// externals
|
|
12
|
+
const check_version_modules_1 = __importDefault(require("check-version-modules"));
|
|
13
|
+
const fs_extra_1 = require("fs-extra");
|
|
14
|
+
// locals
|
|
15
|
+
const checkAbsoluteDirectory_1 = __importDefault(require("./checkers/checkAbsoluteDirectory"));
|
|
16
|
+
const checkFunction_1 = __importDefault(require("./checkers/checkFunction"));
|
|
17
|
+
const checkNonEmptyArray_1 = __importDefault(require("./checkers/checkNonEmptyArray"));
|
|
18
|
+
const checkNonEmptyString_1 = __importDefault(require("./checkers/checkNonEmptyString"));
|
|
19
|
+
const checkOrchestrator_1 = __importDefault(require("./checkers/checkOrchestrator"));
|
|
20
|
+
const createPluginByDirectory_1 = __importDefault(require("./createPluginByDirectory"));
|
|
21
|
+
const loadSortedPlugins_1 = __importDefault(require("./loadSortedPlugins"));
|
|
22
|
+
const initSortedPlugins_1 = __importDefault(require("./initSortedPlugins"));
|
|
23
|
+
const extractGithub_1 = __importDefault(require("./extractGithub"));
|
|
24
|
+
// git
|
|
25
|
+
const gitInstall_1 = __importDefault(require("./cmd/git/gitInstall"));
|
|
26
|
+
const gitUpdate_1 = __importDefault(require("./cmd/git/gitUpdate"));
|
|
27
|
+
// npm
|
|
28
|
+
const npmInstall_1 = __importDefault(require("./cmd/npm/npmInstall"));
|
|
29
|
+
const npmUpdate_1 = __importDefault(require("./cmd/npm/npmUpdate"));
|
|
30
|
+
// consts
|
|
31
|
+
const DEFAULT_PLUGINS_DIRECTORY = (0, path_1.join)((0, os_1.homedir)(), "node-pluginsmanager-plugins");
|
|
32
|
+
const DEFAULT_RESSOURCES_DIRECTORY = (0, path_1.join)((0, os_1.homedir)(), "node-pluginsmanager-resources");
|
|
33
|
+
// module
|
|
34
|
+
class PluginsManager extends events_1.default {
|
|
35
|
+
// constructor
|
|
36
|
+
constructor(options) {
|
|
37
|
+
super();
|
|
38
|
+
// protected
|
|
39
|
+
this._beforeLoadAll = null;
|
|
40
|
+
this._beforeInitAll = null;
|
|
41
|
+
this._orderedPluginsNames = [];
|
|
42
|
+
this._logger = options && "function" === typeof options.logger ?
|
|
43
|
+
options.logger : null;
|
|
44
|
+
// public
|
|
45
|
+
this.plugins = [];
|
|
46
|
+
this.directory = options && "undefined" !== typeof options.directory ?
|
|
47
|
+
options.directory : DEFAULT_PLUGINS_DIRECTORY;
|
|
48
|
+
this.externalRessourcesDirectory = options && "undefined" !== typeof options.externalRessourcesDirectory ?
|
|
49
|
+
options.externalRessourcesDirectory : DEFAULT_RESSOURCES_DIRECTORY;
|
|
50
|
+
}
|
|
51
|
+
// public
|
|
52
|
+
getPluginsNames() {
|
|
53
|
+
return [...this.plugins].map((plugin) => {
|
|
54
|
+
return plugin.name;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// create a forced order to synchronously initialize plugins. not ordered plugins are asynchronously initialized after.
|
|
58
|
+
setOrder(pluginsNames) {
|
|
59
|
+
return (0, checkNonEmptyArray_1.default)("setOrder/pluginsNames", pluginsNames).then(() => {
|
|
60
|
+
const errors = [];
|
|
61
|
+
for (let i = 0; i < pluginsNames.length; ++i) {
|
|
62
|
+
if ("string" !== typeof pluginsNames[i]) {
|
|
63
|
+
errors.push("The directory at index \"" + i + "\" must be a string");
|
|
64
|
+
}
|
|
65
|
+
else if ("" === pluginsNames[i].trim()) {
|
|
66
|
+
errors.push("The directory at index \"" + i + "\" must be not empty");
|
|
67
|
+
}
|
|
68
|
+
else if (1 < pluginsNames.filter((name) => {
|
|
69
|
+
return name === pluginsNames[i];
|
|
70
|
+
}).length) {
|
|
71
|
+
errors.push("The directory at index \"" + i + "\" is given twice or more");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return !errors.length ? Promise.resolve() : Promise.reject(new Error(errors.join("\r\n")));
|
|
75
|
+
}).then(() => {
|
|
76
|
+
this._orderedPluginsNames = pluginsNames;
|
|
77
|
+
return Promise.resolve();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
getOrder() {
|
|
81
|
+
return [...this._orderedPluginsNames];
|
|
82
|
+
}
|
|
83
|
+
checkAllModules() {
|
|
84
|
+
const _checkPluginsModules = (i = 0) => {
|
|
85
|
+
return i < this.plugins.length ? this.checkModules(this.plugins[i]).then(() => {
|
|
86
|
+
return _checkPluginsModules(i + 1);
|
|
87
|
+
}) : Promise.resolve();
|
|
88
|
+
};
|
|
89
|
+
return _checkPluginsModules();
|
|
90
|
+
}
|
|
91
|
+
checkModules(plugin) {
|
|
92
|
+
return (0, checkAbsoluteDirectory_1.default)("checkModules/directory", this.directory).then(() => {
|
|
93
|
+
return (0, checkOrchestrator_1.default)("checkModules/plugin", plugin);
|
|
94
|
+
}).then(() => {
|
|
95
|
+
return (0, check_version_modules_1.default)((0, path_1.join)(this.directory, plugin.name, "package.json"), {
|
|
96
|
+
"failAtMajor": true,
|
|
97
|
+
"failAtMinor": true,
|
|
98
|
+
"failAtPatch": false,
|
|
99
|
+
"dev": false,
|
|
100
|
+
"console": false
|
|
101
|
+
}).then((valid) => {
|
|
102
|
+
return valid ? Promise.resolve() : Promise.reject(new Error("\"" + plugin.name + "\" plugin has obsoletes modules"));
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// used for execute all plugins' middlewares in app (express or other)
|
|
107
|
+
appMiddleware(req, res, next) {
|
|
108
|
+
const plugins = this.plugins.filter((plugin) => {
|
|
109
|
+
return "function" === typeof plugin.appMiddleware;
|
|
110
|
+
});
|
|
111
|
+
if (!plugins.length) {
|
|
112
|
+
return next();
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const _recursiveNext = (i = 1) => {
|
|
116
|
+
if (i >= plugins.length) {
|
|
117
|
+
return next;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
return () => {
|
|
121
|
+
return plugins[i].appMiddleware(req, res, _recursiveNext(i + 1));
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return plugins[0].appMiddleware(req, res, _recursiveNext());
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// middleware for socket to add bilateral push events
|
|
129
|
+
socketMiddleware(server) {
|
|
130
|
+
this.plugins.filter((plugin) => {
|
|
131
|
+
return "function" === typeof plugin.socketMiddleware;
|
|
132
|
+
}).forEach((plugin) => {
|
|
133
|
+
plugin.socketMiddleware(server);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// add a function executed before loading all plugins
|
|
137
|
+
beforeLoadAll(callback) {
|
|
138
|
+
return (0, checkFunction_1.default)("beforeLoadAll/callback", callback).then(() => {
|
|
139
|
+
this._beforeLoadAll = callback;
|
|
140
|
+
return Promise.resolve();
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// load all plugins asynchronously, using "data" in arguments for "load" plugin's Orchestrator method
|
|
144
|
+
loadAll(...data) {
|
|
145
|
+
// create dir if not exist
|
|
146
|
+
return (0, checkNonEmptyString_1.default)("initAll/directory", this.directory).then(() => {
|
|
147
|
+
return (0, fs_extra_1.mkdirp)(this.directory).then(() => {
|
|
148
|
+
return (0, checkAbsoluteDirectory_1.default)("initAll/directory", this.directory);
|
|
149
|
+
});
|
|
150
|
+
// create dir if not exist
|
|
151
|
+
}).then(() => {
|
|
152
|
+
return (0, checkNonEmptyString_1.default)("initAll/externalRessourcesDirectory", this.externalRessourcesDirectory).then(() => {
|
|
153
|
+
return (0, fs_extra_1.mkdirp)(this.externalRessourcesDirectory).then(() => {
|
|
154
|
+
return (0, checkAbsoluteDirectory_1.default)("initAll/externalRessourcesDirectory", this.externalRessourcesDirectory);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
// ensure loop
|
|
158
|
+
}).then(() => {
|
|
159
|
+
return new Promise((resolve) => {
|
|
160
|
+
setImmediate(resolve);
|
|
161
|
+
});
|
|
162
|
+
// execute _beforeLoadAll
|
|
163
|
+
}).then(() => {
|
|
164
|
+
return "function" !== typeof this._beforeLoadAll ? Promise.resolve() : new Promise((resolve, reject) => {
|
|
165
|
+
const fn = this._beforeLoadAll(...data);
|
|
166
|
+
if (!(fn instanceof Promise)) {
|
|
167
|
+
resolve();
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
fn.then(resolve).catch(reject);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// init plugins
|
|
174
|
+
}).then(() => {
|
|
175
|
+
return (0, fs_extra_1.readdir)(this.directory);
|
|
176
|
+
// load all
|
|
177
|
+
}).then((files) => {
|
|
178
|
+
return (0, loadSortedPlugins_1.default)(this.directory, this.externalRessourcesDirectory, files, this.plugins, this._orderedPluginsNames, this.emit.bind(this), this._logger, ...data);
|
|
179
|
+
// sort plugins
|
|
180
|
+
}).then(() => {
|
|
181
|
+
this.plugins.sort((a, b) => {
|
|
182
|
+
if (a.name < b.name) {
|
|
183
|
+
return -1;
|
|
184
|
+
}
|
|
185
|
+
else if (a.name > b.name) {
|
|
186
|
+
return 1;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
return Promise.resolve();
|
|
193
|
+
// end
|
|
194
|
+
}).then(() => {
|
|
195
|
+
this.emit("allloaded", ...data);
|
|
196
|
+
return Promise.resolve();
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
// after releasing, destroy packages data & free "plugins" list, using "data" in arguments for "destroy" plugin's Orchestrator method
|
|
200
|
+
destroyAll(...data) {
|
|
201
|
+
return Promise.resolve().then(() => {
|
|
202
|
+
const _destroyPlugin = (i = this.plugins.length - 1) => {
|
|
203
|
+
return -1 < i ? Promise.resolve().then(() => {
|
|
204
|
+
const pluginName = this.plugins[i].name;
|
|
205
|
+
// emit event
|
|
206
|
+
return this.plugins[i].destroy().then(() => {
|
|
207
|
+
this.emit("destroyed", pluginName, ...data);
|
|
208
|
+
return Promise.resolve();
|
|
209
|
+
// loop
|
|
210
|
+
}).then(() => {
|
|
211
|
+
return _destroyPlugin(i - 1);
|
|
212
|
+
});
|
|
213
|
+
}) : Promise.resolve();
|
|
214
|
+
};
|
|
215
|
+
return _destroyPlugin();
|
|
216
|
+
// end
|
|
217
|
+
}).then(() => {
|
|
218
|
+
this.plugins = [];
|
|
219
|
+
this.emit("alldestroyed", ...data);
|
|
220
|
+
return Promise.resolve();
|
|
221
|
+
// remove all external resources
|
|
222
|
+
}).then(() => {
|
|
223
|
+
return (0, fs_extra_1.remove)(this.externalRessourcesDirectory);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// add a function executed before initializing all plugins
|
|
227
|
+
beforeInitAll(callback) {
|
|
228
|
+
return (0, checkFunction_1.default)("beforeInitAll/callback", callback).then(() => {
|
|
229
|
+
this._beforeInitAll = callback;
|
|
230
|
+
return Promise.resolve();
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// initialize all plugins asynchronously, using "data" in arguments for "init" plugin's Orchestrator method
|
|
234
|
+
initAll(...data) {
|
|
235
|
+
return (0, checkAbsoluteDirectory_1.default)("initAll/directory", this.directory).then(() => {
|
|
236
|
+
return (0, checkAbsoluteDirectory_1.default)("initAll/externalRessourcesDirectory", this.externalRessourcesDirectory);
|
|
237
|
+
}).then(() => {
|
|
238
|
+
// execute _beforeInitAll
|
|
239
|
+
return "function" !== typeof this._beforeInitAll ? Promise.resolve() : new Promise((resolve, reject) => {
|
|
240
|
+
const fn = this._beforeInitAll(...data);
|
|
241
|
+
if (!(fn instanceof Promise)) {
|
|
242
|
+
resolve();
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
fn.then(resolve).catch(reject);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// init plugins
|
|
249
|
+
}).then(() => {
|
|
250
|
+
return (0, initSortedPlugins_1.default)(this.plugins, this._orderedPluginsNames, this.emit.bind(this), ...data);
|
|
251
|
+
// end
|
|
252
|
+
}).then(() => {
|
|
253
|
+
this.emit("allinitialized", ...data);
|
|
254
|
+
return Promise.resolve();
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
// release a plugin (keep package but destroy Mediator & Server), using "data" in arguments for "release" plugin's Orchestrator method
|
|
258
|
+
releaseAll(...data) {
|
|
259
|
+
return Promise.resolve().then(() => {
|
|
260
|
+
const _releasePlugin = (i = this.plugins.length - 1) => {
|
|
261
|
+
return -1 < i ? Promise.resolve().then(() => {
|
|
262
|
+
return this.plugins[i].release(data);
|
|
263
|
+
// emit event
|
|
264
|
+
}).then(() => {
|
|
265
|
+
this.emit("released", this.plugins[i], ...data);
|
|
266
|
+
return Promise.resolve();
|
|
267
|
+
// loop
|
|
268
|
+
}).then(() => {
|
|
269
|
+
return _releasePlugin(i - 1);
|
|
270
|
+
}) : Promise.resolve();
|
|
271
|
+
};
|
|
272
|
+
return _releasePlugin();
|
|
273
|
+
// end
|
|
274
|
+
}).then(() => {
|
|
275
|
+
this.emit("allreleased", ...data);
|
|
276
|
+
return Promise.resolve();
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// install a plugin via github repo, using "data" in arguments for "install" and "init" plugin's Orchestrator methods
|
|
280
|
+
installViaGithub(user, repo, ...data) {
|
|
281
|
+
return (0, checkAbsoluteDirectory_1.default)("installViaGithub/directory", this.directory).then(() => {
|
|
282
|
+
return (0, checkNonEmptyString_1.default)("installViaGithub/user", user);
|
|
283
|
+
}).then(() => {
|
|
284
|
+
return (0, checkNonEmptyString_1.default)("installViaGithub/repo", repo);
|
|
285
|
+
}).then(() => {
|
|
286
|
+
const directory = (0, path_1.join)(this.directory, repo);
|
|
287
|
+
return new Promise((resolve, reject) => {
|
|
288
|
+
(0, checkAbsoluteDirectory_1.default)("installViaGithub/plugindirectory", directory).then(() => {
|
|
289
|
+
return reject(new Error("\"" + repo + "\" plugin already exists"));
|
|
290
|
+
}).catch(() => {
|
|
291
|
+
return resolve(directory);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}).then((directory) => {
|
|
295
|
+
return Promise.resolve().then(() => {
|
|
296
|
+
return (0, gitInstall_1.default)(directory, user, repo);
|
|
297
|
+
}).then(() => {
|
|
298
|
+
// install dependencies & execute install script
|
|
299
|
+
return (0, createPluginByDirectory_1.default)(directory, this.externalRessourcesDirectory, this._logger);
|
|
300
|
+
// check plugin modules versions
|
|
301
|
+
}).then((plugin) => {
|
|
302
|
+
return this.checkModules(plugin).then(() => {
|
|
303
|
+
return Promise.resolve(plugin);
|
|
304
|
+
});
|
|
305
|
+
}).then((plugin) => {
|
|
306
|
+
return Promise.resolve().then(() => {
|
|
307
|
+
return !plugin.dependencies ? Promise.resolve() : (0, npmInstall_1.default)(directory);
|
|
308
|
+
}).then(() => {
|
|
309
|
+
return plugin.install(...data);
|
|
310
|
+
// execute init script
|
|
311
|
+
}).then(() => {
|
|
312
|
+
this.emit("installed", plugin, ...data);
|
|
313
|
+
return plugin.init(...data);
|
|
314
|
+
}).then(() => {
|
|
315
|
+
this.emit("initialized", plugin, ...data);
|
|
316
|
+
this.plugins.push(plugin);
|
|
317
|
+
return Promise.resolve(plugin);
|
|
318
|
+
}).catch((err) => {
|
|
319
|
+
return this.uninstall(plugin, ...data).then(() => {
|
|
320
|
+
return Promise.reject(err);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
}).catch((err) => {
|
|
324
|
+
return new Promise((resolve, reject) => {
|
|
325
|
+
(0, checkAbsoluteDirectory_1.default)("installViaGithub/plugindirectory", directory).then(() => {
|
|
326
|
+
return (0, fs_extra_1.remove)(directory).then(() => {
|
|
327
|
+
return err ? reject(err) : resolve();
|
|
328
|
+
});
|
|
329
|
+
}).catch(() => {
|
|
330
|
+
return err ? reject(err) : resolve();
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
// update a plugin via its github repo, using "data" in arguments for "release", "update" and "init" plugin's methods
|
|
337
|
+
updateViaGithub(plugin, ...data) {
|
|
338
|
+
let directory = "";
|
|
339
|
+
let key = -1;
|
|
340
|
+
// check plugin
|
|
341
|
+
return Promise.resolve().then(() => {
|
|
342
|
+
return (0, checkOrchestrator_1.default)("updateViaGithub/plugin", plugin).then(() => {
|
|
343
|
+
return (0, checkNonEmptyString_1.default)("updateViaGithub/github", (0, extractGithub_1.default)(plugin)).catch(() => {
|
|
344
|
+
return Promise.reject(new ReferenceError("Plugin \"" + plugin.name + "\" must be linked in the package to a github project to be updated"));
|
|
345
|
+
});
|
|
346
|
+
}).then(() => {
|
|
347
|
+
key = this.getPluginsNames().findIndex((pluginName) => {
|
|
348
|
+
return pluginName === plugin.name;
|
|
349
|
+
});
|
|
350
|
+
return -1 < key ? Promise.resolve() : Promise.reject(new Error("Plugin \"" + plugin.name + "\" is not registered"));
|
|
351
|
+
});
|
|
352
|
+
// check plugin directory
|
|
353
|
+
}).then(() => {
|
|
354
|
+
return (0, checkAbsoluteDirectory_1.default)("updateViaGithub/directory", this.directory).then(() => {
|
|
355
|
+
directory = (0, path_1.join)(this.directory, plugin.name);
|
|
356
|
+
return (0, checkAbsoluteDirectory_1.default)("updateViaGithub/plugindirectory", directory);
|
|
357
|
+
});
|
|
358
|
+
// release plugin
|
|
359
|
+
}).then(() => {
|
|
360
|
+
const pluginName = plugin.name;
|
|
361
|
+
return plugin.release(data).then(() => {
|
|
362
|
+
this.emit("released", plugin, ...data);
|
|
363
|
+
return plugin.destroy();
|
|
364
|
+
}).then(() => {
|
|
365
|
+
this.emit("destroyed", pluginName, ...data);
|
|
366
|
+
this.plugins.splice(key, 1);
|
|
367
|
+
return Promise.resolve();
|
|
368
|
+
});
|
|
369
|
+
// download plugin
|
|
370
|
+
}).then(() => {
|
|
371
|
+
return (0, gitUpdate_1.default)(directory).then(() => {
|
|
372
|
+
return (0, createPluginByDirectory_1.default)(directory, this.externalRessourcesDirectory, this._logger);
|
|
373
|
+
});
|
|
374
|
+
// check plugin modules versions
|
|
375
|
+
}).then((_plugin) => {
|
|
376
|
+
return this.checkModules(_plugin).then(() => {
|
|
377
|
+
return Promise.resolve(_plugin);
|
|
378
|
+
});
|
|
379
|
+
}).then((_plugin) => {
|
|
380
|
+
// update dependencies & execute update script
|
|
381
|
+
return Promise.resolve().then(() => {
|
|
382
|
+
return !_plugin.dependencies ? Promise.resolve() : (0, npmUpdate_1.default)(directory);
|
|
383
|
+
}).then(() => {
|
|
384
|
+
return _plugin.update(...data);
|
|
385
|
+
}).then(() => {
|
|
386
|
+
this.emit("updated", _plugin, ...data);
|
|
387
|
+
return _plugin.init(data);
|
|
388
|
+
// execute init script
|
|
389
|
+
}).then(() => {
|
|
390
|
+
this.emit("initialized", _plugin, ...data);
|
|
391
|
+
this.plugins[key] = _plugin;
|
|
392
|
+
return Promise.resolve(_plugin);
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
// uninstall a plugin, using "data" in arguments for "release" and "uninstall" plugin's methods
|
|
397
|
+
uninstall(plugin, ...data) {
|
|
398
|
+
let directory = "";
|
|
399
|
+
let key = -1;
|
|
400
|
+
let pluginName = "";
|
|
401
|
+
// check plugin
|
|
402
|
+
return Promise.resolve().then(() => {
|
|
403
|
+
return (0, checkOrchestrator_1.default)("uninstall/plugin", plugin).then(() => {
|
|
404
|
+
key = this.getPluginsNames().findIndex((name) => {
|
|
405
|
+
return name === plugin.name;
|
|
406
|
+
});
|
|
407
|
+
return -1 < key ? Promise.resolve() : Promise.reject(new Error("Plugin \"" + plugin.name + "\" is not registered"));
|
|
408
|
+
});
|
|
409
|
+
// check plugin directory
|
|
410
|
+
}).then(() => {
|
|
411
|
+
return (0, checkAbsoluteDirectory_1.default)("uninstall/directory", this.directory).then(() => {
|
|
412
|
+
pluginName = plugin.name;
|
|
413
|
+
directory = (0, path_1.join)(this.directory, pluginName);
|
|
414
|
+
return (0, checkAbsoluteDirectory_1.default)("uninstall/plugindirectory", directory);
|
|
415
|
+
});
|
|
416
|
+
// release plugin
|
|
417
|
+
}).then(() => {
|
|
418
|
+
return plugin.release(data).then(() => {
|
|
419
|
+
return (0, fs_extra_1.remove)((0, path_1.join)(this.externalRessourcesDirectory, pluginName));
|
|
420
|
+
}).then(() => {
|
|
421
|
+
this.emit("released", plugin, ...data);
|
|
422
|
+
return plugin.destroy();
|
|
423
|
+
}).then(() => {
|
|
424
|
+
this.emit("destroyed", pluginName, ...data);
|
|
425
|
+
this.plugins.splice(key, 1);
|
|
426
|
+
return Promise.resolve();
|
|
427
|
+
});
|
|
428
|
+
// update dependencies & execute update script
|
|
429
|
+
}).then(() => {
|
|
430
|
+
return Promise.resolve().then(() => {
|
|
431
|
+
return plugin.uninstall(...data);
|
|
432
|
+
}).then(() => {
|
|
433
|
+
this.emit("uninstalled", pluginName, ...data);
|
|
434
|
+
return (0, fs_extra_1.remove)(directory);
|
|
435
|
+
});
|
|
436
|
+
}).then(() => {
|
|
437
|
+
return Promise.resolve(pluginName);
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
exports.default = PluginsManager;
|
|
442
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function checkAbsoluteDirectory(dataName: string, directory: string): Promise<void>;
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
// deps
|
|
7
|
+
// natives
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
// locals
|
|
10
|
+
const checkDirectory_1 = __importDefault(require("./checkDirectory"));
|
|
11
|
+
// module
|
|
12
|
+
function checkAbsoluteDirectory(dataName, directory) {
|
|
13
|
+
return (0, checkDirectory_1.default)(dataName, directory).then(() => {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
return (0, path_1.isAbsolute)(directory) ? resolve() : reject(new Error("\"" + dataName + "\" (" + directory + ") is not an absolute path"));
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
exports.default = checkAbsoluteDirectory;
|
|
20
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function checkDirectory(dataName: string, directory: string): Promise<void>;
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
// deps
|
|
7
|
+
// natives
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
// locals
|
|
10
|
+
const checkNonEmptyString_1 = __importDefault(require("./checkNonEmptyString"));
|
|
11
|
+
// module
|
|
12
|
+
function checkDirectory(dataName, directory) {
|
|
13
|
+
return (0, checkNonEmptyString_1.default)(dataName, directory).then(() => {
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
(0, fs_1.lstat)(directory, (err, stats) => {
|
|
16
|
+
return resolve(Boolean(!err && stats.isDirectory()));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}).then((exists) => {
|
|
20
|
+
return exists ? Promise.resolve() : Promise.reject(new Error("\"" + dataName + "\" (" + directory + ") is not a valid directory"));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
exports.default = checkDirectory;
|
|
24
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function isFunction(dataName: string, data: any): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// module
|
|
4
|
+
function isFunction(dataName, data) {
|
|
5
|
+
if ("undefined" === typeof data) {
|
|
6
|
+
return Promise.reject(new ReferenceError("\"" + dataName + "\" parameter is missing"));
|
|
7
|
+
}
|
|
8
|
+
else if ("function" !== typeof data) {
|
|
9
|
+
return Promise.reject(new TypeError("\"" + dataName + "\" parameter is not a function"));
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
return Promise.resolve();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.default = isFunction;
|
|
16
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function isNonEmptyArray(dataName: string, data: any): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// module
|
|
4
|
+
function isNonEmptyArray(dataName, data) {
|
|
5
|
+
if ("undefined" === typeof data) {
|
|
6
|
+
return Promise.reject(new ReferenceError("\"" + dataName + "\" parameter is missing"));
|
|
7
|
+
}
|
|
8
|
+
else if ("object" !== typeof data || !(data instanceof Array)) {
|
|
9
|
+
return Promise.reject(new TypeError("\"" + dataName + "\" parameter is not an Array"));
|
|
10
|
+
}
|
|
11
|
+
else if (!data.length) {
|
|
12
|
+
return Promise.reject(new RangeError("\"" + dataName + "\" parameter is empty"));
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = isNonEmptyArray;
|
|
19
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function isNonEmptyString(dataName: string, data: any): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// module
|
|
4
|
+
function isNonEmptyString(dataName, data) {
|
|
5
|
+
if ("undefined" === typeof data) {
|
|
6
|
+
return Promise.reject(new ReferenceError("\"" + dataName + "\" parameter is missing"));
|
|
7
|
+
}
|
|
8
|
+
else if ("string" !== typeof data) {
|
|
9
|
+
return Promise.reject(new TypeError("\"" + dataName + "\" parameter is not a string"));
|
|
10
|
+
}
|
|
11
|
+
else if ("" === data.trim()) {
|
|
12
|
+
return Promise.reject(new RangeError("\"" + dataName + "\" parameter is empty"));
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = isNonEmptyString;
|
|
19
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function checkOrchestrator(dataName: string, data: any): Promise<void>;
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
// deps
|
|
7
|
+
// natives
|
|
8
|
+
const events_1 = __importDefault(require("events"));
|
|
9
|
+
// locals
|
|
10
|
+
const checkFunction_1 = __importDefault(require("./checkFunction"));
|
|
11
|
+
// module
|
|
12
|
+
function checkOrchestrator(dataName, data) {
|
|
13
|
+
if ("undefined" === typeof data) {
|
|
14
|
+
return Promise.reject(new ReferenceError("\"" + dataName + "\" parameter is missing"));
|
|
15
|
+
}
|
|
16
|
+
else if ("object" !== typeof data || !(data instanceof events_1.default)) {
|
|
17
|
+
return Promise.reject(new TypeError("\"" + dataName + "\" parameter is not an Event"));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return (0, checkFunction_1.default)("isOrchestrator/load", data.load).then(() => {
|
|
21
|
+
return (0, checkFunction_1.default)("isOrchestrator/destroy", data.destroy);
|
|
22
|
+
}).then(() => {
|
|
23
|
+
return (0, checkFunction_1.default)("isOrchestrator/init", data.init);
|
|
24
|
+
}).then(() => {
|
|
25
|
+
return (0, checkFunction_1.default)("isOrchestrator/release", data.release);
|
|
26
|
+
}).then(() => {
|
|
27
|
+
return (0, checkFunction_1.default)("isOrchestrator/install", data.install);
|
|
28
|
+
}).then(() => {
|
|
29
|
+
return (0, checkFunction_1.default)("isOrchestrator/update", data.update);
|
|
30
|
+
}).then(() => {
|
|
31
|
+
return (0, checkFunction_1.default)("isOrchestrator/uninstall", data.uninstall);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = checkOrchestrator;
|
|
36
|
+
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function cmd(directory: string, command: string, params: Array<string>): Promise<void>;
|