bajo 2.21.1 → 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.
- package/.jsdoc.conf.json +1 -1
- package/class/app.js +139 -115
- package/class/bajo.js +96 -89
- package/class/base.js +25 -9
- package/class/cache.js +32 -19
- package/class/err.js +11 -9
- package/class/log.js +102 -52
- package/class/plugin.js +45 -35
- package/class/print.js +45 -44
- package/class/tools.js +7 -1
- package/docs/App.html +1 -23
- package/docs/Bajo.html +1 -6
- package/docs/Base.html +1 -1
- package/docs/Cache.html +1 -1
- package/docs/Err.html +2 -2
- package/docs/Log.html +4 -4
- package/docs/Plugin.html +1 -1
- package/docs/Print.html +1 -1
- package/docs/Tools.html +1 -1
- package/docs/class_app.js.html +141 -117
- package/docs/class_bajo.js.html +98 -91
- package/docs/class_base.js.html +27 -11
- package/docs/class_cache.js.html +34 -21
- package/docs/class_err.js.html +13 -11
- package/docs/class_log.js.html +104 -54
- package/docs/class_plugin.js.html +47 -37
- package/docs/class_print.js.html +47 -46
- package/docs/class_tools.js.html +9 -3
- package/docs/data/search.json +1 -1
- package/docs/global.html +1 -1
- package/docs/index.html +1 -1
- package/docs/index.js.html +8 -4
- package/docs/{class__helper.js.html → lib_helper.js.html} +208 -96
- package/docs/lib_hook.js.html +231 -0
- package/docs/module-Helper.html +8 -1
- package/docs/module-Hook.html +3 -0
- package/docs/module-Lib.html +1 -8
- package/index.js +1 -1
- package/{class/_helper.js → lib/helper.js} +206 -94
- package/lib/hook.js +228 -0
- package/package.json +1 -1
- package/wiki/CHANGES.md +6 -0
- package/docs/class_helper_bajo.js.html +0 -398
- package/docs/class_helper_base.js.html +0 -246
- package/docs/class_misc_err.js.html +0 -129
- package/docs/class_misc_log.js.html +0 -210
- package/docs/class_misc_print.js.html +0 -267
- package/docs/lib_current-loc.js.html +0 -36
- package/docs/lib_find-deep.js.html +0 -27
- package/docs/lib_formats.js.html +0 -68
- package/docs/lib_freeze.js.html +0 -54
- package/docs/lib_import-module.js.html +0 -61
- package/docs/lib_index.js.html +0 -9
- package/docs/lib_log-levels.js.html +0 -38
- package/docs/lib_parse-args-argv.js.html +0 -83
- package/docs/lib_parse-env.js.html +0 -53
- package/docs/lib_resolve-path.js.html +0 -27
- package/docs/lib_shim.js.html +0 -40
- package/docs/module-Helper_Bajo.html +0 -3
- package/docs/module-Helper_Base.html +0 -3
- package/lib/find-deep.js +0 -24
- package/lib/formats.js +0 -65
- package/lib/freeze.js +0 -51
- package/lib/import-module.js +0 -58
- package/lib/index.js +0 -6
- package/lib/log-levels.js +0 -35
package/class/bajo.js
CHANGED
|
@@ -8,9 +8,7 @@ import lodash from 'lodash'
|
|
|
8
8
|
import { createRequire } from 'module'
|
|
9
9
|
import fastGlob from 'fast-glob'
|
|
10
10
|
import querystring from 'querystring'
|
|
11
|
-
import
|
|
12
|
-
import logLevels from '../lib/log-levels.js'
|
|
13
|
-
import { types as formatTypes, formats } from '../lib/formats.js'
|
|
11
|
+
import { logLevels } from './log.js'
|
|
14
12
|
import * as yaml from 'js-yaml'
|
|
15
13
|
import aneka from 'aneka'
|
|
16
14
|
import {
|
|
@@ -20,8 +18,11 @@ import {
|
|
|
20
18
|
collectConfigHandlers,
|
|
21
19
|
bootOrder,
|
|
22
20
|
bootPlugins,
|
|
23
|
-
exitHandler
|
|
24
|
-
|
|
21
|
+
exitHandler,
|
|
22
|
+
importModule,
|
|
23
|
+
types as formatTypes,
|
|
24
|
+
formats
|
|
25
|
+
} from '../lib/helper.js'
|
|
25
26
|
|
|
26
27
|
const require = createRequire(import.meta.url)
|
|
27
28
|
|
|
@@ -35,9 +36,10 @@ const {
|
|
|
35
36
|
const { resolvePath, getGlobalModuleDir } = aneka
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
|
-
* Name based
|
|
39
|
+
* Name based `{ns}:{path}` format.
|
|
39
40
|
*
|
|
40
41
|
* @typedef {string} TNsPathPairs
|
|
42
|
+
* @memberof Bajo
|
|
41
43
|
* @see TNsPathResult
|
|
42
44
|
* @see Bajo#buildNsPath
|
|
43
45
|
* @see Bajo#breakNsPath
|
|
@@ -46,12 +48,28 @@ const { resolvePath, getGlobalModuleDir } = aneka
|
|
|
46
48
|
/**
|
|
47
49
|
* Object returned by {@link Bajo#getUnitFormat|bajo:getUnitFormat}.
|
|
48
50
|
*
|
|
49
|
-
* @typedef {Object}
|
|
51
|
+
* @typedef {Object} TFormatResult
|
|
52
|
+
* @memberof Bajo
|
|
50
53
|
* @property {string} unitSys - Unit system.
|
|
51
54
|
* @property {Object} format - Format object.
|
|
52
55
|
* @see Bajo#getUnitFormat
|
|
53
56
|
*/
|
|
54
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath}.
|
|
60
|
+
*
|
|
61
|
+
* @typedef {Object} TNsPathResult
|
|
62
|
+
* @memberof Bajo
|
|
63
|
+
* @property {string} ns - Namespace
|
|
64
|
+
* @property {string} [subNs] - Sub namespace
|
|
65
|
+
* @property {string} [subSubNs] - Sub of sub namespace
|
|
66
|
+
* @property {string} path - Path without query string or hash
|
|
67
|
+
* @property {string} fullPath - Full path, including query string and hash
|
|
68
|
+
* @see TNsPathPairs
|
|
69
|
+
* @see Bajo#buildNsPath
|
|
70
|
+
* @see Bajo#breakNsPath
|
|
71
|
+
*/
|
|
72
|
+
|
|
55
73
|
/**
|
|
56
74
|
* The Core. The main engine. The one and only plugin that control app's boot process and
|
|
57
75
|
* making sure all other plugins working nicely.
|
|
@@ -60,28 +78,38 @@ const { resolvePath, getGlobalModuleDir } = aneka
|
|
|
60
78
|
*/
|
|
61
79
|
class Bajo extends Plugin {
|
|
62
80
|
/**
|
|
81
|
+
* Constructor.
|
|
82
|
+
*
|
|
63
83
|
* @param {App} app - App instance. Usefull to call app method inside a plugin.
|
|
64
84
|
*/
|
|
65
85
|
constructor (app) {
|
|
66
86
|
super('bajo', app)
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Alias
|
|
90
|
+
* @type {string}
|
|
91
|
+
*/
|
|
67
92
|
this.alias = 'bajo'
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* White space characters
|
|
96
|
+
* @type {string[]}
|
|
97
|
+
*/
|
|
68
98
|
this.whiteSpace = [' ', '\t', '\n', '\r']
|
|
99
|
+
|
|
69
100
|
/**
|
|
70
101
|
* Config object.
|
|
71
102
|
*
|
|
72
|
-
* @type {
|
|
103
|
+
* @type {Bajo.TObject}
|
|
73
104
|
* @see {@tutorial config}
|
|
74
105
|
*/
|
|
75
106
|
this.config = {}
|
|
76
107
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
{ ns: 'bajo', ext: '.yml', readHandler: this.fromYml, writeHandler: this.toYml }
|
|
83
|
-
]
|
|
84
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Hooks container.
|
|
110
|
+
*
|
|
111
|
+
* @type {Array<Bajo.THook>}
|
|
112
|
+
*/
|
|
85
113
|
this.hooks = []
|
|
86
114
|
}
|
|
87
115
|
|
|
@@ -112,7 +140,20 @@ class Bajo extends Plugin {
|
|
|
112
140
|
}
|
|
113
141
|
}
|
|
114
142
|
|
|
115
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Break file path to its namespace & path infos.
|
|
145
|
+
*
|
|
146
|
+
* @method
|
|
147
|
+
* @param {Object} options - Options object
|
|
148
|
+
* @param {string} [options.file] - File path to break
|
|
149
|
+
* @param {string} [options.dir] - Base directory to remove from file path
|
|
150
|
+
* @param {string} [options.ns] - Namespace to use. If not provided, will be extracted from file path
|
|
151
|
+
* @param {string} [options.suffix] - Suffix to remove from file path
|
|
152
|
+
* @param {boolean} [options.getType] - Whether to extract type from file path
|
|
153
|
+
* @returns {Object} Namespace and path information
|
|
154
|
+
*/
|
|
155
|
+
breakNsPathFromFile = (options = {}) => {
|
|
156
|
+
const { file = '', dir = '', ns, suffix = '', getType } = options
|
|
116
157
|
let item = file.replace(dir + suffix, '')
|
|
117
158
|
let type
|
|
118
159
|
if (getType) {
|
|
@@ -136,12 +177,12 @@ class Bajo extends Plugin {
|
|
|
136
177
|
* Build ns/path pairs.
|
|
137
178
|
*
|
|
138
179
|
* @method
|
|
139
|
-
* @param {object} [options={}] - Options object
|
|
140
|
-
* @param {string} [options.ns=''] - Namespace
|
|
141
|
-
* @param {string} [options.subNs] - Sub namespace
|
|
142
|
-
* @param {string} [options.subSubNs] - Sub sub namespace
|
|
143
|
-
* @param {string} [options.path] - Path
|
|
144
|
-
* @returns {TNsPathPairs} Ns/path pairs
|
|
180
|
+
* @param {object} [options={}] - Options object
|
|
181
|
+
* @param {string} [options.ns=''] - Namespace
|
|
182
|
+
* @param {string} [options.subNs] - Sub namespace
|
|
183
|
+
* @param {string} [options.subSubNs] - Sub sub namespace
|
|
184
|
+
* @param {string} [options.path] - Path
|
|
185
|
+
* @returns {TNsPathPairs} Ns/path pairs
|
|
145
186
|
*/
|
|
146
187
|
buildNsPath = ({ ns = '', subNs, subSubNs, path } = {}) => {
|
|
147
188
|
if (subNs) ns += '.' + subNs
|
|
@@ -150,25 +191,11 @@ class Bajo extends Plugin {
|
|
|
150
191
|
}
|
|
151
192
|
|
|
152
193
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* @typedef {Object} TNsPathResult
|
|
156
|
-
* @property {string} ns - Namespace.
|
|
157
|
-
* @property {string} [subNs] - Sub namespace.
|
|
158
|
-
* @property {string} [subSubNs] - Sub of sub namespace.
|
|
159
|
-
* @property {string} path - Path without query string or hash.
|
|
160
|
-
* @property {string} fullPath - Full path, including query string and hash.
|
|
161
|
-
* @see TNsPathPairs
|
|
162
|
-
* @see Bajo#buildNsPath
|
|
163
|
-
* @see Bajo#breakNsPath
|
|
164
|
-
*/
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Break name to its namespace & path infos.
|
|
194
|
+
* Break name to its namespace & path infos
|
|
168
195
|
*
|
|
169
196
|
* @method
|
|
170
197
|
* @param {(TNsPathPairs|string)} name - Name to break
|
|
171
|
-
* @param {boolean} [checkNs=true] - If
|
|
198
|
+
* @param {boolean} [checkNs=true] - If `true` (default), namespace will be checked for its validity
|
|
172
199
|
* @returns {TNsPathResult}
|
|
173
200
|
*/
|
|
174
201
|
breakNsPath = (name = '', checkNs = true) => {
|
|
@@ -222,11 +249,11 @@ class Bajo extends Plugin {
|
|
|
222
249
|
* @method
|
|
223
250
|
* @async
|
|
224
251
|
* @param {Object} options - Options.
|
|
225
|
-
* @param {string} [options.ns] - Namespace. If not provided, defaults to
|
|
252
|
+
* @param {string} [options.ns] - Namespace. If not provided, defaults to `bajo`
|
|
226
253
|
* @param {function} [options.handler] - Handler to call while building the collection item.
|
|
227
254
|
* @param {string[]} [options.dupChecks=[]] - Array of keys to check for duplicates.
|
|
228
255
|
* @param {string} options.container - Key used as container name.
|
|
229
|
-
* @param {boolean} [options.useDefaultName=true] - If true (default) and
|
|
256
|
+
* @param {boolean} [options.useDefaultName=true] - If true (default) and `name` key is not provided, returned collection will be named `default`.
|
|
230
257
|
* @fires bajo:beforeBuildCollection
|
|
231
258
|
* @fires bajo:afterBuildCollection
|
|
232
259
|
* @returns {Object[]} The collection
|
|
@@ -239,16 +266,6 @@ class Bajo extends Plugin {
|
|
|
239
266
|
let items = get(cfg, container, [])
|
|
240
267
|
if (!isArray(items)) items = [items]
|
|
241
268
|
this.app[ns].log.trace('collecting%s', this.t(container))
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Run before collection is built.
|
|
245
|
-
*
|
|
246
|
-
* @global
|
|
247
|
-
* @event bajo:beforeBuildCollection
|
|
248
|
-
* @param {string} container
|
|
249
|
-
* @see {@tutorial hook}
|
|
250
|
-
* @see Bajo#buildCollections
|
|
251
|
-
*/
|
|
252
269
|
await this.runHook(`${ns}:beforeBuildCollection`, container)
|
|
253
270
|
const deleted = []
|
|
254
271
|
for (const index in items) {
|
|
@@ -277,17 +294,6 @@ class Bajo extends Plugin {
|
|
|
277
294
|
}
|
|
278
295
|
|
|
279
296
|
if (!noDefault && !items.find(item => item.name === 'default')) this.app[ns].fatal('missing%s%s', 'default', container)
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Run after collection is built
|
|
283
|
-
*
|
|
284
|
-
* @global
|
|
285
|
-
* @event bajo:afterBuildCollection
|
|
286
|
-
* @param {string} container
|
|
287
|
-
* @param {Object[]} items
|
|
288
|
-
* @see {@tutorial hook}
|
|
289
|
-
* @see Bajo#buildCollections
|
|
290
|
-
*/
|
|
291
297
|
await this.runHook(`${ns}:afterBuildCollection`, container, items)
|
|
292
298
|
this.app[ns].log.debug('collected%s%d', this.t(container), items.length)
|
|
293
299
|
return items
|
|
@@ -299,7 +305,7 @@ class Bajo extends Plugin {
|
|
|
299
305
|
* - If name is a string, the corresponding plugin's method will be called with passed args as its parameters
|
|
300
306
|
* - If name is a plugin instance, this will be used as the scope instead. The first args is now the handler name and the rest are its parameters
|
|
301
307
|
* - If name is a function, this function will be run under scope with the remaining args
|
|
302
|
-
* - If name is an object and has
|
|
308
|
+
* - If name is an object and has `handler` key in it, this function handler will be instead
|
|
303
309
|
*
|
|
304
310
|
* @method
|
|
305
311
|
* @async
|
|
@@ -339,15 +345,15 @@ class Bajo extends Plugin {
|
|
|
339
345
|
* This function iterates through all loaded plugins and call the provided handler scoped as the running plugin.
|
|
340
346
|
* And an object with the following key serves as its parameter:
|
|
341
347
|
*
|
|
342
|
-
* -
|
|
343
|
-
* -
|
|
348
|
+
* - `file`: file matched the glob pattern
|
|
349
|
+
* - `dir`: plugin's base directory
|
|
344
350
|
*
|
|
345
351
|
* @method
|
|
346
352
|
* @async
|
|
347
353
|
* @param {function} handler - Function handler. Can be an async function. Scoped to the running plugin.
|
|
348
354
|
* @param {(string|Object)} [options={}] - Options. If a string is provided, it serves as the glob pattern, otherwise:
|
|
349
355
|
* @param {(string|string[])} [options.glob] - Glob pattern. If provided,
|
|
350
|
-
* @param {boolean} [options.useBajo=false] - If true, add
|
|
356
|
+
* @param {boolean} [options.useBajo=false] - If true, add `bajo` to the running plugins too.
|
|
351
357
|
* @param {string} [options.prefix=''] - Prepend glob pattern with prefix.
|
|
352
358
|
* @param {boolean} [options.noUnderscore=true] - If true (default), matched file with name starts with underscore is ignored.
|
|
353
359
|
* @param {any} [options.returnItems] - If true, each value of returned handler call will be saved as an object with running plugin name as its keys.
|
|
@@ -403,7 +409,7 @@ class Bajo extends Plugin {
|
|
|
403
409
|
* @method
|
|
404
410
|
* @param {Object} [options={}] - Options.
|
|
405
411
|
* @param {string} [options.lang] - Language to use. Defaults to the one you set in config.
|
|
406
|
-
* @param {string} [options.unitSys] - Unit system to use. Defaults to language's unit system or
|
|
412
|
+
* @param {string} [options.unitSys] - Unit system to use. Defaults to language's unit system or `metric` if unspecified.
|
|
407
413
|
* @returns {TBajoFormatResult} Returned value.
|
|
408
414
|
*/
|
|
409
415
|
getUnitFormat = (options = {}) => {
|
|
@@ -423,7 +429,7 @@ class Bajo extends Plugin {
|
|
|
423
429
|
* @param {Object} [options={}] - Options.
|
|
424
430
|
* @param {boolean} [options.withUnit=true] - Return with its unit appended.
|
|
425
431
|
* @param {string} [options.lang] - Format value according to this language. Defaults to the one you set in config.
|
|
426
|
-
* @returns {(Array|string)} Return string if
|
|
432
|
+
* @returns {(Array|string)} Return string if `withUnit` is true. Otherwise is an array of `[value, unit, separator]`.
|
|
427
433
|
*/
|
|
428
434
|
formatByType = (type, value, dataType, options = {}) => {
|
|
429
435
|
const { defaultsDeep } = this.app.lib.aneka
|
|
@@ -504,8 +510,8 @@ class Bajo extends Plugin {
|
|
|
504
510
|
* Get class method by name.
|
|
505
511
|
*
|
|
506
512
|
* @method
|
|
507
|
-
* @param {string} name - Name in format
|
|
508
|
-
* @param {boolean} [thrown=true] - If
|
|
513
|
+
* @param {string} name - Name in format `ns:methodName`.
|
|
514
|
+
* @param {boolean} [thrown=true] - If `true` (default), throw exception in case of error.
|
|
509
515
|
* @returns {function} Class method.
|
|
510
516
|
*/
|
|
511
517
|
getMethod = (name = '', thrown = true) => {
|
|
@@ -541,11 +547,11 @@ class Bajo extends Plugin {
|
|
|
541
547
|
/**
|
|
542
548
|
* Import file/module from any loaded plugins.
|
|
543
549
|
*
|
|
544
|
-
* Method proxy from {@link module:
|
|
550
|
+
* Method proxy from {@link module:Helper.importModule}
|
|
545
551
|
*
|
|
546
552
|
* @method
|
|
547
553
|
* @async
|
|
548
|
-
* @see module:
|
|
554
|
+
* @see module:Helper.importModule
|
|
549
555
|
*/
|
|
550
556
|
importModule = async (file, { asDefaultImport, asHandler, noCache } = {}) => {
|
|
551
557
|
return await importModule.call(this, file, { asDefaultImport, asHandler, noCache })
|
|
@@ -555,27 +561,27 @@ class Bajo extends Plugin {
|
|
|
555
561
|
* Import one or more packages belongs to a plugin.
|
|
556
562
|
*
|
|
557
563
|
* If the last arguments passed is an object, this object serves as options object:
|
|
558
|
-
* -
|
|
559
|
-
* -
|
|
560
|
-
* -
|
|
561
|
-
* -
|
|
564
|
+
* - `returnDefault`: should return package's default export. Defaults to `true`
|
|
565
|
+
* - `throwNotFound`: should throw if package is not found. Defaults to `false`
|
|
566
|
+
* - `noCache`: always use fresh import. Defaults to `false`
|
|
567
|
+
* - `asObject`: see below. Defaults to `false`
|
|
562
568
|
*
|
|
563
569
|
* Return value:
|
|
564
|
-
* - if
|
|
570
|
+
* - if `options.asObject` is `true` (default `false`), return as object with package's names as it's keys
|
|
565
571
|
* - Otherwise depends on how many parameters are provided, it should return the named package or an array of packages
|
|
566
572
|
*
|
|
567
|
-
* Example: you want to import
|
|
568
|
-
*
|
|
573
|
+
* Example: you want to import `delay` and `chalk` from `bajo` plugin because you want to use it in your code
|
|
574
|
+
* `javascript
|
|
569
575
|
* const { importPkg } from this.app.bajo
|
|
570
576
|
* const [delay, chalk] = await importPkg('bajo:delay', 'bajo:chalk')
|
|
571
577
|
*
|
|
572
578
|
* await delay(1000)
|
|
573
579
|
* ...
|
|
574
|
-
*
|
|
580
|
+
* `
|
|
575
581
|
*
|
|
576
582
|
* @method
|
|
577
583
|
* @async
|
|
578
|
-
* @param {...TNsPathPairs} pkgs - One or more packages in format
|
|
584
|
+
* @param {...TNsPathPairs} pkgs - One or more packages in format `{ns}:{packageName}`.
|
|
579
585
|
* @returns {(Object|Array)} See above.
|
|
580
586
|
*/
|
|
581
587
|
importPkg = async (...pkgs) => {
|
|
@@ -647,7 +653,7 @@ class Bajo extends Plugin {
|
|
|
647
653
|
*
|
|
648
654
|
* @method
|
|
649
655
|
* @param {string} dir - Directory to check.
|
|
650
|
-
* @param {boolean} [returnPkg] - Set
|
|
656
|
+
* @param {boolean} [returnPkg] - Set `true` to return its package.json content.
|
|
651
657
|
* @returns {(boolean|Object)}
|
|
652
658
|
*/
|
|
653
659
|
isValidApp = (dir, returnPkg) => {
|
|
@@ -660,7 +666,7 @@ class Bajo extends Plugin {
|
|
|
660
666
|
*
|
|
661
667
|
* @method
|
|
662
668
|
* @param {string} dir - Directory to check.
|
|
663
|
-
* @param {boolean} [returnPkg] - Set
|
|
669
|
+
* @param {boolean} [returnPkg] - Set `true` to return its package.json content.
|
|
664
670
|
* @returns {(boolean|Object)}
|
|
665
671
|
*/
|
|
666
672
|
isValidPlugin = (dir, returnPkg) => {
|
|
@@ -707,10 +713,10 @@ class Bajo extends Plugin {
|
|
|
707
713
|
}
|
|
708
714
|
|
|
709
715
|
/**
|
|
710
|
-
* Read and parse file as config object. Supported types:
|
|
711
|
-
* More supports can be added using plugin. {@link https://github.com/ardhi/bajo-config|bajo-config} gives you additional supports for
|
|
716
|
+
* Read and parse file as config object. Supported types: `.js`, `.json` and `.yml/.yaml`.
|
|
717
|
+
* More supports can be added using plugin. {@link https://github.com/ardhi/bajo-config|bajo-config} gives you additional supports for `.yml`, `.yaml` and `.toml` file.
|
|
712
718
|
*
|
|
713
|
-
* If file extension is
|
|
719
|
+
* If file extension is `.*`, it will be auto detected and parsed accordingly
|
|
714
720
|
*
|
|
715
721
|
* @method
|
|
716
722
|
* @async
|
|
@@ -718,7 +724,7 @@ class Bajo extends Plugin {
|
|
|
718
724
|
* @param {Object} [options={}] - Options.
|
|
719
725
|
* @param {boolean} [options.ignoreError] - Any exception will be silently discarded.
|
|
720
726
|
* @param {string} [options.ns] - If given, use this as the scope.
|
|
721
|
-
* @param {string} [options.pattern] - If given and auto detection is on (extension is
|
|
727
|
+
* @param {string} [options.pattern] - If given and auto detection is on (extension is `.*`), it will be used for instead the default one.
|
|
722
728
|
* @param {Object} [options.defValue={}] - Default value to use if value returned empty.
|
|
723
729
|
* @param {Object} [options.parserOpts={}] - Parser setting.
|
|
724
730
|
* @param {Object} [options.globOpts={}] - {@link https://github.com/mrmlnc/fast-glob|fast-glob} options.
|
|
@@ -743,7 +749,7 @@ class Bajo extends Plugin {
|
|
|
743
749
|
const output = async (obj) => {
|
|
744
750
|
let orig = parseObject(obj)
|
|
745
751
|
if (!baseNs || extend === false) {
|
|
746
|
-
await this.runHook('bajo:afterReadConfig', file, orig, options)
|
|
752
|
+
await this.runHook('bajo.default:afterReadConfig', file, orig, options)
|
|
747
753
|
if (cache.name) await this.app.cache.save(cache.name, orig, cache.ttlDur)
|
|
748
754
|
return orig
|
|
749
755
|
}
|
|
@@ -839,7 +845,7 @@ class Bajo extends Plugin {
|
|
|
839
845
|
*
|
|
840
846
|
* @method
|
|
841
847
|
* @param {string} file - File to read.
|
|
842
|
-
* @param {boolean} [thrownNotFound=false] - If
|
|
848
|
+
* @param {boolean} [thrownNotFound=false] - If `true`, silently ignore if file is not found.
|
|
843
849
|
* @returns {Object}
|
|
844
850
|
*/
|
|
845
851
|
readJson = (file, thrownNotFound = false) => {
|
|
@@ -1043,6 +1049,7 @@ class Bajo extends Plugin {
|
|
|
1043
1049
|
* Read config using all registered config handlers. The first handler that returns a
|
|
1044
1050
|
* valid object or array will be used.
|
|
1045
1051
|
*
|
|
1052
|
+
* @method
|
|
1046
1053
|
* @param {string} input - The input string to be processed by the config handlers.
|
|
1047
1054
|
* @param {string[]} [exts] - Optional array of extensions to filter the config handlers. If provided, only handlers with matching extensions will be used.
|
|
1048
1055
|
* @param {object} [options={}] - Options to be passed to the config handlers.
|
package/class/base.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Plugin from './plugin.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* This is the class
|
|
4
|
+
* This is the class your own plugin suppose to extend. Don't use {@link Plugin} directly
|
|
5
5
|
* unless you know what you're doing.
|
|
6
6
|
*
|
|
7
7
|
* @class
|
|
@@ -9,8 +9,10 @@ import Plugin from './plugin.js'
|
|
|
9
9
|
|
|
10
10
|
class Base extends Plugin {
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Constructor.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} pkgName - Package name (the one in package.json)
|
|
15
|
+
* @param {Object} app - App instance reference. Useful to call app method inside a plugin
|
|
14
16
|
*/
|
|
15
17
|
constructor (pkgName, app) {
|
|
16
18
|
super(pkgName, app)
|
|
@@ -20,8 +22,7 @@ class Base extends Plugin {
|
|
|
20
22
|
*
|
|
21
23
|
* Semver is also supported.
|
|
22
24
|
*
|
|
23
|
-
* @
|
|
24
|
-
* @memberof Base
|
|
25
|
+
* @type {string[]}
|
|
25
26
|
*/
|
|
26
27
|
this.dependencies = []
|
|
27
28
|
|
|
@@ -31,10 +32,11 @@ class Base extends Plugin {
|
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* Load config from file in data directory, program arguments and environment variables. Level of importance:
|
|
34
|
-
*
|
|
35
|
+
* `Env Variables > Program Arguments > Config File`
|
|
35
36
|
*
|
|
36
37
|
* @method
|
|
37
38
|
* @async
|
|
39
|
+
* @returns {void}
|
|
38
40
|
*/
|
|
39
41
|
loadConfig = async () => {
|
|
40
42
|
const { defaultsDeep } = this.app.lib.aneka
|
|
@@ -65,24 +67,33 @@ class Base extends Plugin {
|
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
/**
|
|
68
|
-
* After config is read, plugin will be initialized.
|
|
69
|
-
* because after plugin is initialized, config will be deep frozen.
|
|
70
|
+
* After config is read, plugin will be initialized.
|
|
70
71
|
*
|
|
71
72
|
* @method
|
|
72
73
|
* @async
|
|
74
|
+
* @returns {void}
|
|
73
75
|
*/
|
|
74
76
|
init = async () => {
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
/**
|
|
78
|
-
* This method will be called after plugin's init
|
|
80
|
+
* This method will be called after plugin's init. You can still change your config here,
|
|
81
|
+
* because after plugin is started, config will be deep frozen
|
|
79
82
|
*
|
|
80
83
|
* @method
|
|
81
84
|
* @async
|
|
85
|
+
* @returns {void}
|
|
82
86
|
*/
|
|
83
87
|
start = async () => {
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Reserved for future use. This method will be called before plugin is stopped.
|
|
92
|
+
*
|
|
93
|
+
* @method
|
|
94
|
+
* @async
|
|
95
|
+
* @returns {void}
|
|
96
|
+
*/
|
|
86
97
|
stop = async () => {
|
|
87
98
|
}
|
|
88
99
|
|
|
@@ -92,6 +103,7 @@ class Base extends Plugin {
|
|
|
92
103
|
*
|
|
93
104
|
* @method
|
|
94
105
|
* @async
|
|
106
|
+
* @returns {void}
|
|
95
107
|
*/
|
|
96
108
|
exit = async () => {
|
|
97
109
|
await this.dispose()
|
|
@@ -99,6 +111,10 @@ class Base extends Plugin {
|
|
|
99
111
|
|
|
100
112
|
/**
|
|
101
113
|
* Dispose internal references.
|
|
114
|
+
*
|
|
115
|
+
* @async
|
|
116
|
+
* @method
|
|
117
|
+
* @returns {Promise<void>}
|
|
102
118
|
*/
|
|
103
119
|
dispose = async () => {
|
|
104
120
|
await super.dispose()
|
package/class/cache.js
CHANGED
|
@@ -5,16 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
class Cache {
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Constructor.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} app - Application container
|
|
9
11
|
*/
|
|
10
12
|
constructor (app) {
|
|
11
13
|
this.app = app
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
|
-
* Get root
|
|
17
|
+
* Get root directory for this class. It will be used to store all cache files, organized by namespace and TTL.
|
|
16
18
|
*
|
|
17
|
-
* @
|
|
19
|
+
* @method
|
|
20
|
+
* @returns {string} Absolute cache root directory
|
|
18
21
|
*/
|
|
19
22
|
getRootDir = () => {
|
|
20
23
|
return `${this.app.getPluginDataDir('bajo')}/cache`
|
|
@@ -23,9 +26,10 @@ class Cache {
|
|
|
23
26
|
/**
|
|
24
27
|
* Prepare cache paths for a namespaced key and TTL.
|
|
25
28
|
*
|
|
26
|
-
* @
|
|
27
|
-
* @param {
|
|
28
|
-
* @
|
|
29
|
+
* @method
|
|
30
|
+
* @param {string} name - Cache key in namespaced path format
|
|
31
|
+
* @param {number|string} [ttlDur=0] - TTL duration (milliseconds or parseable duration)
|
|
32
|
+
* @returns {{dir: string, file: string, cacheDir: string}|undefined} Prepared paths or undefined when not cacheable
|
|
29
33
|
*/
|
|
30
34
|
prep = (name, ttlDur = 0) => {
|
|
31
35
|
const { breakNsPath } = this.app.bajo
|
|
@@ -43,9 +47,10 @@ class Cache {
|
|
|
43
47
|
/**
|
|
44
48
|
* Load cached content when available and not expired.
|
|
45
49
|
*
|
|
46
|
-
* @
|
|
47
|
-
* @param {
|
|
48
|
-
* @
|
|
50
|
+
* @method
|
|
51
|
+
* @param {string} name - Cache key in namespaced path format
|
|
52
|
+
* @param {number|string} [ttlDur=0] - TTL duration (milliseconds or parseable duration)
|
|
53
|
+
* @returns {Promise<any>} Cached value, or undefined if missing/expired
|
|
49
54
|
*/
|
|
50
55
|
load = async (name, ttlDur = 0) => {
|
|
51
56
|
const { fs } = this.app.lib
|
|
@@ -67,10 +72,11 @@ class Cache {
|
|
|
67
72
|
/**
|
|
68
73
|
* Save a value into cache for the given key and TTL directory.
|
|
69
74
|
*
|
|
70
|
-
* @
|
|
71
|
-
* @param {
|
|
72
|
-
* @param {
|
|
73
|
-
* @
|
|
75
|
+
* @method
|
|
76
|
+
* @param {string} name - Cache key in namespaced path format
|
|
77
|
+
* @param {any} item - Value to persist
|
|
78
|
+
* @param {number|string} [ttlDur=0] - TTL duration (milliseconds or parseable duration)
|
|
79
|
+
* @returns {Promise<void>} Resolves when the value is written
|
|
74
80
|
*/
|
|
75
81
|
save = async (name, item, ttlDur = 0) => {
|
|
76
82
|
const { fs } = this.app.lib
|
|
@@ -88,10 +94,11 @@ class Cache {
|
|
|
88
94
|
/**
|
|
89
95
|
* Return cached content, and store the fallback value if cache is empty.
|
|
90
96
|
*
|
|
91
|
-
* @
|
|
92
|
-
* @param {
|
|
93
|
-
* @param {
|
|
94
|
-
* @
|
|
97
|
+
* @method
|
|
98
|
+
* @param {string} name - Cache key in namespaced path format
|
|
99
|
+
* @param {any} item - Fallback value to save when cache miss happens
|
|
100
|
+
* @param {number|string} [ttlDur=0] - TTL duration (milliseconds or parseable duration)
|
|
101
|
+
* @returns {Promise<any>} Cached content
|
|
95
102
|
*/
|
|
96
103
|
sync = async (name, item, ttlDur = 0) => {
|
|
97
104
|
const content = await this.loadCache(name, ttlDur)
|
|
@@ -102,7 +109,8 @@ class Cache {
|
|
|
102
109
|
/**
|
|
103
110
|
* Remove a specific cache namespace or all first-level namespaces.
|
|
104
111
|
*
|
|
105
|
-
* @
|
|
112
|
+
* @method
|
|
113
|
+
* @param {string} name - Namespace name or `*` for all
|
|
106
114
|
* @returns {void}
|
|
107
115
|
*/
|
|
108
116
|
_purgeItem = (name) => {
|
|
@@ -121,7 +129,8 @@ class Cache {
|
|
|
121
129
|
/**
|
|
122
130
|
* Purge cache by namespace or remove expired TTL directories.
|
|
123
131
|
*
|
|
124
|
-
* @
|
|
132
|
+
* @method
|
|
133
|
+
* @param {string} [name] - Optional namespace to remove directly
|
|
125
134
|
* @returns {void}
|
|
126
135
|
*/
|
|
127
136
|
purge = (name) => {
|
|
@@ -140,6 +149,10 @@ class Cache {
|
|
|
140
149
|
|
|
141
150
|
/**
|
|
142
151
|
* Dispose internal reference.
|
|
152
|
+
*
|
|
153
|
+
* @async
|
|
154
|
+
* @method
|
|
155
|
+
* @returns {Promise<void>}
|
|
143
156
|
*/
|
|
144
157
|
dispose = async () => {
|
|
145
158
|
this.app = null
|
package/class/err.js
CHANGED
|
@@ -8,7 +8,7 @@ Error.stackTraceLimit = 15
|
|
|
8
8
|
/**
|
|
9
9
|
* Bajo error class, a thin wrapper of node's Error object.
|
|
10
10
|
*
|
|
11
|
-
* Every Bajo {@link Plugin|plugin} has a built-in method called
|
|
11
|
+
* Every Bajo {@link Plugin|plugin} has a built-in method called `error` which basically the shortcut to create a new Err instance.
|
|
12
12
|
* It helps you create this instance anywhere in your code quickly without the hassle of importing & instantiating:
|
|
13
13
|
*
|
|
14
14
|
* ```javascript
|
|
@@ -18,30 +18,29 @@ Error.stackTraceLimit = 15
|
|
|
18
18
|
*/
|
|
19
19
|
class Err extends Tools {
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @param
|
|
21
|
+
* Constructor.
|
|
22
|
+
*
|
|
23
|
+
* @param {Plugin} plugin - Plugin instance
|
|
24
|
+
* @param {string} msg - Error message
|
|
25
|
+
* @param {...any} [args] - Variables to interpolate with error message. Payload object can be pushed at the very last argument
|
|
24
26
|
*/
|
|
25
27
|
constructor (plugin, msg, ...args) {
|
|
26
28
|
super(plugin)
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* Error payload extracted from the last arguments.
|
|
30
|
-
*
|
|
31
32
|
* @type {Object}
|
|
32
33
|
*/
|
|
33
34
|
this.payload = args.length > 0 && isPlainObject(args[args.length - 1]) ? args[args.length - 1] : {}
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Original message before translation.
|
|
37
|
-
*
|
|
38
38
|
* @type {string}
|
|
39
39
|
*/
|
|
40
40
|
this.orgMessage = msg
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Translated message.
|
|
44
|
-
*
|
|
45
44
|
* @type {string}
|
|
46
45
|
*/
|
|
47
46
|
this.message = this.payload.noTrans ? msg : this.plugin.t(msg, ...args)
|
|
@@ -51,7 +50,7 @@ class Err extends Tools {
|
|
|
51
50
|
* Write message to the console.
|
|
52
51
|
*
|
|
53
52
|
* @method
|
|
54
|
-
* @returns {Err} Error object, useful for chaining
|
|
53
|
+
* @returns {Err} - Error object, useful for chaining
|
|
55
54
|
*/
|
|
56
55
|
write = () => {
|
|
57
56
|
let err
|
|
@@ -94,8 +93,11 @@ class Err extends Tools {
|
|
|
94
93
|
/**
|
|
95
94
|
* Pretty format error details.
|
|
96
95
|
*
|
|
96
|
+
* Formatted error will be applied directly to the value parameter, and a detailsMessage
|
|
97
|
+
* will be returned for display purpose.
|
|
98
|
+
*
|
|
97
99
|
* @method
|
|
98
|
-
* @param {Object} value Value to format
|
|
100
|
+
* @param {Object} value - Value to format
|
|
99
101
|
* @returns {Object}
|
|
100
102
|
*/
|
|
101
103
|
formatErrorDetails = (value) => {
|