node-pluginsmanager 2.3.7 → 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.
Files changed (59) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +10 -186
  3. package/lib/cjs/PluginsManager.d.ts +38 -0
  4. package/lib/cjs/PluginsManager.js +442 -0
  5. package/lib/cjs/checkers/checkAbsoluteDirectory.d.ts +1 -0
  6. package/lib/cjs/checkers/checkAbsoluteDirectory.js +20 -0
  7. package/lib/cjs/checkers/checkDirectory.d.ts +1 -0
  8. package/lib/cjs/checkers/checkDirectory.js +24 -0
  9. package/lib/cjs/checkers/checkFunction.d.ts +1 -0
  10. package/lib/cjs/checkers/checkFunction.js +16 -0
  11. package/lib/cjs/checkers/checkNonEmptyArray.d.ts +1 -0
  12. package/lib/cjs/checkers/checkNonEmptyArray.js +19 -0
  13. package/lib/cjs/checkers/checkNonEmptyString.d.ts +1 -0
  14. package/lib/cjs/checkers/checkNonEmptyString.js +19 -0
  15. package/lib/cjs/checkers/checkOrchestrator.d.ts +1 -0
  16. package/lib/cjs/checkers/checkOrchestrator.js +36 -0
  17. package/lib/cjs/cmd/cmd.d.ts +1 -0
  18. package/lib/cjs/cmd/cmd.js +37 -0
  19. package/lib/cjs/cmd/git/gitInstall.d.ts +1 -0
  20. package/lib/cjs/cmd/git/gitInstall.js +42 -0
  21. package/lib/cjs/cmd/git/gitUpdate.d.ts +1 -0
  22. package/lib/cjs/cmd/git/gitUpdate.js +18 -0
  23. package/lib/cjs/cmd/npm/npmCmd.d.ts +1 -0
  24. package/lib/cjs/cmd/npm/npmCmd.js +18 -0
  25. package/lib/cjs/cmd/npm/npmInstall.d.ts +1 -0
  26. package/lib/cjs/cmd/npm/npmInstall.js +14 -0
  27. package/lib/cjs/cmd/npm/npmUpdate.d.ts +1 -0
  28. package/lib/cjs/cmd/npm/npmUpdate.js +14 -0
  29. package/lib/cjs/cmd/stdToString.d.ts +1 -0
  30. package/lib/cjs/cmd/stdToString.js +16 -0
  31. package/lib/cjs/createPluginByDirectory.d.ts +2 -0
  32. package/lib/cjs/createPluginByDirectory.js +61 -0
  33. package/lib/cjs/extractGithub.d.ts +1 -0
  34. package/lib/cjs/extractGithub.js +20 -0
  35. package/lib/cjs/initSortedPlugins.d.ts +2 -0
  36. package/lib/cjs/initSortedPlugins.js +56 -0
  37. package/lib/cjs/loadSortedPlugins.d.ts +2 -0
  38. package/lib/cjs/loadSortedPlugins.js +74 -0
  39. package/lib/cjs/main.cjs +8 -0
  40. package/lib/cjs/main.d.cts +2 -0
  41. package/package.json +31 -13
  42. package/lib/checkers/isAbsoluteDirectory.js +0 -27
  43. package/lib/checkers/isDirectory.js +0 -34
  44. package/lib/checkers/isFunction.js +0 -18
  45. package/lib/checkers/isNonEmptyArray.js +0 -21
  46. package/lib/checkers/isNonEmptyString.js +0 -21
  47. package/lib/checkers/isOrchestrator.js +0 -41
  48. package/lib/cmd/cmd.js +0 -44
  49. package/lib/cmd/git/install.js +0 -49
  50. package/lib/cmd/git/update.js +0 -23
  51. package/lib/cmd/npm/cmd.js +0 -23
  52. package/lib/cmd/npm/install.js +0 -15
  53. package/lib/cmd/npm/update.js +0 -15
  54. package/lib/cmd/stdToString.js +0 -17
  55. package/lib/createPluginByDirectory.js +0 -64
  56. package/lib/index.d.ts +0 -81
  57. package/lib/initSortedPlugins.js +0 -96
  58. package/lib/loadSortedPlugins.js +0 -132
  59. package/lib/main.js +0 -745
package/lib/main.js DELETED
@@ -1,745 +0,0 @@
1
- /*
2
- eslint-disable max-lines, prefer-destructuring, func-style
3
- */
4
-
5
- "use strict";
6
-
7
- // deps
8
-
9
- // natives
10
- const Events = require("events");
11
- const { join } = require("path");
12
- const { homedir } = require("os");
13
-
14
- // externals
15
- const versionModulesChecker = require("check-version-modules");
16
- const {
17
- mkdirpProm, readdirProm, rmdirpProm
18
- } = require("node-promfs");
19
-
20
- // locals
21
- const isAbsoluteDirectory = require(join(__dirname, "checkers", "isAbsoluteDirectory.js"));
22
- const isFunction = require(join(__dirname, "checkers", "isFunction.js"));
23
- const isNonEmptyArray = require(join(__dirname, "checkers", "isNonEmptyArray.js"));
24
- const isNonEmptyString = require(join(__dirname, "checkers", "isNonEmptyString.js"));
25
- const isOrchestrator = require(join(__dirname, "checkers", "isOrchestrator.js"));
26
- const createPluginByDirectory = require(join(__dirname, "createPluginByDirectory.js"));
27
-
28
- // git
29
- const gitInstall = require(join(__dirname, "cmd", "git", "install.js"));
30
- const gitUpdate = require(join(__dirname, "cmd", "git", "update.js"));
31
-
32
- // npm
33
- const npmInstall = require(join(__dirname, "cmd", "npm", "install.js"));
34
- const npmUpdate = require(join(__dirname, "cmd", "npm", "update.js"));
35
-
36
- const loadSortedPlugins = require(join(__dirname, "loadSortedPlugins.js"));
37
- const initSortedPlugins = require(join(__dirname, "initSortedPlugins.js"));
38
-
39
- // consts
40
-
41
- const DEFAULT_PLUGINS_DIRECTORY = join(homedir(), "node-pluginsmanager-plugins");
42
- const DEFAULT_RESSOURCES_DIRECTORY = join(homedir(), "node-pluginsmanager-resources");
43
-
44
- // module
45
-
46
- module.exports = class PluginsManager extends Events {
47
-
48
- constructor (options) {
49
-
50
- super(options);
51
-
52
- // protected
53
-
54
- this._beforeLoadAll = null;
55
- this._beforeInitAll = null;
56
-
57
- this._orderedPluginsNames = [];
58
-
59
- this._logger = options && "function" === typeof options.logger ?
60
- options.logger : null;
61
-
62
- // public
63
-
64
- this.plugins = [];
65
-
66
- this.directory = options && "undefined" !== typeof options.directory ?
67
- options.directory : DEFAULT_PLUGINS_DIRECTORY;
68
-
69
- this.externalRessourcesDirectory = options && "undefined" !== typeof options.externalRessourcesDirectory ?
70
- options.externalRessourcesDirectory : DEFAULT_RESSOURCES_DIRECTORY;
71
-
72
- }
73
-
74
- // public
75
-
76
- // getters
77
-
78
- getPluginsNames () {
79
-
80
- return [ ...this.plugins ].map((plugin) => {
81
- return plugin.name;
82
- });
83
-
84
- }
85
-
86
- // setters
87
-
88
- setOrder (pluginsNames) {
89
-
90
- return isNonEmptyArray("setOrder/pluginsNames", pluginsNames).then(() => {
91
-
92
- const errors = [];
93
- for (let i = 0; i < pluginsNames.length; ++i) {
94
-
95
- if ("string" !== typeof pluginsNames[i]) {
96
- errors.push("The directory at index \"" + i + "\" must be a string");
97
- }
98
- else if ("" === pluginsNames[i].trim()) {
99
- errors.push("The directory at index \"" + i + "\" must be not empty");
100
- }
101
- else if (1 < pluginsNames.filter((name) => {
102
- return name === pluginsNames[i];
103
- }).length) {
104
- errors.push("The directory at index \"" + i + "\" is given twice or more");
105
- }
106
-
107
- }
108
-
109
- return !errors.length ? Promise.resolve() : Promise.reject(new Error(errors.join("\r\n")));
110
-
111
- }).then(() => {
112
-
113
- this._orderedPluginsNames = pluginsNames;
114
-
115
- return Promise.resolve();
116
-
117
- });
118
-
119
- }
120
-
121
- getOrder () {
122
-
123
- return [ ...this._orderedPluginsNames ];
124
-
125
- }
126
-
127
- // checkers
128
-
129
- checkAllModules () {
130
-
131
- const _checkPluginsModules = (i = 0) => {
132
-
133
- return i < this.plugins.length ? this.checkModules(this.plugins[i]).then(() => {
134
-
135
- return _checkPluginsModules(i + 1);
136
-
137
- }) : Promise.resolve();
138
-
139
- };
140
-
141
- return _checkPluginsModules();
142
-
143
- }
144
-
145
- checkModules (plugin) {
146
-
147
- return isAbsoluteDirectory("checkModules/directory", this.directory).then(() => {
148
-
149
- return isOrchestrator("checkModules/plugin", plugin);
150
-
151
- }).then(() => {
152
-
153
- return versionModulesChecker(join(this.directory, plugin.name, "package.json"), {
154
- "failAtMajor": true,
155
- "failAtMinor": true,
156
- "failAtPatch": false,
157
- "dev": false,
158
- "console": false
159
- }).then((valid) => {
160
-
161
- return valid ? Promise.resolve() : Promise.reject(new Error("\"" + plugin.name + "\" plugin has obsoletes modules"));
162
-
163
- });
164
-
165
- });
166
-
167
- }
168
-
169
- // network
170
-
171
- appMiddleware (req, res, next) {
172
-
173
- const plugins = this.plugins.filter((plugin) => {
174
- return "function" === typeof plugin.appMiddleware;
175
- });
176
-
177
- if (!plugins.length) {
178
- return next();
179
- }
180
- else {
181
-
182
- const _recursiveNext = (i) => {
183
-
184
- if (i >= plugins.length) {
185
- return next;
186
- }
187
- else {
188
-
189
- return () => {
190
- return plugins[i].appMiddleware(req, res, _recursiveNext(i + 1));
191
- };
192
-
193
- }
194
-
195
- };
196
-
197
- return plugins[0].appMiddleware(req, res, _recursiveNext(1));
198
-
199
- }
200
-
201
- }
202
-
203
- socketMiddleware (server) {
204
-
205
- this.plugins.filter((plugin) => {
206
- return "function" === typeof plugin.socketMiddleware;
207
- }).forEach((plugin) => {
208
- plugin.socketMiddleware(server);
209
- });
210
-
211
- }
212
-
213
- // load / destroy
214
-
215
- beforeLoadAll (callback) {
216
-
217
- return isFunction("beforeLoadAll/callback", callback).then(() => {
218
-
219
- this._beforeLoadAll = callback;
220
-
221
- return Promise.resolve();
222
-
223
- });
224
-
225
- }
226
-
227
- loadAll (data) {
228
-
229
- // create dir if not exist
230
- return isNonEmptyString("initAll/directory", this.directory).then(() => {
231
-
232
- return mkdirpProm(this.directory).then(() => {
233
- return isAbsoluteDirectory("initAll/directory", this.directory);
234
- });
235
-
236
- // create dir if not exist
237
- }).then(() => {
238
-
239
- return isNonEmptyString("initAll/externalRessourcesDirectory", this.externalRessourcesDirectory).then(() => {
240
-
241
- return mkdirpProm(this.externalRessourcesDirectory).then(() => {
242
- return isAbsoluteDirectory("initAll/externalRessourcesDirectory", this.externalRessourcesDirectory);
243
- });
244
-
245
- });
246
-
247
- // ensure loop
248
- }).then(() => {
249
-
250
- return new Promise((resolve) => {
251
- setImmediate(resolve);
252
- });
253
-
254
- // execute _beforeLoadAll
255
- }).then(() => {
256
-
257
- return "function" !== typeof this._beforeLoadAll ? Promise.resolve() : new Promise((resolve, reject) => {
258
-
259
- const fn = this._beforeLoadAll();
260
-
261
- if (!(fn instanceof Promise)) {
262
- resolve();
263
- }
264
- else {
265
- fn.then(resolve).catch(reject);
266
- }
267
-
268
- });
269
-
270
- // init plugins
271
- }).then(() => {
272
-
273
- return readdirProm(this.directory);
274
-
275
- // load all
276
- }).then((files) => {
277
-
278
- return loadSortedPlugins(
279
- this.directory, this.externalRessourcesDirectory, files, this.plugins,
280
- this._orderedPluginsNames, this.emit.bind(this), this._logger, data
281
- );
282
-
283
- // sort plugins
284
- }).then(() => {
285
-
286
- this.plugins.sort((a, b) => {
287
-
288
- if (a.name < b.name) {
289
- return -1;
290
- }
291
- else if (a.name > b.name) {
292
- return 1;
293
- }
294
- else {
295
- return 0;
296
- }
297
-
298
- });
299
-
300
- return Promise.resolve();
301
-
302
- // end
303
- }).then(() => {
304
-
305
- this.emit("allloaded", data);
306
-
307
- return Promise.resolve();
308
-
309
- });
310
-
311
- }
312
-
313
- destroyAll (data) {
314
-
315
- return Promise.resolve().then(() => {
316
-
317
- const _destroyPlugin = (i = this.plugins.length - 1) => {
318
-
319
- return -1 < i ? Promise.resolve().then(() => {
320
-
321
- const pluginName = this.plugins[i].name;
322
-
323
- // emit event
324
- return this.plugins[i].destroy(data).then(() => {
325
-
326
- this.emit("destroyed", pluginName, data);
327
-
328
- return Promise.resolve();
329
-
330
- // loop
331
- }).then(() => {
332
-
333
- return _destroyPlugin(i - 1);
334
-
335
- });
336
-
337
- }) : Promise.resolve();
338
-
339
- };
340
-
341
- return _destroyPlugin();
342
-
343
- // end
344
- }).then(() => {
345
-
346
- this.plugins = [];
347
-
348
- this.emit("alldestroyed", data);
349
-
350
- return Promise.resolve();
351
-
352
- // remove all external resources
353
- }).then(() => {
354
-
355
- return rmdirpProm(this.externalRessourcesDirectory);
356
-
357
- });
358
-
359
- }
360
-
361
- // init / release
362
-
363
- beforeInitAll (callback) {
364
-
365
- return isFunction("beforeInitAll/callback", callback).then(() => {
366
-
367
- this._beforeInitAll = callback;
368
-
369
- return Promise.resolve();
370
-
371
- });
372
-
373
- }
374
-
375
- initAll (data) {
376
-
377
- return isAbsoluteDirectory("initAll/directory", this.directory).then(() => {
378
-
379
- return isAbsoluteDirectory("initAll/externalRessourcesDirectory", this.externalRessourcesDirectory);
380
-
381
- }).then(() => {
382
-
383
- // execute _beforeInitAll
384
- return "function" !== typeof this._beforeInitAll ? Promise.resolve() : new Promise((resolve, reject) => {
385
-
386
- const fn = this._beforeInitAll();
387
-
388
- if (!(fn instanceof Promise)) {
389
- resolve();
390
- }
391
- else {
392
- fn.then(resolve).catch(reject);
393
- }
394
-
395
- });
396
-
397
- // init plugins
398
- }).then(() => {
399
-
400
- return initSortedPlugins(
401
- this.plugins, this._orderedPluginsNames, (...subdata) => {
402
- this.emit(...subdata);
403
- }, data
404
- );
405
-
406
- // end
407
- }).then(() => {
408
-
409
- this.emit("allinitialized", data);
410
-
411
- return Promise.resolve();
412
-
413
- });
414
-
415
- }
416
-
417
- releaseAll (data) {
418
-
419
- return Promise.resolve().then(() => {
420
-
421
- const _releasePlugin = (i = this.plugins.length - 1) => {
422
-
423
- return -1 < i ? Promise.resolve().then(() => {
424
-
425
- return this.plugins[i].release(data);
426
-
427
- // emit event
428
- }).then(() => {
429
-
430
- this.emit("released", this.plugins[i], data);
431
-
432
- return Promise.resolve();
433
-
434
- // loop
435
- }).then(() => {
436
-
437
- return _releasePlugin(i - 1);
438
-
439
- }) : Promise.resolve();
440
-
441
- };
442
-
443
- return _releasePlugin();
444
-
445
- // end
446
- }).then(() => {
447
-
448
- this.emit("allreleased", data);
449
-
450
- return Promise.resolve();
451
-
452
- });
453
-
454
- }
455
-
456
- // write
457
-
458
- installViaGithub (user, repo, data) {
459
-
460
- return isAbsoluteDirectory("installViaGithub/directory", this.directory).then(() => {
461
- return isNonEmptyString("installViaGithub/user", user);
462
- }).then(() => {
463
- return isNonEmptyString("installViaGithub/repo", repo);
464
- }).then(() => {
465
-
466
- const directory = join(this.directory, repo);
467
-
468
- return new Promise((resolve, reject) => {
469
-
470
- isAbsoluteDirectory("installViaGithub/plugindirectory", directory).then(() => {
471
- reject(new Error("\"" + repo + "\" plugin already exists"));
472
- }).catch(() => {
473
- resolve(directory);
474
- });
475
-
476
- });
477
-
478
- }).then((directory) => {
479
-
480
- return Promise.resolve().then(() => {
481
-
482
- return gitInstall(directory, user, repo);
483
-
484
- }).then(() => {
485
-
486
- // install dependencies & execute install script
487
- return createPluginByDirectory(directory, this.externalRessourcesDirectory, this._logger);
488
-
489
- // check plugin modules versions
490
- }).then((plugin) => {
491
-
492
- return this.checkModules(plugin).then(() => {
493
- return Promise.resolve(plugin);
494
- });
495
-
496
- }).then((plugin) => {
497
-
498
- return Promise.resolve().then(() => {
499
-
500
- return !plugin.dependencies ? Promise.resolve() : npmInstall(directory);
501
-
502
- }).then(() => {
503
-
504
- return plugin.install(data);
505
-
506
- // execute init script
507
- }).then(() => {
508
-
509
- this.emit("installed", plugin, data);
510
-
511
- return plugin.init(data);
512
-
513
- }).then(() => {
514
-
515
- this.emit("initialized", plugin, data);
516
- this.plugins.push(plugin);
517
-
518
- return Promise.resolve(plugin);
519
-
520
- }).catch((err) => {
521
-
522
- return this.uninstall(plugin, data).then(() => {
523
- return Promise.reject(err);
524
- });
525
-
526
- });
527
-
528
- }).catch((err) => {
529
-
530
- return new Promise((resolve, reject) => {
531
-
532
- isAbsoluteDirectory("installViaGithub/plugindirectory", directory).then(() => {
533
-
534
- return rmdirpProm(directory).then(() => {
535
- reject(err);
536
- });
537
-
538
- }).catch(() => {
539
- reject(err);
540
- });
541
-
542
- });
543
-
544
- });
545
-
546
- });
547
-
548
- }
549
-
550
- updateViaGithub (plugin, data) {
551
-
552
- let directory = "";
553
- let key = -1;
554
-
555
- // check plugin
556
- return Promise.resolve().then(() => {
557
-
558
- return isOrchestrator("updateViaGithub/plugin", plugin).then(() => {
559
-
560
- let github = "";
561
- if ("string" === typeof plugin.github) {
562
- github = plugin.github;
563
- }
564
- else if ("string" === typeof plugin.repository) {
565
- github = plugin.repository;
566
- }
567
- else if (plugin.repository && "string" === typeof plugin.repository.url) {
568
- github = plugin.repository.url;
569
- }
570
-
571
- return isNonEmptyString("updateViaGithub/github", github).catch(() => {
572
-
573
- return Promise.reject(new ReferenceError(
574
- "Plugin \"" + plugin.name + "\" must be linked in the package to a github project to be updated"
575
- ));
576
-
577
- });
578
-
579
- }).then(() => {
580
-
581
- key = this.getPluginsNames().findIndex((pluginName) => {
582
- return pluginName === plugin.name;
583
- });
584
-
585
- return -1 < key ? Promise.resolve() : Promise.reject(new Error("Plugin \"" + plugin.name + "\" is not registered"));
586
-
587
- });
588
-
589
- // check plugin directory
590
- }).then(() => {
591
-
592
- return isAbsoluteDirectory("updateViaGithub/directory", this.directory).then(() => {
593
-
594
- directory = join(this.directory, plugin.name);
595
-
596
- return isAbsoluteDirectory("updateViaGithub/plugindirectory", directory);
597
-
598
- });
599
-
600
- // release plugin
601
- }).then(() => {
602
-
603
- const pluginName = plugin.name;
604
-
605
- return plugin.release(data).then(() => {
606
-
607
- this.emit("released", plugin, data);
608
-
609
- return plugin.destroy(data);
610
-
611
- }).then(() => {
612
-
613
- this.emit("destroyed", pluginName, data);
614
-
615
- this.plugins[key] = null;
616
-
617
- return Promise.resolve();
618
-
619
- });
620
-
621
- // download plugin
622
- }).then(() => {
623
-
624
- return gitUpdate(directory).then(() => {
625
-
626
- return createPluginByDirectory(directory, this.externalRessourcesDirectory, this._logger);
627
-
628
- });
629
-
630
- // check plugin modules versions
631
- }).then((_plugin) => {
632
-
633
- return this.checkModules(_plugin).then(() => {
634
- return Promise.resolve(_plugin);
635
- });
636
-
637
- }).then((_plugin) => {
638
-
639
- // update dependencies & execute update script
640
- return Promise.resolve().then(() => {
641
-
642
- return !_plugin.dependencies ? Promise.resolve() : npmUpdate(directory);
643
-
644
- }).then(() => {
645
-
646
- return _plugin.update(data);
647
-
648
- }).then(() => {
649
-
650
- this.emit("updated", _plugin, data);
651
-
652
- return _plugin.init(data);
653
-
654
- // execute init script
655
- }).then(() => {
656
-
657
- this.emit("initialized", _plugin, data);
658
- this.plugins[key] = _plugin;
659
-
660
- return Promise.resolve(_plugin);
661
-
662
- });
663
-
664
- });
665
-
666
- }
667
-
668
- uninstall (plugin, data) {
669
-
670
- let directory = "";
671
- let key = -1;
672
- let pluginName = "";
673
-
674
- // check plugin
675
- return Promise.resolve().then(() => {
676
-
677
- return isOrchestrator("uninstall/plugin", plugin).then(() => {
678
-
679
- key = this.getPluginsNames().findIndex((name) => {
680
- return name === plugin.name;
681
- });
682
-
683
- return -1 < key ? Promise.resolve() : Promise.reject(new Error("Plugin \"" + plugin.name + "\" is not registered"));
684
-
685
- });
686
-
687
- // check plugin directory
688
- }).then(() => {
689
-
690
- return isAbsoluteDirectory("uninstall/directory", this.directory).then(() => {
691
-
692
- pluginName = plugin.name;
693
- directory = join(this.directory, pluginName);
694
-
695
- return isAbsoluteDirectory("uninstall/plugindirectory", directory);
696
-
697
- });
698
-
699
- // release plugin
700
- }).then(() => {
701
-
702
- return plugin.release(data).then(() => {
703
-
704
- return rmdirpProm(join(this.externalRessourcesDirectory, pluginName));
705
-
706
- }).then(() => {
707
-
708
- this.emit("released", plugin, data);
709
-
710
- return plugin.destroy(data);
711
-
712
- }).then(() => {
713
-
714
- this.emit("destroyed", pluginName, data);
715
-
716
- this.plugins.splice(key, 1);
717
-
718
- return Promise.resolve();
719
-
720
- });
721
-
722
- // update dependencies & execute update script
723
- }).then(() => {
724
-
725
- return Promise.resolve().then(() => {
726
-
727
- return plugin.uninstall(data);
728
-
729
- }).then(() => {
730
-
731
- this.emit("uninstalled", pluginName, data);
732
-
733
- return rmdirpProm(directory);
734
-
735
- });
736
-
737
- }).then(() => {
738
-
739
- return Promise.resolve(pluginName);
740
-
741
- });
742
-
743
- }
744
-
745
- };