bajo 2.1.0 → 2.2.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 (99) hide show
  1. package/.github/FUNDING.yml +0 -0
  2. package/.github/workflows/repo-lockdown.yml +0 -0
  3. package/.jsdoc.conf.json +0 -0
  4. package/.mocharc.json +4 -0
  5. package/LICENSE +0 -0
  6. package/README.md +0 -0
  7. package/class/{misc → app}/log.js +8 -2
  8. package/class/app.js +63 -50
  9. package/class/bajo.js +43 -211
  10. package/class/base.js +25 -22
  11. package/class/helper/bajo.js +55 -53
  12. package/class/helper/base.js +34 -75
  13. package/class/{misc → plugin}/err.js +23 -18
  14. package/class/{misc → plugin}/print.js +7 -16
  15. package/class/plugin/tools.js +42 -0
  16. package/class/plugin.js +58 -54
  17. package/docs/App.html +0 -0
  18. package/docs/Bajo.html +0 -0
  19. package/docs/Base.html +0 -0
  20. package/docs/Err.html +0 -0
  21. package/docs/Log.html +0 -0
  22. package/docs/Plugin.html +0 -0
  23. package/docs/Print.html +0 -0
  24. package/docs/class_app.js.html +0 -0
  25. package/docs/class_bajo.js.html +0 -0
  26. package/docs/class_base.js.html +0 -0
  27. package/docs/class_helper_bajo.js.html +0 -0
  28. package/docs/class_helper_base.js.html +0 -0
  29. package/docs/class_misc_err.js.html +0 -0
  30. package/docs/class_misc_log.js.html +0 -0
  31. package/docs/class_misc_print.js.html +0 -0
  32. package/docs/class_plugin.js.html +0 -0
  33. package/docs/data/search.json +0 -0
  34. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  35. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  36. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  37. package/docs/global.html +0 -0
  38. package/docs/index.html +0 -0
  39. package/docs/index.js.html +0 -0
  40. package/docs/lib_current-loc.js.html +0 -0
  41. package/docs/lib_formats.js.html +0 -0
  42. package/docs/lib_import-module.js.html +0 -0
  43. package/docs/lib_log-levels.js.html +0 -0
  44. package/docs/lib_parse-args-argv.js.html +0 -0
  45. package/docs/lib_parse-env.js.html +0 -0
  46. package/docs/lib_resolve-path.js.html +0 -0
  47. package/docs/lib_shim.js.html +0 -0
  48. package/docs/module-Helper_Bajo.html +0 -0
  49. package/docs/module-Helper_Base.html +0 -0
  50. package/docs/module-Lib.html +0 -0
  51. package/docs/scripts/core.js +476 -477
  52. package/docs/scripts/core.min.js +0 -0
  53. package/docs/scripts/resize.js +36 -36
  54. package/docs/scripts/search.js +105 -105
  55. package/docs/scripts/search.min.js +0 -0
  56. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
  57. package/docs/scripts/third-party/fuse.js +1 -1
  58. package/docs/scripts/third-party/hljs-line-num-original.js +282 -285
  59. package/docs/scripts/third-party/hljs-line-num.js +1 -1
  60. package/docs/scripts/third-party/hljs-original.js +1195 -1202
  61. package/docs/scripts/third-party/hljs.js +1 -1
  62. package/docs/scripts/third-party/popper.js +1 -1
  63. package/docs/scripts/third-party/tippy.js +1 -1
  64. package/docs/scripts/third-party/tocbot.js +508 -509
  65. package/docs/scripts/third-party/tocbot.min.js +0 -0
  66. package/docs/static/bitcoin.jpeg +0 -0
  67. package/docs/static/home.md +0 -0
  68. package/docs/static/logo-ecosystem.png +0 -0
  69. package/docs/static/logo.png +0 -0
  70. package/docs/styles/clean-jsdoc-theme-base.css +0 -0
  71. package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
  72. package/docs/styles/clean-jsdoc-theme-light.css +0 -0
  73. package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  74. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  75. package/docs/styles/clean-jsdoc-theme.min.css +0 -0
  76. package/extend/bajo/intl/en-US.json +10 -5
  77. package/extend/bajo/intl/id.json +10 -5
  78. package/extend/waibuStatic/virtual.json +0 -0
  79. package/index.js +9 -1
  80. package/lib/find-deep.js +24 -0
  81. package/lib/formats.js +0 -0
  82. package/lib/freeze.js +16 -0
  83. package/lib/import-module.js +5 -3
  84. package/lib/index.js +6 -0
  85. package/lib/log-levels.js +0 -0
  86. package/package.json +5 -11
  87. package/test/base.test.js +108 -0
  88. package/wiki/CHANGES.md +63 -0
  89. package/wiki/CONFIG.md +0 -0
  90. package/wiki/CONTRIBUTING.md +0 -0
  91. package/wiki/DEV_GUIDE.md +0 -0
  92. package/wiki/ECOSYSTEM.md +0 -0
  93. package/wiki/GETTING-STARTED.md +1 -1
  94. package/wiki/USER-GUIDE.md +0 -0
  95. package/lib/current-loc.js +0 -33
  96. package/lib/parse-args-argv.js +0 -80
  97. package/lib/parse-env.js +0 -50
  98. package/lib/resolve-path.js +0 -24
  99. package/lib/shim.js +0 -37
File without changes
File without changes
package/.jsdoc.conf.json CHANGED
File without changes
package/.mocharc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "spec": "test/**/*.test.js",
3
+ "timeout": 5000
4
+ }
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
File without changes
@@ -2,7 +2,6 @@ import os from 'os'
2
2
  import logLevels from '../../lib/log-levels.js'
3
3
  import chalk from 'chalk'
4
4
  import { stripVTControlCharacters } from 'node:util'
5
- import dayjs from 'dayjs'
6
5
 
7
6
  /**
8
7
  * Log output in stringified JSON format. Returned when app run in ```prod``` environment
@@ -163,7 +162,7 @@ class Log {
163
162
  */
164
163
  save = (text, prefix = 'bajo') => {
165
164
  const { fs } = this.app.lib
166
- let fname = this.app.bajo.config.log.rotation.byPlugin ? prefix : 'bajo'
165
+ const fname = this.app.bajo.config.log.rotation.byPlugin ? prefix : 'bajo'
167
166
  let file = `${this.logDir}/${fname}.log`
168
167
  const content = stripVTControlCharacters(text)
169
168
  const pattern = this.getRotationPattern()
@@ -250,6 +249,13 @@ class Log {
250
249
  silent = (prefix, ...params) => {
251
250
  this.formatMsg('silent', prefix, ...params)
252
251
  }
252
+
253
+ /**
254
+ * Dispose internal references
255
+ */
256
+ dispose = () => {
257
+ this.app = null
258
+ }
253
259
  }
254
260
 
255
261
  export default Log
package/class/app.js CHANGED
@@ -7,22 +7,23 @@ import outmatch from 'outmatch'
7
7
  import fs from 'fs-extra'
8
8
  import aneka from 'aneka/index.js'
9
9
  import Base from './base.js'
10
- import resolvePath from '../lib/resolve-path.js'
11
- import parseArgsArgv from '../lib/parse-args-argv.js'
12
- import parseEnv from '../lib/parse-env.js'
10
+ import freeze from '../lib/freeze.js'
13
11
  import { runAsApplet } from './helper/bajo.js'
12
+ import Tools from './plugin/tools.js'
14
13
  import dayjs from 'dayjs'
15
14
  import utc from 'dayjs/plugin/utc.js'
16
15
  import customParseFormat from 'dayjs/plugin/customParseFormat.js'
17
16
  import localizedFormat from 'dayjs/plugin/localizedFormat.js'
18
17
  import weekOfYear from 'dayjs/plugin/weekOfYear.js'
18
+ import findDeep from '../lib/find-deep.js'
19
19
 
20
20
  dayjs.extend(utc)
21
21
  dayjs.extend(customParseFormat)
22
22
  dayjs.extend(localizedFormat)
23
23
  dayjs.extend(weekOfYear)
24
24
 
25
- const { isPlainObject, get, reverse, map, isString, last, without, keys } = lodash
25
+ const { camelCase, isPlainObject, get, reverse, map, last, without } = lodash
26
+ const { pascalCase } = aneka
26
27
  let unknownLangWarning = false
27
28
 
28
29
  function outmatchNs (source, pattern) {
@@ -54,6 +55,8 @@ function outmatchNs (source, pattern) {
54
55
  * @property {Object} aneka - Access to {@link https://github.com/ardhi/aneka|aneka}
55
56
  * @property {Object} outmatch - Access to {@link https://github.com/axtgr/outmatch|outmatch}
56
57
  * @property {Object} dayjs - Access to {@link https://day.js.org|dayjs} with utc & customParseFormat plugin already applied
58
+ * @property {Object} freeze
59
+ * @property {Object} findDeep
57
60
  * @see App
58
61
  */
59
62
  const lib = {
@@ -63,7 +66,9 @@ const lib = {
63
66
  sprintf,
64
67
  outmatch,
65
68
  dayjs,
66
- aneka
69
+ aneka,
70
+ freeze,
71
+ findDeep
67
72
  }
68
73
 
69
74
  /**
@@ -72,26 +77,26 @@ const lib = {
72
77
  * @class
73
78
  */
74
79
  class App {
75
- /**
76
- * Your main namespace. And yes, you suppose to NOT CHANGE this
77
- *
78
- * @memberof App
79
- * @constant {string}
80
- * @default 'main'
81
- */
82
- static mainNs = 'main'
83
-
84
- /**
85
- * App environments
86
- * @memberof App
87
- * @constant {TAppEnv}
88
- */
89
- static envs = { dev: 'development', prod: 'production' }
90
-
91
80
  /**
92
81
  * @param {string} cwd - Current working dirctory
93
82
  */
94
83
  constructor (cwd) {
84
+ /**
85
+ * Your main namespace. And yes, you suppose to NOT CHANGE this
86
+ *
87
+ * @memberof App
88
+ * @constant {string}
89
+ * @default 'main'
90
+ */
91
+ this.mainNs = 'main'
92
+
93
+ /**
94
+ * App environments
95
+ * @memberof App
96
+ * @constant {TAppEnv}
97
+ */
98
+ this.envs = { dev: 'development', prod: 'production' }
99
+
95
100
  /**
96
101
  * Date/time when your app start
97
102
  * @type {Date}
@@ -145,6 +150,20 @@ class App {
145
150
  */
146
151
  this.lib = lib
147
152
  this.lib.outmatchNs = outmatchNs.bind(this)
153
+ this.lib.parseObject = (obj, options = {}) => {
154
+ const me = this
155
+ const { ns, lang } = options
156
+ options.translator = {
157
+ lang,
158
+ prefix: 't:',
159
+ handler: val => {
160
+ const scope = ns ? me.app[ns] : me
161
+ const [text, ...args] = val.split('|')
162
+ return scope.t(text, ...args, { lang })
163
+ }
164
+ }
165
+ return aneka.parseObject(obj, options)
166
+ }
148
167
 
149
168
  /**
150
169
  * Instance of system log
@@ -154,16 +173,16 @@ class App {
154
173
  this.log = {}
155
174
 
156
175
  /**
157
- * All plugin's class definitions are saved here as key-value pairs with plugin name as its key.
158
- * The special key ```base``` is for {@link Base}'s class so anytime you want to
176
+ * All plugin's base class are saved here as key-value pairs with plugin name as its key.
177
+ * The special key ```Base``` && ```Tools``` is for {@link Base} & {@link Tools} class so anytime you want to
159
178
  * create your own plugin, just use something like this:
160
179
  *
161
180
  * ```javascript
162
- * class MyPlugin extends this.app.pluginClass.base {
181
+ * class MyPlugin extends this.app.baseClass.Base {
163
182
  * ... your class
164
183
  * }
165
184
  */
166
- this.pluginClass = { base: Base }
185
+ this.baseClass = { Base, Tools }
167
186
 
168
187
  /**
169
188
  * If app runs in applet mode, this will be the applet's name
@@ -240,35 +259,31 @@ class App {
240
259
  const parts = l.split('=')
241
260
  cwd = parts[1]
242
261
  }
243
- this.dir = resolvePath(cwd)
262
+ this.dir = aneka.resolvePath(cwd)
244
263
  process.env.APPDIR = this.dir
245
264
  }
246
265
 
247
- get mainNs () {
248
- return this.constructor.mainNs
249
- }
250
-
251
266
  /**
252
- * Add and save plugin and it's class definition (if provided)
267
+ * Add and save plugin and it's base class definition (if provided)
253
268
  *
254
269
  * @method
255
270
  * @param {TPlugin} plugin - A valid bajo plugin
256
- * @param {Object} [pluginClass] - Plugin's class definition
271
+ * @param {Object} [baseClass] - Base class definition
257
272
  */
258
- addPlugin = (plugin, pluginClass) => {
273
+ addPlugin = (plugin, baseClass) => {
259
274
  if (this[plugin.ns]) throw new Error(`Plugin '${plugin.ns}' added already`)
260
275
  this[plugin.ns] = plugin
261
- if (pluginClass) this.pluginClass[plugin.ns] = pluginClass
276
+ if (baseClass) this.baseClass[pascalCase(plugin.ns)] = baseClass
262
277
  }
263
278
 
264
279
  /**
265
- * Get all loaded plugin namesspaces
280
+ * Get all loaded plugin namespaces
266
281
  *
267
282
  * @method
268
283
  * @returns {string[]}
269
284
  */
270
285
  getAllNs = () => {
271
- return without(keys(this.pluginClass), 'base')
286
+ return this.pluginPkgs.map(pkg => camelCase(pkg))
272
287
  }
273
288
 
274
289
  /**
@@ -284,7 +299,8 @@ class App {
284
299
  const result = util.inspect(arg, { depth: 10, colors: true })
285
300
  console.log(result)
286
301
  }
287
- if (terminate) process.kill(process.pid, 'SIGINT')
302
+ // if (terminate) process.kill(process.pid, 'SIGINT')
303
+ if (terminate) process.exit('1')
288
304
  }
289
305
 
290
306
  /**
@@ -294,27 +310,27 @@ class App {
294
310
  * - Create {@link Bajo|Bajo} instance & initialize it
295
311
  * - {@link module:Helper/Bajo.runAsApplet|Run in applet mode} if ```-a``` or ```--applet``` is given
296
312
  *
297
- * After boot process is completed, event ```bajo:afterBootComplete``` is emitted.
313
+ * After boot process is completed, event ```bajo:afterBootCompleted``` is emitted.
298
314
  *
299
315
  * If app mode is ```applet```, it runs your choosen applet instead.
300
316
  *
301
317
  * @method
302
318
  * @async
303
319
  * @returns {App}
304
- * @fires bajo:afterBootComplete
320
+ * @fires bajo:afterBootCompleted
305
321
  */
306
322
  boot = async () => {
307
323
  // argv/args/env
308
324
  this.bajo = new Bajo(this)
309
- const { argv, args } = await parseArgsArgv.call(this) ?? {}
325
+ const { argv, args } = await aneka.parseArgsArgv() ?? {}
310
326
  this.args = args
311
- this.argv = argv
312
- this.envVars = parseEnv.call(this)
327
+ this.argv = aneka.parseObject(argv, { parseValue: true })
328
+ this.envVars = aneka.parseObject(aneka.parseEnv(), { parseValue: true })
313
329
  this.applet = this.envVars._.applet ?? this.argv._.applet
314
330
  await this.bajo.init()
315
331
  // boot complete
316
332
  const elapsed = new Date() - this.runAt
317
- this.bajo.log.debug('bootCompleted%s', this.lib.aneka.secToHms(elapsed, true))
333
+ this.bajo.log.debug('bootCompleted%s', aneka.secToHms(elapsed, true))
318
334
  /**
319
335
  * Run after boot process is completed
320
336
  *
@@ -323,7 +339,7 @@ class App {
323
339
  * @see {@tutorial hook}
324
340
  * @see App#boot
325
341
  */
326
- await this.bajo.runHook('bajo:afterBootComplete')
342
+ await this.bajo.runHook('bajo:afterBootCompleted')
327
343
  if (this.applet) await runAsApplet.call(this.bajo)
328
344
  return this
329
345
  }
@@ -335,7 +351,8 @@ class App {
335
351
  * @param {string} [signal=SIGINT] - Signal to send
336
352
  */
337
353
  exit = (signal = 'SIGINT') => {
338
- process.kill(process.pid, 'SIGINT')
354
+ if (signal === true) process.exit('1')
355
+ process.kill(process.pid, signal)
339
356
  }
340
357
 
341
358
  /**
@@ -409,11 +426,7 @@ class App {
409
426
  }
410
427
  }
411
428
  if (!trans) trans = text
412
- const values = map(params, a => {
413
- if (!isString(a)) return a
414
- return a
415
- })
416
- return sprintf(trans, ...values)
429
+ return aneka.formatText(trans, ...params)
417
430
  }
418
431
 
419
432
  /**