bajo 2.21.0 → 2.22.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 (66) hide show
  1. package/.jsdoc.conf.json +1 -1
  2. package/class/app.js +139 -115
  3. package/class/bajo.js +96 -89
  4. package/class/base.js +25 -9
  5. package/class/cache.js +32 -19
  6. package/class/err.js +11 -9
  7. package/class/log.js +102 -52
  8. package/class/plugin.js +45 -35
  9. package/class/print.js +45 -44
  10. package/class/tools.js +7 -1
  11. package/docs/App.html +1 -23
  12. package/docs/Bajo.html +1 -6
  13. package/docs/Base.html +1 -1
  14. package/docs/Cache.html +1 -1
  15. package/docs/Err.html +2 -2
  16. package/docs/Log.html +4 -4
  17. package/docs/Plugin.html +1 -1
  18. package/docs/Print.html +1 -1
  19. package/docs/Tools.html +1 -1
  20. package/docs/class_app.js.html +141 -117
  21. package/docs/class_bajo.js.html +98 -91
  22. package/docs/class_base.js.html +27 -11
  23. package/docs/class_cache.js.html +34 -21
  24. package/docs/class_err.js.html +13 -11
  25. package/docs/class_log.js.html +104 -54
  26. package/docs/class_plugin.js.html +47 -37
  27. package/docs/class_print.js.html +47 -46
  28. package/docs/class_tools.js.html +9 -3
  29. package/docs/data/search.json +1 -1
  30. package/docs/global.html +1 -1
  31. package/docs/index.html +1 -1
  32. package/docs/index.js.html +8 -4
  33. package/docs/{class__helper.js.html → lib_helper.js.html} +208 -96
  34. package/docs/lib_hook.js.html +231 -0
  35. package/docs/module-Helper.html +8 -1
  36. package/docs/module-Hook.html +3 -0
  37. package/docs/module-Lib.html +1 -8
  38. package/index.js +6 -2
  39. package/{class/_helper.js → lib/helper.js} +206 -94
  40. package/lib/hook.js +228 -0
  41. package/package.json +1 -1
  42. package/wiki/CHANGES.md +10 -0
  43. package/docs/class_helper_bajo.js.html +0 -398
  44. package/docs/class_helper_base.js.html +0 -246
  45. package/docs/class_misc_err.js.html +0 -129
  46. package/docs/class_misc_log.js.html +0 -210
  47. package/docs/class_misc_print.js.html +0 -267
  48. package/docs/lib_current-loc.js.html +0 -36
  49. package/docs/lib_find-deep.js.html +0 -27
  50. package/docs/lib_formats.js.html +0 -68
  51. package/docs/lib_freeze.js.html +0 -54
  52. package/docs/lib_import-module.js.html +0 -61
  53. package/docs/lib_index.js.html +0 -9
  54. package/docs/lib_log-levels.js.html +0 -38
  55. package/docs/lib_parse-args-argv.js.html +0 -83
  56. package/docs/lib_parse-env.js.html +0 -53
  57. package/docs/lib_resolve-path.js.html +0 -27
  58. package/docs/lib_shim.js.html +0 -40
  59. package/docs/module-Helper_Bajo.html +0 -3
  60. package/docs/module-Helper_Base.html +0 -3
  61. package/lib/find-deep.js +0 -24
  62. package/lib/formats.js +0 -65
  63. package/lib/freeze.js +0 -51
  64. package/lib/import-module.js +0 -58
  65. package/lib/index.js +0 -6
  66. package/lib/log-levels.js +0 -35
package/.jsdoc.conf.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "display-module-header": true,
13
13
  "title": "Bajo API",
14
14
  "homepageTitle": "Bajo API",
15
- "sections": ["Classes", "Events", "Modules", "Global"],
15
+ "sections": ["Classes", "Events", "Modules", "Externals", "Global"],
16
16
  "menu": [{
17
17
  "title": "NPM",
18
18
  "link": "https://www.npmjs.com/package/bajo"
package/class/app.js CHANGED
@@ -4,7 +4,7 @@ import Base from './base.js'
4
4
  import Cache from './cache.js'
5
5
  import Tools from './tools.js'
6
6
  import Plugin from './plugin.js'
7
- import { outmatchNs, parseObject, lib, runAsApplet } from './_helper.js'
7
+ import { lib, runAsApplet } from '../lib/helper.js'
8
8
  import { fileURLToPath } from 'url'
9
9
 
10
10
  const { camelCase, isPlainObject, get, reverse, map, last, without, set } = lib._
@@ -31,10 +31,45 @@ function getCallerFilename () {
31
31
  }
32
32
 
33
33
  /**
34
- * @typedef {Object} TAppEnv
34
+ * @typedef {Object} TEnv
35
+ * @memberof App
35
36
  * @property {string} dev=development
36
37
  * @property {string} prod=production
37
- * @see App
38
+ */
39
+
40
+ /**
41
+ * @callback readHandler
42
+ * @memberof App
43
+ * @param {string} text - Text to be parsed
44
+ * @param {object} options - Options object
45
+ * @returns {object} Parsed object
46
+ */
47
+
48
+ /**
49
+ * @callback writeHandler
50
+ * @memberof App
51
+ * @param {Object} data - Data to be stringified
52
+ * @param {Object} [options={}] - Options
53
+ * @param {boolean} [options.writeToFile=false] - If true, write result to a file
54
+ * @param {string} [options.saveAsFile] - The file path to save result if writeToFile is true
55
+ * @returns {string} Stringified result
56
+ */
57
+
58
+ /**
59
+ * @typedef {Object} TConfigHandler
60
+ * @memberof App
61
+ * @property {string} ns - Namespace
62
+ * @property {string} ext - File extension
63
+ * @property {App.readHandler} [readHandler] - Function to call for reading
64
+ * @property {App.writeHandler} [writeHandler] - Function to call for writing
65
+ */
66
+
67
+ /**
68
+ * @typedef {Object} TOptions
69
+ * @memberof App
70
+ * @property {string} [cwd] - Set current working directory. Defaults to the script directory
71
+ * @property {string[]} [plugins] - Array of plugins to load. If provided, it override the list in `package.json` and `.plugins` file
72
+ * @property {Object} [config] - Plugin's config object. If provided, plugin configs will no longer be read from its config files
38
73
  */
39
74
 
40
75
  /**
@@ -44,73 +79,53 @@ function getCallerFilename () {
44
79
  */
45
80
  class App {
46
81
  /**
47
- * @param {Object} [options] - App options.
48
- * @param {string} [options.cwd] - Set current working directory. Defaults to the script directory.
49
- * @param {string[]} [options.plugins] - Array of plugins to load. If provided, it override the list in ```package.json``` and ```.plugins``` file.
50
- * @param {Object} [options.config] - Plugin's config object. If provided, plugin configs will no longer be read from its config files.
82
+ * Constructor.
83
+ * @param {App.TOptions} [options={}] - Options object.
51
84
  */
52
85
  constructor (options = {}) {
53
86
  /**
54
87
  * Copy of provided options.
55
- *
56
- * @type {Object}
88
+ * @type {App.TOptions}
57
89
  */
58
90
  this.options = options
59
91
 
60
92
  /**
61
- * Your main namespace. And yes, you suppose to NOT CHANGE this.
62
- *
63
- * @memberof App
64
- * @constant {string}
65
- * @default 'main'
93
+ * Main namespace.
94
+ * @type {string}
66
95
  */
67
96
  this.mainNs = 'main'
68
97
 
69
98
  /**
70
99
  * App environments.
71
- *
72
- * @memberof App
73
- * @constant {TAppEnv}
100
+ * @type {App.TEnv}
74
101
  */
75
102
  this.envs = { dev: 'development', prod: 'production' }
76
103
 
77
104
  /**
78
105
  * Date/time when your app start.
79
- *
80
106
  * @type {Date}
81
107
  */
82
108
  this.runAt = new Date()
83
109
 
84
110
  /**
85
111
  * Applets container.
86
- *
87
112
  * @type {Array}
88
113
  */
89
114
  this.applets = []
90
115
 
91
116
  /**
92
- * Plugin's package names container. This is the list of plugins to load. It is read from ```package.json``` and ```.plugins``` file by default, but you can override it by providing ```options.plugins``` at constructor.
93
- *
94
- * @type {Array}
117
+ * Plugin's package names container. This is the list of plugins to load.
118
+ * @type {string[]}
95
119
  */
96
120
  this.pluginPkgs = options.plugins ?? []
97
121
 
98
- /**
99
- * @typedef {Object} TAppConfigHandler
100
- * @property {string} ext - File extension.
101
- * @property {function} [readHandler] - Function to call for reading.
102
- * @property {function} [writeHandler] - Function to call for writing.
103
- * @see App#configHandlers
104
- */
105
-
106
122
  /**
107
123
  * Config handlers.
108
124
  *
109
- * By default, there are two built-in handlers available: ```.js```, ```.json```
110
- * and ```.yml/.yaml```. Use plugins to add more, e.g {@link https://github.com/ardhi/bajo-config|bajo-config}
111
- * lets you to use ```.toml```.
112
- *
113
- * @type {TAppConfigHandler[]}
125
+ * By default, there are three built-in handlers: `.js`, `.json`
126
+ * and `.yml/.yaml`. Use plugins to add more, e.g {@link https://github.com/ardhi/bajo-config|bajo-config}
127
+ * lets you to use `.toml`.
128
+ * @type {Array<App.TConfigHandler>}
114
129
  */
115
130
  this.configHandlers = []
116
131
 
@@ -118,17 +133,14 @@ class App {
118
133
  * Gives you direct access to the most commonly used 3rd party library in a Bajo based app.
119
134
  * No manual import necessary, always available, anywhere, anytime!
120
135
  *
121
- * Example:
122
- * ```javascript
136
+ * @type {App.TLib}
137
+ * @example
123
138
  * const { camelCase, kebabCase } = this.app.lib._
124
139
  * console.log(camelCase('Elit commodo sit et aliqua'))
125
- * ```
126
- *
127
- * @type {TAppLib}
128
140
  */
129
141
  this.lib = lib
130
- this.lib.outmatchNs = outmatchNs.bind(this)
131
- this.lib.parseObject = parseObject.bind(this)
142
+ this.lib.outmatchNs = this.lib.outmatchNs.bind(this)
143
+ this.lib.parseObject = this.lib.parseObject.bind(this)
132
144
 
133
145
  /**
134
146
  * Instance of system log.
@@ -139,47 +151,47 @@ class App {
139
151
 
140
152
  /**
141
153
  * All plugin's base class are saved here as key-value pairs with plugin name as its key.
142
- * The special key ```Base``` && ```Tools``` is for {@link Base} & {@link Tools} class so anytime you want to
143
- * create your own plugin, just use something like this:
154
+ * The special key `Base` && `Tools` is for {@link Base} & {@link Tools} class so that anytime you want to
155
+ * create your own plugin, you can just write something like this:
144
156
  *
145
- * ```javascript
157
+ * `javascript
146
158
  * class MyPlugin extends this.app.baseClass.Base {
147
159
  * ... your class
148
160
  * }
161
+ *
162
+ * @type {Object}
149
163
  */
150
164
  this.baseClass = { Base, Tools }
151
165
 
152
166
  /**
153
167
  * If app runs in applet mode, this will be the applet's name.
154
- *
155
168
  * @type {string}
156
169
  */
157
170
  this.applet = undefined
158
171
 
159
172
  /**
160
- * Program arguments.
161
- *
162
- * ```
173
+ * Parsed program arguments.
174
+ * @type {string[]}
175
+ * @see module:Helper.parseArgsArgv
176
+ * @example
163
177
  * $ node index.js arg1 arg2
164
178
  * ...
165
179
  * console.log(this.args) // it should print: ['arg1', 'arg2']
166
- * ```
167
- *
168
- * @type {string[]}
169
- * @see module:Lib.parseArgsArgv
170
180
  */
171
181
  this.args = []
172
182
 
173
183
  /**
174
- * Program options.
184
+ * Parsed program options.
175
185
  *
176
- * - Dash (```-```) breaks the string into object keys
177
- * - While colon (```:```) is used as namespace separator. If no namespace found, it is saved under ```_``` key.
186
+ * - Dash (`-`) breaks the string into object keys
187
+ * - While colon (`:`) is used as namespace separator. If no namespace found, it is saved under `_` key.
178
188
  *
179
189
  * Values are parsed automatically. See {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}
180
190
  * for details.
181
191
  *
182
- * ```
192
+ * @type {Object}
193
+ * @see module:Helper.parseArgsArgv
194
+ * @example
183
195
  * $ node index.js --my-name-first=John --my-name-last=Doe --my-birthDay=secret --nameSpace:path-subPath=true
184
196
  * ...
185
197
  * // {
@@ -191,38 +203,39 @@ class App {
191
203
  * // },
192
204
  * // nameSpace: { path: { subPath: true } }
193
205
  * // }
194
- * ```
195
- *
196
- * @type {Object}
197
- * @see module:Lib.parseArgsArgv
198
206
  */
199
207
  this.argv = {}
200
208
 
201
209
  /**
202
- * Environment variables. Support dotenv (```.env```) file too!
210
+ * Environment variables. Support dotenv (`.env`) file too!
203
211
  *
204
- * - Underscore (```_```) translates key to camel-cased one
205
- * - Double underscores (```__```) breaks the key into object keys
206
- * - While dot (```.```) is used as namespace separator. If no namespace found, it is saved under ```_``` key.
212
+ * - Underscore (`_`) translates key to camel-cased one
213
+ * - Double underscores (`__`) breaks the key into object keys
214
+ * - While dot (`.`) is used as namespace separator. If no namespace found, it is saved under `_` key.
207
215
  *
208
216
  * Values are also parsed automatically using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}.
209
217
  *
210
- * Example:
218
+ * E.g.:
211
219
  *
212
- * - ```MY_KEY=secret``````{ _: { myKey: 'secret' } }```
213
- * - ```MY_KEY__SUB_KEY=supersecret``````{ _: { myKey: { subKey: 'supersecret' } } }```
214
- * - ```MY_NS.MY_NAME=John``````{ myNs: { myName: 'John' } }```
220
+ * - `MY_KEY=secret``{ _: { myKey: 'secret' } }`
221
+ * - `MY_KEY__SUB_KEY=supersecret``{ _: { myKey: { subKey: 'supersecret' } } }`
222
+ * - `MY_NS.MY_NAME=John``{ myNs: { myName: 'John' } }`
215
223
  *
216
224
  * @type {Object}
217
- * @see module:Lib.parseEnv
225
+ * @see module:Helper.parseEnv
218
226
  */
219
227
  this.envVars = {}
220
228
 
221
229
  /**
222
- * Placeholder for boxen that will get imported from ```bajoCli``` later during boot process.
230
+ * Placeholder for boxen that will get imported from `bajoCli` later during boot process.
231
+ * @type {Object}
223
232
  */
224
233
  this.boxen = null
225
234
 
235
+ /**
236
+ * Cache instance. This is used to store temporary data in memory for faster access.
237
+ * @type {Cache}
238
+ */
226
239
  this.cache = new Cache(this)
227
240
 
228
241
  if (!options.cwd) options.cwd = process.cwd()
@@ -285,7 +298,7 @@ class App {
285
298
  *
286
299
  * @method
287
300
  * @param {string} name - Plugin name/namespace or alias.
288
- * @param {boolean} [silent] - If ```true```, silently return undefined even on error.
301
+ * @param {boolean} [silent] - If `true`, silently return undefined even on error.
289
302
  * @returns {Object} Plugin object.
290
303
  */
291
304
  getPlugin = (name, silent) => {
@@ -313,7 +326,7 @@ class App {
313
326
  *
314
327
  * @method
315
328
  * @param {string} name - Plugin name (namespace) or alias.
316
- * @param {boolean} [ensureDir=true] - Set ```true``` (default) to ensure directory is existed.
329
+ * @param {boolean} [ensureDir=true] - Set `true` (default) to ensure directory is existed.
317
330
  * @returns {string}
318
331
  */
319
332
  getPluginDataDir = (name, ensureDir = true) => {
@@ -328,8 +341,8 @@ class App {
328
341
  * Resolve file path from:
329
342
  *
330
343
  * - local/absolute file
331
- * - TNsPath (```myPlugin:/path/to/file.txt```)
332
- * - file under node_modules, e.g. ```myPlugin:node_modules/some-package/file.txt```
344
+ * - TNsPath (`myPlugin:/path/to/file.txt`)
345
+ * - file under node_modules, e.g. `myPlugin:node_modules/some-package/file.txt`
333
346
  *
334
347
  * @method
335
348
  * @param {string} file - File path, see above for supported types.
@@ -356,15 +369,15 @@ class App {
356
369
  }
357
370
 
358
371
  /**
359
- * Dumping variable on screen. Like ```console.log``` with configurable options. Useful for quick debugging and testing. You can also use it to dump variables in production without worrying about performance because it is using Bajo's built-in cache to store the result of util's inspect, so it will only be processed once for each unique variable.
372
+ * Dumping variable on screen. Like `console.log` with configurable options. Useful for quick debugging and testing. You can also use it to dump variables in production without worrying about performance because it is using Bajo's built-in cache to store the result of util's inspect, so it will only be processed once for each unique variable.
360
373
  *
361
374
  * Any argument passed to this method will be displayed on screen.
362
- * If the last argument is a boolean ```true```, app will quit rightaway after dumping.
375
+ * If the last argument is a boolean `true`, app will quit rightaway after dumping.
363
376
  *
364
- * If you have ```bajoCli``` plugin installed, variables will be displayed in a nice box using ```boxen``` package.
365
- * Otherwise, it will fallback to ```console.log``` with util's inspect result.
377
+ * If you have `bajoCli` plugin installed, variables will be displayed in a nice box using `boxen` package.
378
+ * Otherwise, it will fallback to `console.log` with util's inspect result.
366
379
  *
367
- * To have more control on how the variable is displayed, you can set options in Bajo's config under ```dump``` key.
380
+ * To have more control on how the variable is displayed, you can set options in Bajo's config under `dump` key.
368
381
  * See {@link Bajo#config} for details.
369
382
  *
370
383
  * @method
@@ -391,23 +404,29 @@ class App {
391
404
  }
392
405
 
393
406
  /**
394
- * Boot process:
407
+ * Run application:
395
408
  *
396
- * - Parsing {@link module:Lib.parseArgsArgv|program arguments, options} and {@link module:Lib.parseEnv|environment values}
409
+ * - Parsing {@link module:Helper.parseArgsArgv|program arguments, options} and {@link module:Helper.parseEnv|environment values}
397
410
  * - Create {@link Bajo|Bajo} instance & initialize it
398
- * - {@link module:Helper/Bajo.runAsApplet|Run in applet mode} if ```-a``` or ```--applet``` is given
411
+ * - {@link module:Helper/Bajo.runAsApplet|Run in applet mode} if `-a` or `--applet` is given
399
412
  *
400
- * After boot process is completed, event ```bajo:afterBootCompleted``` is emitted.
413
+ * After boot process is completed, event `bajo:afterBootCompleted` is emitted.
401
414
  *
402
- * If app mode is ```applet```, it runs your choosen applet instead.
415
+ * If app mode is `applet`, it runs your choosen applet instead.
403
416
  *
404
- * @method
405
417
  * @async
406
- * @returns {App}
407
- * @fires bajo:afterBootCompleted
418
+ * @method
419
+ * @returns {Promise<App>} App instance.
408
420
  */
409
- boot = async () => {
421
+ run = async () => {
410
422
  this.bajo = new Bajo(this)
423
+ this.configHandlers = [
424
+ { ns: 'bajo', ext: '.js', readHandler: this.bajo.fromJs },
425
+ { ns: 'bajo', ext: '.json', readHandler: this.bajo.fromJson, writeHandler: this.bajo.toJson },
426
+ { ns: 'bajo', ext: '.yaml', readHandler: this.bajo.fromYaml, writeHandler: this.bajo.toYaml },
427
+ { ns: 'bajo', ext: '.yml', readHandler: this.bajo.fromYml, writeHandler: this.bajo.toYml }
428
+ ]
429
+
411
430
  const hooks = (this.options.hooks ?? []).map(item => {
412
431
  item.src = item.src ?? 'bajo'
413
432
  return item
@@ -433,14 +452,6 @@ class App {
433
452
  // boot complete
434
453
  const elapsed = new Date() - this.runAt
435
454
  this.bajo.log.debug('bootCompleted%s', secToHms(elapsed, true))
436
- /**
437
- * Run after boot process is completed
438
- *
439
- * @global
440
- * @event bajo:afterBootComplete
441
- * @see {@tutorial hook}
442
- * @see App#boot
443
- */
444
455
  await this.bajo.runHook('bajo:afterBoot')
445
456
  if (this.applet) await runAsApplet.call(this.bajo)
446
457
  return this
@@ -450,7 +461,7 @@ class App {
450
461
  * Terminate the app and back to console.
451
462
  *
452
463
  * @method
453
- * @param {string} [signal=SIGINT] - Signal to send.
464
+ * @param {string|boolean} [signal=SIGINT] - Signal to send. Set to `true` to terminate immediately without sending any signal.
454
465
  */
455
466
  exit = (signal = 'SIGINT') => {
456
467
  if (signal === true) process.exit('1')
@@ -461,7 +472,7 @@ class App {
461
472
  * Load internationalization & languages files for particular plugin.
462
473
  *
463
474
  * @method
464
- * @param {string} ns - Plugin name.
475
+ * @param {string} ns - Plugin name (namespace)
465
476
  */
466
477
  loadIntl = (ns) => {
467
478
  const { fs } = this.lib
@@ -478,6 +489,16 @@ class App {
478
489
  }
479
490
  }
480
491
 
492
+ /**
493
+ * Prepare translation text and parameters for translation.
494
+ *
495
+ * @method
496
+ * @private
497
+ * @param {string} ns
498
+ * @param {string} text
499
+ * @param {Array} params
500
+ * @returns {Object}
501
+ */
481
502
  _prepTrans = (ns, text, params) => {
482
503
  const { fallback, supported } = this.bajo.config.intl
483
504
  const { isSet } = this.lib.aneka
@@ -515,22 +536,23 @@ class App {
515
536
  }
516
537
 
517
538
  /**
518
- * Translate text and interpolate with given ```args```.
539
+ * Translate text and interpolate with given `params`.
540
+ *
541
+ * If the last parameter is an object with `lang` key, it will use that language instead of the default one.
519
542
  *
520
543
  * There is a shortcut to this method attached on all plugins. You'll normally call that shorcut
521
- * instead of this method, because it is bound to plugin's name already
544
+ * instead of this method, because it is bound to plugin's namespace already
522
545
  *
523
- * ```javascript
546
+ * @method
547
+ * @param {string} ns - Namespace
548
+ * @param {string} text - Text to translate
549
+ * @param {...any} params - Arguments
550
+ * @returns {string}
551
+ * @example
524
552
  * ... within your main plugin
525
553
  * const translated = this.app.t('main', 'My cute cat is %s', 'purring')
526
- * // or
554
+ * // or within your plugin
527
555
  * const translated = this.t('My cute cat is %s', 'purring')
528
- * ```
529
- * @method
530
- * @param {string} ns - Namespace.
531
- * @param {string} text - Text to translate.
532
- * @param {...any} params - Arguments.
533
- * @returns {string}
534
556
  */
535
557
  t = (ns, text, ...params) => {
536
558
  const { formatText, isSet } = this.lib.aneka
@@ -547,11 +569,11 @@ class App {
547
569
  }
548
570
 
549
571
  /**
550
- * Check whether translation text/key exists
572
+ * Check whether translation text/key exists.
551
573
  *
552
574
  * @method
553
- * @param {string} ns - Namespace.
554
- * @param {string} text - Text to translate.
575
+ * @param {string} ns - Namespace
576
+ * @param {string} text - Text to translate
555
577
  * @returns {boolean}
556
578
  */
557
579
  te = (ns, text, ...params) => {
@@ -563,7 +585,7 @@ class App {
563
585
  * Helper method to list all supported config formats.
564
586
  *
565
587
  * @method
566
- * @param {boolean} [noDot] - If ```true```, it will return the list without dot prefix.
588
+ * @param {boolean} [noDot] - If `true`, it will return the list without dot prefix
567
589
  * @returns {string[]}
568
590
  */
569
591
  getConfigFormats = (noDot) => {
@@ -574,8 +596,9 @@ class App {
574
596
  /**
575
597
  * Start a plugin.
576
598
  *
599
+ * @method
577
600
  * @param {string} ns - Plugin namespace.
578
- * @param {...any} args - Arguments to pass to the plugin's start method.
601
+ * @param {...any} args - Arguments to pass to the plugin's start method
579
602
  */
580
603
  startPlugin = (ns, ...args) => {
581
604
  this[ns].start(...args)
@@ -584,8 +607,9 @@ class App {
584
607
  /**
585
608
  * Stop a plugin.
586
609
  *
610
+ * @method
587
611
  * @param {string} ns - Plugin namespace.
588
- * @param {...any} args - Arguments to pass to the plugin's stop method.
612
+ * @param {...any} args - Arguments to pass to the plugin's stop method
589
613
  */
590
614
  stopPlugin = (ns, ...args) => {
591
615
  // Disabled for now, reserved for future use. It is not a good idea to stop a plugin because other plugins might be dependent on it.