bajo 1.2.9 → 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.
- package/.jsdoc.conf.json +6 -3
- package/README.md +8 -148
- package/class/app.js +113 -0
- package/{boot/class/bajo-core.js → class/bajo.js} +448 -35
- package/{boot/class/error.js → class/base/err.js} +29 -3
- package/class/base/log.js +205 -0
- package/class/base/plugin.js +177 -0
- package/class/base/print.js +272 -0
- package/class/helper/bajo.js +344 -0
- package/class/helper/plugin.js +169 -0
- package/{boot/class/bajo-plugin.js → class/plugin.js} +60 -3
- package/docs/App.html +3 -0
- package/docs/Bajo.html +15 -0
- package/docs/BasePlugin.html +5 -0
- package/docs/Err.html +3 -0
- package/docs/Log.html +3 -0
- package/docs/Plugin.html +3 -0
- package/docs/Print.html +3 -0
- package/docs/bitcoin.jpeg +0 -0
- package/docs/class_app.js.html +116 -0
- package/docs/class_bajo.js.html +1100 -0
- package/docs/class_base_err.js.html +99 -0
- package/docs/class_base_log.js.html +208 -0
- package/docs/class_base_plugin.js.html +180 -0
- package/docs/class_base_print.js.html +275 -0
- package/docs/class_helper_bajo.js.html +347 -0
- package/docs/class_helper_plugin.js.html +172 -0
- package/docs/class_plugin.js.html +121 -0
- package/docs/data/search.json +1 -0
- package/docs/fonts/Inconsolata-Regular.ttf +0 -0
- package/docs/fonts/OpenSans-Regular.ttf +0 -0
- package/docs/fonts/WorkSans-Bold.ttf +0 -0
- package/docs/global.html +3 -0
- package/docs/index.html +3 -0
- package/docs/lib_create-method.js.html +42 -0
- package/docs/lib_formats.js.html +68 -0
- package/docs/lib_log-levels.js.html +28 -0
- package/docs/lib_resolve-path.js.html +30 -0
- package/docs/lib_shim.js.html +35 -0
- package/docs/module-class_helper_bajo.html +3 -0
- package/docs/module-class_helper_plugin.html +3 -0
- package/docs/module-lib_create-method.html +3 -0
- package/docs/module-lib_formats.html +3 -0
- package/docs/module-lib_log-levels.html +3 -0
- package/docs/module-lib_resolve-path.html +3 -0
- package/docs/module-lib_shim.html +3 -0
- package/docs/scripts/core.js +726 -0
- package/docs/scripts/core.min.js +23 -0
- package/docs/scripts/resize.js +90 -0
- package/docs/scripts/search.js +265 -0
- package/docs/scripts/search.min.js +6 -0
- package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/docs/scripts/third-party/fuse.js +9 -0
- package/docs/scripts/third-party/hljs-line-num-original.js +369 -0
- package/docs/scripts/third-party/hljs-line-num.js +1 -0
- package/docs/scripts/third-party/hljs-original.js +5171 -0
- package/docs/scripts/third-party/hljs.js +1 -0
- package/docs/scripts/third-party/popper.js +5 -0
- package/docs/scripts/third-party/tippy.js +1 -0
- package/docs/scripts/third-party/tocbot.js +672 -0
- package/docs/scripts/third-party/tocbot.min.js +1 -0
- package/docs/styles/clean-jsdoc-theme-base.css +1159 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +412 -0
- package/docs/styles/clean-jsdoc-theme-light.css +482 -0
- package/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
- package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
- package/docs/styles/clean-jsdoc-theme.min.css +1 -0
- package/docs/tutorial-contribution.html +3 -0
- package/docs/tutorial-ecosystem.html +3 -0
- package/docs/tutorial-getting-started.html +13 -0
- package/docs/tutorial-plugin-dev.html +3 -0
- package/docs/tutorial-user-guide.html +3 -0
- package/lib/create-method.js +39 -0
- package/{boot/lib → lib}/formats.js +28 -0
- package/{boot/lib → lib}/log-levels.js +16 -0
- package/{boot/lib → lib}/parse-args-argv.js +1 -1
- package/{boot/lib → lib}/resolve-path.js +12 -0
- package/{boot/lib → lib}/shim.js +10 -0
- package/misc-docs/bitcoin.jpeg +0 -0
- package/misc-docs/contribution.md +20 -0
- package/{docs → misc-docs}/ecosystem.md +41 -12
- package/misc-docs/getting-started.md +142 -0
- package/misc-docs/plugin-dev.md +0 -0
- package/misc-docs/toc.json +17 -0
- package/misc-docs/user-guide.md +1 -0
- package/package.json +14 -13
- package/bajoBook/book/doc/.metadata.json +0 -28
- package/bajoBook/book/doc/How-to-Make-a-Paper-Boat-564x400@2x.jpg +0 -0
- package/bajoBook/book/doc/pages/guides/definition.md +0 -7
- package/bajoBook/book/doc/pages/guides/intro.md +0 -3
- package/bajoBook/book/doc/pages/guides/setup.md +0 -22
- package/bajoBook/book/reference/.metadata.json +0 -152
- package/bajoBook/book/reference/concept-leadership-business-with-paper-boats.jpg +0 -0
- package/bajoBook/book/reference/pages/configuration/configuration-file.md +0 -52
- package/bajoBook/book/reference/pages/helper/break-ns-path.md +0 -24
- package/bajoBook/book/reference/pages/helper/build-collections.md +0 -19
- package/bajoBook/book/reference/pages/helper/call-helper-or-handler.md +0 -35
- package/bajoBook/book/reference/pages/helper/current-loc.md +0 -28
- package/bajoBook/book/reference/pages/helper/dayjs.md +0 -13
- package/bajoBook/book/reference/pages/helper/defaults-deep.md +0 -29
- package/bajoBook/book/reference/pages/helper/dump.md +0 -32
- package/bajoBook/book/reference/pages/helper/each-plugins.md +0 -24
- package/bajoBook/book/reference/pages/helper/envs.md +0 -11
- package/bajoBook/book/reference/pages/helper/error.md +0 -29
- package/bajoBook/book/reference/pages/helper/fatal.md +0 -18
- package/bajoBook/book/reference/pages/helper/freeze.md +0 -13
- package/bajoBook/book/reference/pages/helper/generate-id.md +0 -36
- package/bajoBook/book/reference/pages/helper/get-config.md +0 -27
- package/bajoBook/book/reference/pages/helper/get-global-module-dir.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-helper.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-item-by-name.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-key-by-value.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-module-dir.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-plugin-data-dir.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-plugin-name.md +0 -13
- package/bajoBook/book/reference/pages/helper/get-plugin.md +0 -13
- package/bajoBook/book/reference/pages/helper/import-module.md +0 -13
- package/bajoBook/book/reference/pages/helper/import-pkg.md +0 -13
- package/bajoBook/book/reference/pages/helper/is-empty-dir.md +0 -13
- package/bajoBook/book/reference/pages/helper/is-log-in-range.md +0 -13
- package/bajoBook/book/reference/pages/helper/is-set.md +0 -13
- package/bajoBook/book/reference/pages/helper/is-valid-app.md +0 -13
- package/bajoBook/book/reference/pages/helper/is-valid-plugin.md +0 -13
- package/bajoBook/book/reference/pages/helper/log-levels.md +0 -13
- package/bajoBook/book/reference/pages/helper/log.md +0 -13
- package/bajoBook/book/reference/pages/helper/paginate.md +0 -13
- package/bajoBook/book/reference/pages/helper/pascal-case.md +0 -13
- package/bajoBook/book/reference/pages/helper/print.md +0 -13
- package/bajoBook/book/reference/pages/helper/read-config.md +0 -13
- package/bajoBook/book/reference/pages/helper/read-json.md +0 -13
- package/bajoBook/book/reference/pages/helper/resolve-path.md +0 -13
- package/bajoBook/book/reference/pages/helper/resolve-tpl-path.md +0 -13
- package/bajoBook/book/reference/pages/helper/run-hook.md +0 -13
- package/bajoBook/book/reference/pages/helper/save-as-download.md +0 -13
- package/bajoBook/book/reference/pages/helper/titleize.md +0 -13
- package/bajoBook/book/reference/pages/helper/white-space.md +0 -13
- package/boot/class/app.js +0 -67
- package/boot/class/bajo-core/boot-order.js +0 -35
- package/boot/class/bajo-core/boot-plugins.js +0 -17
- package/boot/class/bajo-core/build-config.js +0 -86
- package/boot/class/bajo-core/build-plugins.js +0 -44
- package/boot/class/bajo-core/collect-config-handlers.js +0 -20
- package/boot/class/bajo-core/exit-handler.js +0 -53
- package/boot/class/bajo-core/run-as-applet.js +0 -26
- package/boot/class/bajo-plugin/attach-method.js +0 -14
- package/boot/class/bajo-plugin/build-config.js +0 -15
- package/boot/class/bajo-plugin/check-clash.js +0 -18
- package/boot/class/bajo-plugin/check-dependency.js +0 -39
- package/boot/class/bajo-plugin/collect-hooks.js +0 -31
- package/boot/class/bajo-plugin/run.js +0 -23
- package/boot/class/log.js +0 -96
- package/boot/class/plugin.js +0 -79
- package/boot/class/print.js +0 -153
- package/boot/lib/create-method.js +0 -33
- package/test/method/isSet.js +0 -43
- /package/{bajo → extend/bajo}/intl/en-US.json +0 -0
- /package/{bajo → extend/bajo}/intl/id.json +0 -0
- /package/{waibuStatic → extend/waibuStatic}/virtual.json +0 -0
- /package/{boot/index.js → index.js} +0 -0
- /package/{boot/lib → lib}/current-loc.js +0 -0
- /package/{boot/lib → lib}/dayjs.js +0 -0
- /package/{boot/lib → lib}/import-module.js +0 -0
- /package/{boot/lib → lib}/omitted-plugin-keys.js +0 -0
- /package/{boot/lib → lib}/parse-env.js +0 -0
- /package/{boot/lib → lib}/read-all-configs.js +0 -0
- /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,86 +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
|
-
plain: false,
|
|
16
|
-
applet: false,
|
|
17
|
-
traceHook: false
|
|
18
|
-
},
|
|
19
|
-
lang: Intl.DateTimeFormat().resolvedOptions().lang ?? 'en-US',
|
|
20
|
-
intl: {
|
|
21
|
-
supported: ['en-US', 'id'],
|
|
22
|
-
fallback: 'en-US',
|
|
23
|
-
lookupOrder: [],
|
|
24
|
-
format: {
|
|
25
|
-
emptyValue: '',
|
|
26
|
-
datetime: { dateStyle: 'medium', timeStyle: 'short' },
|
|
27
|
-
date: { dateStyle: 'medium' },
|
|
28
|
-
time: { timeStyle: 'short' },
|
|
29
|
-
float: { maximumFractionDigits: 2 },
|
|
30
|
-
double: { maximumFractionDigits: 5 },
|
|
31
|
-
smallint: {},
|
|
32
|
-
integer: {}
|
|
33
|
-
},
|
|
34
|
-
unitSys: {
|
|
35
|
-
'en-US': 'imperial',
|
|
36
|
-
id: 'metric'
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
exitHandler: true
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function buildBaseConfig () {
|
|
43
|
-
const { defaultsDeep } = this.lib.aneka
|
|
44
|
-
this.applet = this.app.argv._.applet
|
|
45
|
-
this.config = defaultsDeep({}, this.app.env._, this.app.argv._)
|
|
46
|
-
this.alias = this.name
|
|
47
|
-
set(this, 'dir.base', this.app.dir)
|
|
48
|
-
const path = currentLoc(import.meta).dir + '/../../..'
|
|
49
|
-
set(this, 'dir.pkg', this.resolvePath(path))
|
|
50
|
-
if (!get(this, 'dir.data')) set(this, 'dir.data', `${this.dir.base}/data`)
|
|
51
|
-
this.dir.data = this.resolvePath(this.dir.data)
|
|
52
|
-
if (!fs.existsSync(this.dir.data)) {
|
|
53
|
-
console.log('Data directory (%s) doesn\'t exist yet', this.dir.data)
|
|
54
|
-
process.exit(1)
|
|
55
|
-
}
|
|
56
|
-
fs.ensureDirSync(`${this.dir.data}/config`)
|
|
57
|
-
if (!this.dir.tmp) {
|
|
58
|
-
this.dir.tmp = `${this.resolvePath(os.tmpdir())}/${this.name}`
|
|
59
|
-
fs.ensureDirSync(this.dir.tmp)
|
|
60
|
-
}
|
|
61
|
-
this.app.addPlugin(this)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function buildExtConfig () {
|
|
65
|
-
// config merging
|
|
66
|
-
const { defaultsDeep } = this.lib.aneka
|
|
67
|
-
let resp = await readAllConfigs.call(this.app, `${this.dir.data}/config/${this.name}`)
|
|
68
|
-
resp = omitDeep(pick(resp, ['log', 'exitHandler', 'env']), omitted)
|
|
69
|
-
this.config = defaultsDeep({}, this.config, resp, defConfig)
|
|
70
|
-
this.config.env = (this.config.env ?? 'dev').toLowerCase()
|
|
71
|
-
if (values(this.envs).includes(this.config.env)) this.config.env = this.lib.aneka.getKeyByValue(this.envs, this.config.env)
|
|
72
|
-
if (!keys(this.envs).includes(this.config.env)) throw new Error(`Unknown environment '${this.config.env}'. Supported: ${this.join(keys(this.envs))}`)
|
|
73
|
-
process.env.NODE_ENV = this.envs[this.config.env]
|
|
74
|
-
if (!this.config.log.level) this.config.log.level = this.config.env === 'dev' ? 'debug' : 'info'
|
|
75
|
-
if (this.config.silent) this.config.log.level = 'silent'
|
|
76
|
-
if (this.applet) {
|
|
77
|
-
if (!this.pluginPkgs.includes('bajo-cli')) throw new Error('Applet needs to have \'bajo-cli\' loaded first')
|
|
78
|
-
if (!this.config.log.applet) this.config.log.level = 'silent'
|
|
79
|
-
this.config.exitHandler = false
|
|
80
|
-
}
|
|
81
|
-
const exts = map(this.configHandlers, 'ext')
|
|
82
|
-
this.initPrint()
|
|
83
|
-
this.initLog()
|
|
84
|
-
this.log.debug('configHandlers%s', this.join(exts))
|
|
85
|
-
this.config = this.parseObject(this.config, { parseValue: true })
|
|
86
|
-
}
|
|
@@ -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.trace('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,96 +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
|
-
import chalk from 'chalk'
|
|
6
|
-
|
|
7
|
-
const { isEmpty, without, merge } = lodash
|
|
8
|
-
|
|
9
|
-
export function isIgnored (level) {
|
|
10
|
-
const { filter, isArray } = this.lib._
|
|
11
|
-
let ignore = this.app.bajo.config.log.ignore ?? []
|
|
12
|
-
if (!isArray(ignore)) ignore = [ignore]
|
|
13
|
-
const items = filter(ignore, i => {
|
|
14
|
-
const [ns, lvl] = i.split(':')
|
|
15
|
-
if (lvl) return ns === this.name && lvl === level
|
|
16
|
-
return ns === this.name
|
|
17
|
-
})
|
|
18
|
-
return items.length > 0
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
class Log {
|
|
22
|
-
constructor (plugin) {
|
|
23
|
-
this.plugin = plugin
|
|
24
|
-
this.format = 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
init = () => {
|
|
28
|
-
this.bajoLog = this.plugin.app.bajo.config.log.logger ?? 'bajoLogger'
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
write = (text, ...args) => {
|
|
32
|
-
return this.plugin.print.write(text, ...args)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
isExtLogger = () => {
|
|
36
|
-
return this.plugin.app[this.bajoLog] && this.plugin.app[this.bajoLog].logger
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
isIgnored = level => {
|
|
40
|
-
return isIgnored.call(this.plugin, level)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
child = () => {
|
|
44
|
-
if (this.isExtLogger()) return this.plugin.app[this.bajoLog].logger.child()
|
|
45
|
-
return this.plugin.app
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
formatMsg = (level, ...params) => {
|
|
49
|
-
if (this.plugin.app.bajo.config.log.level === 'silent') return
|
|
50
|
-
if (!this.plugin.app.bajo.isLogInRange(level)) return
|
|
51
|
-
const plain = this.plugin.app.bajo.config.log.plain
|
|
52
|
-
let [data, msg, ...args] = params
|
|
53
|
-
if (typeof data === 'string') {
|
|
54
|
-
args.unshift(msg)
|
|
55
|
-
msg = data
|
|
56
|
-
data = null
|
|
57
|
-
}
|
|
58
|
-
args = without(args, undefined)
|
|
59
|
-
if (data instanceof Error) {
|
|
60
|
-
msg = 'error%s'
|
|
61
|
-
args = [data.message]
|
|
62
|
-
}
|
|
63
|
-
msg = this.write(msg, ...args)
|
|
64
|
-
if (this.plugin.app[this.bajoLog] && this.plugin.app[this.bajoLog].logger) {
|
|
65
|
-
this.plugin.app[this.bajoLog].logger[level](data, `[${this.plugin.name}] ${msg}`, ...args)
|
|
66
|
-
} else {
|
|
67
|
-
let text
|
|
68
|
-
const dt = new Date()
|
|
69
|
-
if (this.plugin.app.bajo.config.env === 'prod') {
|
|
70
|
-
const json = { level: logLevels[level].number, time: dt.valueOf(), pid: process.pid, hostname: os.hostname() }
|
|
71
|
-
if (!isEmpty(data)) merge(json, data)
|
|
72
|
-
merge(json, { msg: `[${this.plugin.name}] ${msg}` })
|
|
73
|
-
text = JSON.stringify(json)
|
|
74
|
-
} else {
|
|
75
|
-
const date = dayjs(dt).utc(true).format(this.format)
|
|
76
|
-
const tdate = plain ? `[${date}]` : chalk.cyan(date)
|
|
77
|
-
const tlevel = plain ? level.toUpperCase() : chalk[logLevels[level].color](level.toUpperCase())
|
|
78
|
-
const tplugin = plain ? `[${this.plugin.name}]` : chalk.bgBlue(`${this.plugin.name}`)
|
|
79
|
-
text = `${tdate} ${tlevel}: ${tplugin} ${msg}`
|
|
80
|
-
if (!isEmpty(data)) text += '\n' + JSON.stringify(data)
|
|
81
|
-
}
|
|
82
|
-
if (!this.isIgnored(level)) {
|
|
83
|
-
console.log(text)
|
|
84
|
-
if (data instanceof Error && level === 'trace') console.error(data)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
Object.keys(logLevels).forEach(level => {
|
|
91
|
-
Log.prototype[level] = function (...params) {
|
|
92
|
-
this.formatMsg(level, ...params)
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
export default Log
|
package/boot/class/plugin.js
DELETED
|
@@ -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
|