bajo 1.2.8 → 2.0.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 (167) hide show
  1. package/.jsdoc.conf.json +6 -3
  2. package/README.md +8 -148
  3. package/class/app.js +113 -0
  4. package/{boot/class/bajo-core.js → class/bajo.js} +449 -37
  5. package/{boot/class/error.js → class/base/err.js} +29 -3
  6. package/class/base/log.js +205 -0
  7. package/class/base/plugin.js +177 -0
  8. package/class/base/print.js +272 -0
  9. package/class/helper/bajo.js +344 -0
  10. package/class/helper/plugin.js +169 -0
  11. package/{boot/class/bajo-plugin.js → class/plugin.js} +60 -3
  12. package/docs/App.html +3 -0
  13. package/docs/Bajo.html +15 -0
  14. package/docs/BasePlugin.html +5 -0
  15. package/docs/Err.html +3 -0
  16. package/docs/Log.html +3 -0
  17. package/docs/Plugin.html +3 -0
  18. package/docs/Print.html +3 -0
  19. package/docs/bitcoin.jpeg +0 -0
  20. package/docs/class_app.js.html +116 -0
  21. package/docs/class_bajo.js.html +1100 -0
  22. package/docs/class_base_err.js.html +99 -0
  23. package/docs/class_base_log.js.html +208 -0
  24. package/docs/class_base_plugin.js.html +180 -0
  25. package/docs/class_base_print.js.html +275 -0
  26. package/docs/class_helper_bajo.js.html +347 -0
  27. package/docs/class_helper_plugin.js.html +172 -0
  28. package/docs/class_plugin.js.html +121 -0
  29. package/docs/data/search.json +1 -0
  30. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  31. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  32. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  33. package/docs/global.html +3 -0
  34. package/docs/index.html +3 -0
  35. package/docs/lib_create-method.js.html +42 -0
  36. package/docs/lib_formats.js.html +68 -0
  37. package/docs/lib_log-levels.js.html +28 -0
  38. package/docs/lib_resolve-path.js.html +30 -0
  39. package/docs/lib_shim.js.html +35 -0
  40. package/docs/module-class_helper_bajo.html +3 -0
  41. package/docs/module-class_helper_plugin.html +3 -0
  42. package/docs/module-lib_create-method.html +3 -0
  43. package/docs/module-lib_formats.html +3 -0
  44. package/docs/module-lib_log-levels.html +3 -0
  45. package/docs/module-lib_resolve-path.html +3 -0
  46. package/docs/module-lib_shim.html +3 -0
  47. package/docs/scripts/core.js +726 -0
  48. package/docs/scripts/core.min.js +23 -0
  49. package/docs/scripts/resize.js +90 -0
  50. package/docs/scripts/search.js +265 -0
  51. package/docs/scripts/search.min.js +6 -0
  52. package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
  53. package/docs/scripts/third-party/fuse.js +9 -0
  54. package/docs/scripts/third-party/hljs-line-num-original.js +369 -0
  55. package/docs/scripts/third-party/hljs-line-num.js +1 -0
  56. package/docs/scripts/third-party/hljs-original.js +5171 -0
  57. package/docs/scripts/third-party/hljs.js +1 -0
  58. package/docs/scripts/third-party/popper.js +5 -0
  59. package/docs/scripts/third-party/tippy.js +1 -0
  60. package/docs/scripts/third-party/tocbot.js +672 -0
  61. package/docs/scripts/third-party/tocbot.min.js +1 -0
  62. package/docs/styles/clean-jsdoc-theme-base.css +1159 -0
  63. package/docs/styles/clean-jsdoc-theme-dark.css +412 -0
  64. package/docs/styles/clean-jsdoc-theme-light.css +482 -0
  65. package/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
  66. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
  67. package/docs/styles/clean-jsdoc-theme.min.css +1 -0
  68. package/docs/tutorial-contribution.html +3 -0
  69. package/docs/tutorial-ecosystem.html +3 -0
  70. package/docs/tutorial-getting-started.html +13 -0
  71. package/docs/tutorial-plugin-dev.html +3 -0
  72. package/docs/tutorial-user-guide.html +3 -0
  73. package/lib/create-method.js +39 -0
  74. package/{boot/lib → lib}/formats.js +28 -0
  75. package/lib/log-levels.js +25 -0
  76. package/{boot/lib → lib}/parse-args-argv.js +1 -1
  77. package/{boot/lib → lib}/resolve-path.js +12 -0
  78. package/{boot/lib → lib}/shim.js +10 -0
  79. package/misc-docs/bitcoin.jpeg +0 -0
  80. package/misc-docs/contribution.md +20 -0
  81. package/{docs → misc-docs}/ecosystem.md +41 -12
  82. package/misc-docs/getting-started.md +142 -0
  83. package/misc-docs/plugin-dev.md +0 -0
  84. package/misc-docs/toc.json +17 -0
  85. package/misc-docs/user-guide.md +1 -0
  86. package/package.json +14 -12
  87. package/bajoBook/book/doc/.metadata.json +0 -28
  88. package/bajoBook/book/doc/How-to-Make-a-Paper-Boat-564x400@2x.jpg +0 -0
  89. package/bajoBook/book/doc/pages/guides/definition.md +0 -7
  90. package/bajoBook/book/doc/pages/guides/intro.md +0 -3
  91. package/bajoBook/book/doc/pages/guides/setup.md +0 -22
  92. package/bajoBook/book/reference/.metadata.json +0 -152
  93. package/bajoBook/book/reference/concept-leadership-business-with-paper-boats.jpg +0 -0
  94. package/bajoBook/book/reference/pages/configuration/configuration-file.md +0 -52
  95. package/bajoBook/book/reference/pages/helper/break-ns-path.md +0 -24
  96. package/bajoBook/book/reference/pages/helper/build-collections.md +0 -19
  97. package/bajoBook/book/reference/pages/helper/call-helper-or-handler.md +0 -35
  98. package/bajoBook/book/reference/pages/helper/current-loc.md +0 -28
  99. package/bajoBook/book/reference/pages/helper/dayjs.md +0 -13
  100. package/bajoBook/book/reference/pages/helper/defaults-deep.md +0 -29
  101. package/bajoBook/book/reference/pages/helper/dump.md +0 -32
  102. package/bajoBook/book/reference/pages/helper/each-plugins.md +0 -24
  103. package/bajoBook/book/reference/pages/helper/envs.md +0 -11
  104. package/bajoBook/book/reference/pages/helper/error.md +0 -29
  105. package/bajoBook/book/reference/pages/helper/fatal.md +0 -18
  106. package/bajoBook/book/reference/pages/helper/freeze.md +0 -13
  107. package/bajoBook/book/reference/pages/helper/generate-id.md +0 -36
  108. package/bajoBook/book/reference/pages/helper/get-config.md +0 -27
  109. package/bajoBook/book/reference/pages/helper/get-global-module-dir.md +0 -13
  110. package/bajoBook/book/reference/pages/helper/get-helper.md +0 -13
  111. package/bajoBook/book/reference/pages/helper/get-item-by-name.md +0 -13
  112. package/bajoBook/book/reference/pages/helper/get-key-by-value.md +0 -13
  113. package/bajoBook/book/reference/pages/helper/get-module-dir.md +0 -13
  114. package/bajoBook/book/reference/pages/helper/get-plugin-data-dir.md +0 -13
  115. package/bajoBook/book/reference/pages/helper/get-plugin-name.md +0 -13
  116. package/bajoBook/book/reference/pages/helper/get-plugin.md +0 -13
  117. package/bajoBook/book/reference/pages/helper/import-module.md +0 -13
  118. package/bajoBook/book/reference/pages/helper/import-pkg.md +0 -13
  119. package/bajoBook/book/reference/pages/helper/is-empty-dir.md +0 -13
  120. package/bajoBook/book/reference/pages/helper/is-log-in-range.md +0 -13
  121. package/bajoBook/book/reference/pages/helper/is-set.md +0 -13
  122. package/bajoBook/book/reference/pages/helper/is-valid-app.md +0 -13
  123. package/bajoBook/book/reference/pages/helper/is-valid-plugin.md +0 -13
  124. package/bajoBook/book/reference/pages/helper/log-levels.md +0 -13
  125. package/bajoBook/book/reference/pages/helper/log.md +0 -13
  126. package/bajoBook/book/reference/pages/helper/paginate.md +0 -13
  127. package/bajoBook/book/reference/pages/helper/pascal-case.md +0 -13
  128. package/bajoBook/book/reference/pages/helper/print.md +0 -13
  129. package/bajoBook/book/reference/pages/helper/read-config.md +0 -13
  130. package/bajoBook/book/reference/pages/helper/read-json.md +0 -13
  131. package/bajoBook/book/reference/pages/helper/resolve-path.md +0 -13
  132. package/bajoBook/book/reference/pages/helper/resolve-tpl-path.md +0 -13
  133. package/bajoBook/book/reference/pages/helper/run-hook.md +0 -13
  134. package/bajoBook/book/reference/pages/helper/save-as-download.md +0 -13
  135. package/bajoBook/book/reference/pages/helper/titleize.md +0 -13
  136. package/bajoBook/book/reference/pages/helper/white-space.md +0 -13
  137. package/boot/class/app.js +0 -67
  138. package/boot/class/bajo-core/boot-order.js +0 -35
  139. package/boot/class/bajo-core/boot-plugins.js +0 -17
  140. package/boot/class/bajo-core/build-config.js +0 -85
  141. package/boot/class/bajo-core/build-plugins.js +0 -44
  142. package/boot/class/bajo-core/collect-config-handlers.js +0 -20
  143. package/boot/class/bajo-core/exit-handler.js +0 -53
  144. package/boot/class/bajo-core/run-as-applet.js +0 -26
  145. package/boot/class/bajo-plugin/attach-method.js +0 -14
  146. package/boot/class/bajo-plugin/build-config.js +0 -15
  147. package/boot/class/bajo-plugin/check-clash.js +0 -18
  148. package/boot/class/bajo-plugin/check-dependency.js +0 -39
  149. package/boot/class/bajo-plugin/collect-hooks.js +0 -31
  150. package/boot/class/bajo-plugin/run.js +0 -23
  151. package/boot/class/log.js +0 -90
  152. package/boot/class/plugin.js +0 -79
  153. package/boot/class/print.js +0 -153
  154. package/boot/lib/create-method.js +0 -33
  155. package/boot/lib/log-levels.js +0 -1
  156. package/test/method/isSet.js +0 -43
  157. /package/{bajo → extend/bajo}/intl/en-US.json +0 -0
  158. /package/{bajo → extend/bajo}/intl/id.json +0 -0
  159. /package/{waibuStatic → extend/waibuStatic}/virtual.json +0 -0
  160. /package/{boot/index.js → index.js} +0 -0
  161. /package/{boot/lib → lib}/current-loc.js +0 -0
  162. /package/{boot/lib → lib}/dayjs.js +0 -0
  163. /package/{boot/lib → lib}/import-module.js +0 -0
  164. /package/{boot/lib → lib}/omitted-plugin-keys.js +0 -0
  165. /package/{boot/lib → lib}/parse-env.js +0 -0
  166. /package/{boot/lib → lib}/read-all-configs.js +0 -0
  167. /package/{docs/hook.md → misc-docs/.hook.md} +0 -0
@@ -1,35 +0,0 @@
1
- import lodash from 'lodash'
2
- import fs from 'fs-extra'
3
-
4
- const { reduce, map, isNaN, trim, forOwn, orderBy } = lodash
5
-
6
- async function bootOrder () {
7
- this.log.debug('setupBootOrder')
8
- const order = reduce(this.pluginPkgs, (o, k, i) => {
9
- const key = map(k.split(':'), m => trim(m))
10
- if (key[1] && !isNaN(Number(key[1]))) o[key[0]] = Number(key[1])
11
- else o[key[0]] = 10000 + i
12
- return o
13
- }, {})
14
- const norder = {}
15
- for (let n of this.pluginPkgs) {
16
- n = map(n.split(':'), m => trim(m))[0]
17
- const dir = n === this.mainNs ? (`${this.dir.base}/${this.mainNs}`) : this.getModuleDir(n)
18
- if (n !== this.mainNs && !fs.existsSync(dir)) throw this.error('packageNotFoundOrNotBajo%s', n)
19
- norder[n] = NaN
20
- try {
21
- norder[n] = Number(trim(await fs.readFile(`${dir}/.bootorder`, 'utf8')))
22
- } catch (err) {}
23
- }
24
- const result = []
25
- forOwn(order, (v, k) => {
26
- const item = { k, v: isNaN(norder[k]) ? v : norder[k] }
27
- result.push(item)
28
- })
29
- this.pluginPkgs = map(orderBy(result, ['v']), 'k')
30
- this.log.info('runInEnv%s', this.print.write(this.envs[this.config.env]))
31
- // misc
32
- this.freeze(this.config)
33
- }
34
-
35
- export default bootOrder
@@ -1,17 +0,0 @@
1
- import buildConfig from '../bajo-plugin/build-config.js'
2
- import checkDependency from '../bajo-plugin/check-dependency.js'
3
- import checkClash from '../bajo-plugin/check-clash.js'
4
- import attachMethod from '../bajo-plugin/attach-method.js'
5
- import collectHooks from '../bajo-plugin/collect-hooks.js'
6
- import run from '../bajo-plugin/run.js'
7
-
8
- async function bootPlugins () {
9
- await buildConfig.call(this.app)
10
- await checkClash.call(this.app)
11
- await checkDependency.call(this.app)
12
- await attachMethod.call(this.app)
13
- await collectHooks.call(this.app)
14
- await run.call(this.app)
15
- }
16
-
17
- export default bootPlugins
@@ -1,85 +0,0 @@
1
- import readAllConfigs from '../../lib/read-all-configs.js'
2
- import currentLoc from '../../lib/current-loc.js'
3
- import omitDeep from 'omit-deep'
4
- import os from 'os'
5
- import fs from 'fs-extra'
6
-
7
- import lodash from 'lodash'
8
- const { map, pick, values, keys, set, get } = lodash
9
-
10
- const omitted = ['spawn', 'cwd', 'name', 'alias', 'applet', 'a', 'plugins']
11
-
12
- const defConfig = {
13
- log: {
14
- dateFormat: 'YYYY-MM-DDTHH:MM:ss.SSS[Z]',
15
- applet: false,
16
- traceHook: false
17
- },
18
- lang: Intl.DateTimeFormat().resolvedOptions().lang ?? 'en-US',
19
- intl: {
20
- supported: ['en-US', 'id'],
21
- fallback: 'en-US',
22
- lookupOrder: [],
23
- format: {
24
- emptyValue: '',
25
- datetime: { dateStyle: 'medium', timeStyle: 'short' },
26
- date: { dateStyle: 'medium' },
27
- time: { timeStyle: 'short' },
28
- float: { maximumFractionDigits: 2 },
29
- double: { maximumFractionDigits: 5 },
30
- smallint: {},
31
- integer: {}
32
- },
33
- unitSys: {
34
- 'en-US': 'imperial',
35
- id: 'metric'
36
- }
37
- },
38
- exitHandler: true
39
- }
40
-
41
- export async function buildBaseConfig () {
42
- const { defaultsDeep } = this.lib.aneka
43
- this.applet = this.app.argv._.applet
44
- this.config = defaultsDeep({}, this.app.env._, this.app.argv._)
45
- this.alias = this.name
46
- set(this, 'dir.base', this.app.dir)
47
- const path = currentLoc(import.meta).dir + '/../../..'
48
- set(this, 'dir.pkg', this.resolvePath(path))
49
- if (!get(this, 'dir.data')) set(this, 'dir.data', `${this.dir.base}/data`)
50
- this.dir.data = this.resolvePath(this.dir.data)
51
- if (!fs.existsSync(this.dir.data)) {
52
- console.log('Data directory (%s) doesn\'t exist yet', this.dir.data)
53
- process.exit(1)
54
- }
55
- fs.ensureDirSync(`${this.dir.data}/config`)
56
- if (!this.dir.tmp) {
57
- this.dir.tmp = `${this.resolvePath(os.tmpdir())}/${this.name}`
58
- fs.ensureDirSync(this.dir.tmp)
59
- }
60
- this.app.addPlugin(this)
61
- }
62
-
63
- export async function buildExtConfig () {
64
- // config merging
65
- const { defaultsDeep } = this.lib.aneka
66
- let resp = await readAllConfigs.call(this.app, `${this.dir.data}/config/${this.name}`)
67
- resp = omitDeep(pick(resp, ['log', 'exitHandler', 'env']), omitted)
68
- this.config = defaultsDeep({}, resp, this.config, defConfig)
69
- this.config.env = (this.config.env ?? 'dev').toLowerCase()
70
- if (values(this.envs).includes(this.config.env)) this.config.env = this.lib.aneka.getKeyByValue(this.envs, this.config.env)
71
- if (!keys(this.envs).includes(this.config.env)) throw new Error(`Unknown environment '${this.config.env}'. Supported: ${this.join(keys(this.envs))}`)
72
- process.env.NODE_ENV = this.envs[this.config.env]
73
- if (!this.config.log.level) this.config.log.level = this.config.env === 'dev' ? 'debug' : 'info'
74
- if (this.config.silent) this.config.log.level = 'silent'
75
- if (this.applet) {
76
- if (!this.pluginPkgs.includes('bajo-cli')) throw new Error('Applet needs to have \'bajo-cli\' loaded first')
77
- if (!this.config.log.applet) this.config.log.level = 'silent'
78
- this.config.exitHandler = false
79
- }
80
- const exts = map(this.configHandlers, 'ext')
81
- this.initPrint()
82
- this.initLog()
83
- this.log.debug('configHandlers%s', this.join(exts))
84
- this.config = this.parseObject(this.config, { parseValue: true })
85
- }
@@ -1,44 +0,0 @@
1
- import lodash from 'lodash'
2
- import fs from 'fs-extra'
3
- import resolvePath from '../../lib/resolve-path.js'
4
-
5
- const { isString, filter, map, trim, without, uniq, camelCase, isEmpty, omit } = lodash
6
-
7
- async function buildPlugins () {
8
- let pluginPkgs = this.config.plugins ?? []
9
- if (isString(pluginPkgs)) pluginPkgs = [pluginPkgs]
10
- const pluginsFile = `${this.dir.data}/config/.plugins`
11
- if (fs.existsSync(pluginsFile)) {
12
- pluginPkgs = pluginPkgs.concat(filter(map(trim(fs.readFileSync(pluginsFile, 'utf8')).split('\n'), p => trim(p)), b => !isEmpty(b)))
13
- }
14
- this.pluginPkgs = map(filter(without(uniq(pluginPkgs), this.mainNs), p => {
15
- return p[0] !== '#'
16
- }), p => {
17
- return trim(p.split('#')[0])
18
- })
19
- this.pluginPkgs.push(this.mainNs)
20
- for (const pkg of this.pluginPkgs) {
21
- const ns = camelCase(pkg)
22
- let dir
23
- if (ns === 'main') {
24
- dir = `${this.dir.base}/${this.mainNs}`
25
- fs.ensureDirSync(dir)
26
- fs.ensureDirSync(`${dir}/plugin`)
27
- } else dir = this.getModuleDir(pkg)
28
- let plugin
29
- const factory = `${dir}/index.js`
30
- if (fs.existsSync(factory)) {
31
- const { default: builder } = await import(resolvePath(factory, true))
32
- const FactoryClass = await builder.call(this, pkg)
33
- plugin = new FactoryClass()
34
- if (!(plugin instanceof this.lib.BajoPlugin)) throw new Error(`Plugin package '${pkg}' should be an instance of BajoPlugin`)
35
- } else {
36
- plugin = new this.lib.BajoPlugin(pkg, this.app)
37
- }
38
- this.pluginNames.push(plugin.name)
39
- this.app.addPlugin(plugin)
40
- }
41
- this.config = omit(this.config, this.pluginNames)
42
- }
43
-
44
- export default buildPlugins
@@ -1,20 +0,0 @@
1
- import lodash from 'lodash'
2
- const { isFunction, isPlainObject, camelCase } = lodash
3
-
4
- async function collectConfigHandlers () {
5
- for (const pkg of this.pluginPkgs) {
6
- let dir
7
- try {
8
- dir = this.getModuleDir(pkg)
9
- } catch (err) {}
10
- if (!dir) continue
11
- const file = `${dir}/bajo/config-handlers.js`
12
- let mod = await this.importModule(file)
13
- if (!mod) continue
14
- if (isFunction(mod)) mod = await mod.call(this.app[camelCase(pkg)])
15
- if (isPlainObject(mod)) mod = [mod]
16
- this.configHandlers = this.configHandlers.concat(mod)
17
- }
18
- }
19
-
20
- export default collectConfigHandlers
@@ -1,53 +0,0 @@
1
- async function exit (signal) {
2
- const { eachPlugins } = this
3
- this.log.warn('signalReceived%s', signal)
4
- await eachPlugins(async function ({ ns }) {
5
- try {
6
- await this.stop()
7
- } catch (err) {}
8
- this.log.debug('exited')
9
- })
10
- this.log.debug('appShutdown')
11
- process.exit(0)
12
- }
13
-
14
- async function exitHandler () {
15
- if (!this.config.exitHandler) return
16
-
17
- process.on('SIGINT', async () => {
18
- await exit.call(this, 'SIGINT')
19
- })
20
-
21
- process.on('SIGTERM', async () => {
22
- await exit.call(this, 'SIGTERM')
23
- })
24
-
25
- process.on('uncaughtException', (error, origin) => {
26
- setTimeout(() => {
27
- console.error(error)
28
- // process.exit(1)
29
- }, 50)
30
- })
31
-
32
- process.on('unhandledRejection', (reason, promise) => {
33
- const stackFile = reason.stack.split('\n')[1]
34
- let file
35
- const info = stackFile.match(/\((.*)\)/) // file is in (<file>)
36
- if (info) file = info[1]
37
- else if (stackFile.startsWith(' at ')) file = stackFile.slice(7) // file is stackFile itself
38
- if (!file) return
39
- const parts = file.split(':')
40
- const column = parseInt(parts[parts.length - 1])
41
- const line = parseInt(parts[parts.length - 2])
42
- parts.pop()
43
- parts.pop()
44
- file = parts.join(':')
45
- this.log.error({ file, line, column }, '%s', reason.message)
46
- })
47
-
48
- process.on('warning', warning => {
49
- this.log.error('%s', warning.message)
50
- })
51
- }
52
-
53
- export default exitHandler
@@ -1,26 +0,0 @@
1
- async function runAsApplet () {
2
- const { isString, map, find } = this.lib._
3
- await this.eachPlugins(async function ({ file, ns, alias }) {
4
- this.app.bajo.applets.push({ ns, file, alias })
5
- }, { glob: 'applet.js', prefix: 'bajoCli' })
6
-
7
- this.log.debug('appletModeActivated')
8
- this.print.info('appRunningAsApplet')
9
- if (this.applets.length === 0) this.print.fatal('noAppletLoaded')
10
- let name = this.applet
11
- if (!isString(this.applet)) {
12
- const select = await this.importPkg('bajoCli:@inquirer/select')
13
- name = await select({
14
- message: this.print.write('Please select:'),
15
- choices: map(this.applets, t => ({ value: t.ns }))
16
- })
17
- }
18
- const [ns, path] = name.split(':')
19
- const applet = find(this.applets, a => (a.ns === ns || a.alias === ns))
20
- if (!applet) this.print.fatal('notFound%s%s', this.print.write('applet'), name)
21
- await this.runHook(`${this.app[applet.ns]}:beforeAppletRun`)
22
- await this.app.bajoCli.runApplet(applet, path, ...this.app.args)
23
- await this.runHook(`${this.app[applet.ns]}:afterAppletRun`)
24
- }
25
-
26
- export default runAsApplet
@@ -1,14 +0,0 @@
1
- import createMethod from '../../lib/create-method.js'
2
-
3
- async function attachMethod () {
4
- const { eachPlugins } = this.bajo
5
- const me = this
6
- me.bajo.log.debug('attachMethods')
7
- await eachPlugins(async function ({ ns, pkgName }) {
8
- const dir = ns === me.bajo.mainNs ? (`${me.bajo.dir.base}/${me.bajo.mainNs}`) : me.bajo.getModuleDir(pkgName)
9
- const num = await createMethod.call(me[ns], `${dir}/plugin-method`, pkgName)
10
- me.bajo.log.trace('- %s (%d)', ns, num)
11
- })
12
- }
13
-
14
- export default attachMethod
@@ -1,15 +0,0 @@
1
- import lodash from 'lodash'
2
-
3
- const { camelCase } = lodash
4
-
5
- async function buildConfig () {
6
- this.bajo.log.debug('readConfigs')
7
- for (const pkg of this.bajo.pluginPkgs) {
8
- const plugin = this[camelCase(pkg)]
9
- await plugin.loadConfig()
10
- plugin.initPrint()
11
- plugin.initLog()
12
- }
13
- }
14
-
15
- export default buildConfig
@@ -1,18 +0,0 @@
1
- import lodash from 'lodash'
2
-
3
- const { find } = lodash
4
-
5
- async function checkAlias () {
6
- const { eachPlugins } = this.bajo
7
- this.bajo.log.debug('checkAliasNameClash')
8
- const refs = []
9
- await eachPlugins(async function ({ ns, pkgName, alias }) {
10
- let item = find(refs, { ns })
11
- if (item) throw this.error('pluginNameClash%s%s%s%s', ns, pkgName, item.ns, item.pkgName, { code: 'BAJO_NAME_CLASH' })
12
- item = find(refs, { alias })
13
- if (item) throw this.error('pluginNameClash%s%s%s%s', alias, pkgName, item.alias, item.pkgName, { code: 'BAJO_ALIAS_CLASH' })
14
- refs.push({ ns, alias, pkgName })
15
- })
16
- }
17
-
18
- export default checkAlias
@@ -1,39 +0,0 @@
1
- import lodash from 'lodash'
2
- import semver from 'semver'
3
-
4
- const { reduce, map, trim, keys, intersection, each, camelCase, get } = lodash
5
-
6
- async function runner ({ ns, pkgName }) {
7
- const { join } = this.app.bajo
8
- this.app.bajo.log.trace('- %s', ns)
9
- const odep = reduce(this.dependencies, (o, k) => {
10
- const item = map(k.split('@'), m => trim(m))
11
- if (k[0] === '@') o['@' + item[1]] = item[2]
12
- else o[item[0]] = item[1]
13
- return o
14
- }, {})
15
- const deps = keys(odep)
16
- if (deps.length > 0) {
17
- if (intersection(this.app.bajo.pluginPkgs, deps).length !== deps.length) {
18
- throw this.error('dependencyUnfulfilled%s%s', pkgName, join(deps), { code: 'BAJO_DEPENDENCY' })
19
- }
20
- each(deps, d => {
21
- if (!odep[d]) return
22
- const ver = get(this.app[camelCase(d)], 'config.pkg.version')
23
- if (!ver) return
24
- if (!semver.satisfies(ver, odep[d])) {
25
- throw this.error('semverCheckFailed%s%s', pkgName, `${d}@${odep[d]}`, { code: 'BAJO_DEPENDENCY_SEMVER' })
26
- }
27
- })
28
- }
29
- }
30
-
31
- async function checkDependency () {
32
- const { eachPlugins } = this.bajo
33
- this.bajo.log.debug('checkDeps')
34
- await eachPlugins(async function ({ ns, pkgName, config }) {
35
- await runner.call(this, { ns, pkgName, config })
36
- })
37
- }
38
-
39
- export default checkDependency
@@ -1,31 +0,0 @@
1
- import lodash from 'lodash'
2
-
3
- const { merge, forOwn, groupBy } = lodash
4
-
5
- async function collectHooks () {
6
- const { eachPlugins, runHook, isLogInRange, importModule, breakNsPathFromFile } = this.bajo
7
- const me = this
8
- me.bajo.hooks = this.bajo.hooks ?? []
9
- me.bajo.log.debug('collectHooks')
10
- // collects
11
- await eachPlugins(async function ({ ns, dir, file }) {
12
- const { fullNs, path } = breakNsPathFromFile({ file, dir, baseNs: ns, suffix: '/hook/' })
13
- const mod = await importModule(file, { asHandler: true })
14
- if (!mod) return undefined
15
- merge(mod, { ns: fullNs, path, src: ns })
16
- me.bajo.hooks.push(mod)
17
- }, { glob: 'hook/**/*.js', prefix: me.bajo.name })
18
- // for log trace purpose only
19
- if (!isLogInRange('trace')) return
20
- const items = groupBy(me.bajo.hooks, 'ns')
21
- forOwn(items, (v, k) => {
22
- const hooks = groupBy(v, 'path')
23
- forOwn(hooks, (v1, k1) => {
24
- me.bajo.log.trace('- %s:%s (%d)', k, k1, v1.length)
25
- })
26
- })
27
- // run handler
28
- await runHook('bajo:afterCollectHooks')
29
- }
30
-
31
- export default collectHooks
@@ -1,23 +0,0 @@
1
- import lodash from 'lodash'
2
- const { camelCase, map } = lodash
3
-
4
- async function run () {
5
- const me = this
6
- const { runHook, eachPlugins, join } = me.bajo
7
- const { freeze } = me.bajo
8
- const methods = ['init']
9
- if (!me.bajo.applet) methods.push('start')
10
- for (const method of methods) {
11
- await runHook(`bajo:${camelCase(`before ${method} all plugins`)}`)
12
- await eachPlugins(async function ({ ns }) {
13
- if (method === 'start') freeze(me[ns].config)
14
- await runHook(`${ns}:${camelCase(`before ${method}`)}`)
15
- await me[ns][method]()
16
- await runHook(`${ns}:${camelCase(`after ${method}`)}`)
17
- })
18
- await runHook(`bajo:${camelCase(`after ${method} all plugins`)}`)
19
- }
20
- me.bajo.log.debug('loadedPlugins%s', join(map(me.bajo.pluginPkgs, b => camelCase(b))))
21
- }
22
-
23
- export default run
package/boot/class/log.js DELETED
@@ -1,90 +0,0 @@
1
- import os from 'os'
2
- import lodash from 'lodash'
3
- import dayjs from 'dayjs'
4
- import logLevels from '../lib/log-levels.js'
5
-
6
- const { isEmpty, without, merge, upperFirst } = lodash
7
-
8
- export function isIgnored (level) {
9
- const { filter, isArray } = this.lib._
10
- let ignore = this.app.bajo.config.log.ignore ?? []
11
- if (!isArray(ignore)) ignore = [ignore]
12
- const items = filter(ignore, i => {
13
- const [ns, lvl] = i.split(':')
14
- if (lvl) return ns === this.name && lvl === level
15
- return ns === this.name
16
- })
17
- return items.length > 0
18
- }
19
-
20
- class Log {
21
- constructor (plugin) {
22
- this.plugin = plugin
23
- this.format = 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'
24
- }
25
-
26
- init = () => {
27
- this.bajoLog = this.plugin.app.bajo.config.log.logger ?? 'bajoLogger'
28
- }
29
-
30
- write = (text, ...args) => {
31
- return this.plugin.print.write(text, ...args)
32
- }
33
-
34
- isExtLogger = () => {
35
- return this.plugin.app[this.bajoLog] && this.plugin.app[this.bajoLog].logger
36
- }
37
-
38
- isIgnored = level => {
39
- return isIgnored.call(this.plugin, level)
40
- }
41
-
42
- child = () => {
43
- if (this.isExtLogger()) return this.plugin.app[this.bajoLog].logger.child()
44
- return this.plugin.app
45
- }
46
-
47
- formatMsg = (level, ...params) => {
48
- if (this.plugin.app.bajo.config.log.level === 'silent') return
49
- if (!this.plugin.app.bajo.isLogInRange(level)) return
50
- let [data, msg, ...args] = params
51
- if (typeof data === 'string') {
52
- args.unshift(msg)
53
- msg = data
54
- data = null
55
- }
56
- args = without(args, undefined)
57
- if (data instanceof Error) {
58
- msg = 'error%s'
59
- args = [data.message]
60
- }
61
- msg = `[${this.plugin.name}] ${this.write(msg, ...args)}`
62
- if (this.plugin.app[this.bajoLog] && this.plugin.app[this.bajoLog].logger) {
63
- this.plugin.app[this.bajoLog].logger[level](data, msg, ...args)
64
- } else {
65
- let text
66
- const dt = new Date()
67
- if (this.plugin.app.bajo.config.env === 'prod') {
68
- const json = { level: logLevels[level], time: dt.valueOf(), pid: process.pid, hostname: os.hostname() }
69
- if (!isEmpty(data)) merge(json, data)
70
- merge(json, { msg })
71
- text = JSON.stringify(json)
72
- } else {
73
- text = `[${dayjs(dt).utc(true).format(this.format)}] ${upperFirst(level)}: ${msg}`
74
- if (!isEmpty(data)) text += '\n' + JSON.stringify(data)
75
- }
76
- if (!this.isIgnored(level)) {
77
- console.log(text)
78
- if (data instanceof Error && level === 'trace') console.error(data)
79
- }
80
- }
81
- }
82
- }
83
-
84
- Object.keys(logLevels).forEach(level => {
85
- Log.prototype[level] = function (...params) {
86
- this.formatMsg(level, ...params)
87
- }
88
- })
89
-
90
- export default Log
@@ -1,79 +0,0 @@
1
- import lodash from 'lodash'
2
- import omittedPluginKeys from '../lib/omitted-plugin-keys.js'
3
- import Log from './log.js'
4
- import Print from './print.js'
5
- import BajoError from './error.js'
6
- import fastGlob from 'fast-glob'
7
- import { sprintf } from 'sprintf-js'
8
- import outmatch from 'outmatch'
9
- import dayjs from '../lib/dayjs.js'
10
- import fs from 'fs-extra'
11
- import aneka from 'aneka/index.js'
12
-
13
- function outmatchNs (source, pattern) {
14
- const { breakNsPath } = this.app.bajo
15
- const [src, subSrc] = source.split(':')
16
- if (!subSrc) return pattern === src
17
- try {
18
- const { fullNs, path } = breakNsPath(pattern)
19
- const isMatch = outmatch(path)
20
- return src === fullNs && isMatch(subSrc)
21
- } catch (err) {
22
- return false
23
- }
24
- }
25
-
26
- const lib = {
27
- _: lodash,
28
- fs,
29
- fastGlob,
30
- sprintf,
31
- outmatch,
32
- dayjs,
33
- aneka
34
- }
35
-
36
- const { get, isEmpty, cloneDeep, omit, isPlainObject, camelCase } = lodash
37
-
38
- class Plugin {
39
- constructor (pkgName, app) {
40
- this.pkgName = pkgName
41
- this.name = camelCase(pkgName)
42
- this.app = app
43
- this.config = {}
44
- this.lib = lib
45
- this.lib.outmatchNs = outmatchNs.bind(this)
46
- }
47
-
48
- getConfig = (path, options = {}) => {
49
- let obj = isEmpty(path) ? this.config : get(this.config, path, options.defValue ?? {})
50
- options.omit = options.omit ?? omittedPluginKeys
51
- if (isPlainObject(obj) && !isEmpty(options.omit)) obj = omit(obj, options.omit)
52
- if (!options.noclone) obj = cloneDeep(obj)
53
- return obj
54
- }
55
-
56
- initLog = () => {
57
- this.log = new Log(this)
58
- this.log.init()
59
- }
60
-
61
- initPrint = (opts) => {
62
- this.print = new Print(this, opts)
63
- this.print.init()
64
- }
65
-
66
- error = (msg, ...args) => {
67
- if (!this.print) return new Error(msg, ...args)
68
- const error = new BajoError(this, msg, ...args)
69
- return error.write()
70
- }
71
-
72
- fatal = (msg, ...args) => {
73
- if (!this.print) return new Error(msg, ...args)
74
- const error = new BajoError(this, msg, ...args)
75
- return error.fatal()
76
- }
77
- }
78
-
79
- export default Plugin