bajo 2.17.0 → 2.18.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/class/app.js CHANGED
@@ -3,6 +3,7 @@ import Bajo from './bajo.js'
3
3
  import Base from './base.js'
4
4
  import Cache from './cache.js'
5
5
  import Tools from './tools.js'
6
+ import Plugin from './plugin.js'
6
7
  import { outmatchNs, parseObject, lib, runAsApplet } from './_helper.js'
7
8
  import { fileURLToPath } from 'url'
8
9
 
@@ -255,6 +256,103 @@ class App {
255
256
  return this.pluginPkgs.map(pkg => camelCase(pkg))
256
257
  }
257
258
 
259
+ /**
260
+ * Get loaded plugins
261
+ *
262
+ * @method
263
+ * @param {string[]} [nss] - Array of namespaces. If empty, it returns all loaded plugins
264
+ * @returns {TPlugin[]}
265
+ */
266
+ getPlugins = (nss) => {
267
+ const allNs = nss ?? this.getAllNs()
268
+ return allNs.map(ns => this[ns])
269
+ }
270
+
271
+ /**
272
+ * Get all plugins loaded plugins
273
+ *
274
+ * @method
275
+ * @returns {TPlugin[]}
276
+ */
277
+ getAllPlugins = () => {
278
+ return this.getPlugins()
279
+ }
280
+
281
+ /**
282
+ * Get plugin by name
283
+ *
284
+ * @method
285
+ * @param {string} name - Plugin name/namespace or alias
286
+ * @param {boolean} [silent] - If ```true```, silently return undefined even on error
287
+ * @returns {Object} Plugin object
288
+ */
289
+ getPlugin = (name, silent) => {
290
+ if (!this[name]) {
291
+ // alias?
292
+ let plugin
293
+ for (const key in this) {
294
+ const item = this[key]
295
+ if (item instanceof Plugin && (item.alias === name || item.pkgName === name)) {
296
+ plugin = item
297
+ break
298
+ }
299
+ }
300
+ if (!plugin) {
301
+ if (silent) return false
302
+ throw this.bajo.error('pluginWithNameAliasNotLoaded%s', name)
303
+ }
304
+ name = plugin.ns
305
+ }
306
+ return this[name]
307
+ }
308
+
309
+ /**
310
+ * Get plugin data directory
311
+ *
312
+ * @method
313
+ * @param {string} name - Plugin name (namespace) or alias
314
+ * @param {boolean} [ensureDir=true] - Set ```true``` (default) to ensure directory is existed
315
+ * @returns {string}
316
+ */
317
+ getPluginDataDir = (name, ensureDir = true) => {
318
+ const { fs } = this.lib
319
+ const plugin = this.getPlugin(name)
320
+ const dir = `${this.bajo.dir.data}/plugins/${plugin.ns}`
321
+ if (ensureDir) fs.ensureDirSync(dir)
322
+ return dir
323
+ }
324
+
325
+ /**
326
+ * Resolve file path from:
327
+ *
328
+ * - local/absolute file
329
+ * - TNsPath (```myPlugin:/path/to/file.txt```)
330
+ * - file under node_modules, e.g. ```myPlugin:node_modules/some-package/file.txt```
331
+ *
332
+ * @method
333
+ * @param {string} file - File path, see above for supported types
334
+ * @returns {string} Resolved file path
335
+ */
336
+ getPluginFile = (file) => {
337
+ const { currentLoc } = this.lib.aneka
338
+ const { fs } = this.lib
339
+ const { trim } = this.lib._
340
+ if (!this) return file
341
+ if (file[0] === '.') file = `${currentLoc(import.meta).dir}/${trim(file.slice(1), '/')}`
342
+ if (file.includes(':')) {
343
+ if (file.slice(1, 2) === ':') return file // windows fs
344
+ const { ns, path } = this.bajo.breakNsPath(file, false)
345
+ if (ns !== 'file' && this && this[ns] && ns.length > 1) {
346
+ file = `${this[ns].dir.pkg}${path}`
347
+ if (path.startsWith('node_modules/')) {
348
+ file = `${this[ns].dir.pkg}/${path}`
349
+ if (!fs.existsSync(file)) file = `${this[ns].dir.pkg}/../${path.slice('node_modules/'.length)}`
350
+ }
351
+ }
352
+ }
353
+ return file
354
+ }
355
+
258
356
  /**
259
357
  * 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.
260
358
  *
@@ -273,7 +371,8 @@ class App {
273
371
  dump = (...args) => {
274
372
  let caller = getCallerFilename()
275
373
  caller = caller ? fileURLToPath(caller) : 'Unavailable'
276
- const terminate = last(args) === true
374
+ const opts = last(args)
375
+ const terminate = isPlainObject(opts) && opts.abort
277
376
  if (terminate) args.pop()
278
377
  const value = args.length === 1 ? args[0] : args
279
378
  const options = { ...this.bajo.config.dump }
package/class/bajo.js CHANGED
@@ -33,7 +33,7 @@ const {
33
33
  last, get, has, values, dropRight, pick
34
34
  } = lodash
35
35
 
36
- const { resolvePath, currentLoc } = aneka
36
+ const { resolvePath } = aneka
37
37
 
38
38
  /**
39
39
  * The Core. The main engine. The one and only plugin that control app's boot process and
@@ -172,7 +172,7 @@ class Bajo extends Plugin {
172
172
  [ns, subNs, subSubNs] = ns.split('.')
173
173
  if (checkNs) {
174
174
  if (!this.app[ns]) {
175
- const plugin = this.getPlugin(ns)
175
+ const plugin = this.app.getPlugin(ns)
176
176
  if (plugin) ns = plugin.ns
177
177
  }
178
178
  if (!this.app[ns]) throw this.error('unknownPluginOrNotLoaded%s')
@@ -572,77 +572,6 @@ class Bajo extends Plugin {
572
572
  return resolvePath(path.dirname(dir))
573
573
  }
574
574
 
575
- /**
576
- * Get plugin data directory
577
- *
578
- * @method
579
- * @param {string} name - Plugin name (namespace) or alias
580
- * @param {boolean} [ensureDir=true] - Set ```true``` (default) to ensure directory is existed
581
- * @returns {string}
582
- */
583
- getPluginDataDir = (name, ensureDir = true) => {
584
- const plugin = this.getPlugin(name)
585
- const dir = `${this.app.bajo.dir.data}/plugins/${plugin.ns}`
586
- if (ensureDir) fs.ensureDirSync(dir)
587
- return dir
588
- }
589
-
590
- /**
591
- * Resolve file path from:
592
- *
593
- * - local/absolute file
594
- * - TNsPath (```myPlugin:/path/to/file.txt```)
595
- * - file under node_modules, e.g. ```myPlugin:node_modules/some-package/file.txt```
596
- *
597
- * @method
598
- * @param {string} file - File path, see above for supported types
599
- * @returns {string} Resolved file path
600
- */
601
- getPluginFile = (file) => {
602
- if (!this) return file
603
- if (file[0] === '.') file = `${currentLoc(import.meta).dir}/${trim(file.slice(1), '/')}`
604
- if (file.includes(':')) {
605
- if (file.slice(1, 2) === ':') return file // windows fs
606
- const { ns, path } = this.breakNsPath(file)
607
- if (ns !== 'file' && this && this.app && this.app[ns] && ns.length > 1) {
608
- file = `${this.app[ns].dir.pkg}${path}`
609
- if (path.startsWith('node_modules/')) {
610
- file = `${this.app[ns].dir.pkg}/${path}`
611
- if (!fs.existsSync(file)) file = `${this.app[ns].dir.pkg}/../${path.slice('node_modules/'.length)}`
612
- }
613
- }
614
- }
615
- return file
616
- }
617
-
618
- /**
619
- * Get plugin by name
620
- *
621
- * @method
622
- * @param {string} name - Plugin name/namespace or alias
623
- * @param {boolean} [silent] - If ```true```, silently return undefined even on error
624
- * @returns {Object} Plugin object
625
- */
626
- getPlugin = (name, silent) => {
627
- if (!this.app[name]) {
628
- // alias?
629
- let plugin
630
- for (const key in this.app) {
631
- const item = this.app[key]
632
- if (item instanceof Plugin && (item.alias === name || item.pkgName === name)) {
633
- plugin = item
634
- break
635
- }
636
- }
637
- if (!plugin) {
638
- if (silent) return false
639
- throw this.error('pluginWithNameAliasNotLoaded%s', name)
640
- }
641
- name = plugin.ns
642
- }
643
- return this.app[name]
644
- }
645
-
646
575
  /**
647
576
  * Import file/module from any loaded plugins.
648
577
  *
@@ -730,7 +659,7 @@ class Bajo extends Plugin {
730
659
  * @returns {boolean}
731
660
  */
732
661
  isEmptyDir = async (dir, filterFn) => {
733
- dir = resolvePath(this.getPluginFile(dir))
662
+ dir = resolvePath(this.app.getPluginFile(dir))
734
663
  await fs.exists(dir)
735
664
  return await emptyDir(dir, filterFn)
736
665
  }
@@ -916,7 +845,7 @@ class Bajo extends Plugin {
916
845
  await this.runHook('bajo:beforeReadConfig', file, options)
917
846
  parserOpts.readFromFile = true
918
847
  if (!ns) ns = this.ns
919
- file = resolvePath(this.getPluginFile(file))
848
+ file = resolvePath(this.app.getPluginFile(file))
920
849
  let ext = path.extname(file)
921
850
  const fname = path.dirname(file) + '/' + path.basename(file, ext)
922
851
  ext = ext.toLowerCase()
@@ -1065,8 +994,8 @@ class Bajo extends Plugin {
1065
994
  * @returns {string} Full file path
1066
995
  */
1067
996
  saveAsDownload = async (file, item, printSaved = true) => {
1068
- const { print, getPluginDataDir } = this.app.bajo
1069
- const fname = increment(`${getPluginDataDir(this.ns)}/download/${trim(file, '/')}`, { fs: true })
997
+ const { print } = this.app.bajo
998
+ const fname = increment(`${this.app.getPluginDataDir(this.ns)}/download/${trim(file, '/')}`, { fs: true })
1070
999
  const dir = path.dirname(fname)
1071
1000
  if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
1072
1001
  await fs.writeFile(fname, item, 'utf8')
package/class/cache.js CHANGED
@@ -4,8 +4,7 @@ class Cache {
4
4
  }
5
5
 
6
6
  getRootDir = () => {
7
- const { getPluginDataDir } = this.app.bajo
8
- return `${getPluginDataDir('bajo')}/cache`
7
+ return `${this.app.getPluginDataDir('bajo')}/cache`
9
8
  }
10
9
 
11
10
  prep = (name, ttlDur = 0) => {
@@ -43,7 +43,7 @@ async function importModule (file, { asDefaultImport = true, asHandler, noCache
43
43
  return imported
44
44
  }
45
45
 
46
- if (this) file = this.getPluginFile(file)
46
+ if (this) file = this.app.getPluginFile(file)
47
47
  if (!fs.existsSync(file)) return
48
48
  let mod = await load(file, asDefaultImport, noCache)
49
49
  if (!asHandler) return mod
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bajo",
3
- "version": "2.17.0",
3
+ "version": "2.18.0",
4
4
  "description": "The ultimate framework for whipping up massive apps in no time",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-06-12
4
+
5
+ - [2.18.0] Move plugin related methods to ```app```
6
+ - [2.18.0] Last argument of ```app.dump()``` serves as options if it a plain object with certain keys
7
+
3
8
  ## 2026-06-03
4
9
 
5
10
  - [2.17.0] Combine all helpers to ```_helper.js```