bajo 0.3.10 → 1.0.2
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/README.md +127 -26
- package/bajoI18N/resource/id.json +31 -0
- package/boot/class/app.js +69 -0
- package/boot/class/bajo-core/helper/attach-method.js +30 -0
- package/boot/{boot-order.js → class/bajo-core/helper/boot-order.js} +10 -10
- package/boot/class/bajo-core/helper/boot-plugins.js +19 -0
- package/boot/class/bajo-core/helper/build-config.js +61 -0
- package/boot/class/bajo-core/helper/build-plugins.js +26 -0
- package/boot/class/bajo-core/helper/collect-config-handlers.js +21 -0
- package/boot/{exit-handler.js → class/bajo-core/helper/exit-handler.js} +10 -16
- package/boot/class/bajo-core/helper/run-as-applet.js +26 -0
- package/boot/class/bajo-core/method/arrange-array.js +18 -0
- package/boot/class/bajo-core/method/break-ns-path-from-file.js +24 -0
- package/boot/class/bajo-core/method/break-ns-path.js +29 -0
- package/boot/class/bajo-core/method/build-collections.js +46 -0
- package/boot/class/bajo-core/method/call-handler.js +29 -0
- package/boot/{helper → class/bajo-core/method}/defaults-deep.js +1 -1
- package/boot/class/bajo-core/method/each-plugins.js +55 -0
- package/boot/class/bajo-core/method/envs.js +7 -0
- package/boot/{helper → class/bajo-core/method}/generate-id.js +4 -0
- package/boot/{helper → class/bajo-core/method}/get-global-module-dir.js +5 -6
- package/boot/class/bajo-core/method/get-method.js +10 -0
- package/boot/{helper → class/bajo-core/method}/get-module-dir.js +3 -4
- package/boot/{helper → class/bajo-core/method}/get-plugin-data-dir.js +2 -3
- package/boot/class/bajo-core/method/get-plugin-file.js +18 -0
- package/boot/class/bajo-core/method/get-plugin.js +23 -0
- package/boot/{helper → class/bajo-core/method}/import-module.js +4 -10
- package/boot/{helper → class/bajo-core/method}/import-pkg.js +9 -3
- package/boot/class/bajo-core/method/includes.js +13 -0
- package/boot/class/bajo-core/method/is-class.js +7 -0
- package/boot/{helper → class/bajo-core/method}/is-log-in-range.js +1 -1
- package/boot/{helper → class/bajo-core/method}/is-valid-app.js +2 -2
- package/boot/class/bajo-core/method/join.js +15 -0
- package/boot/class/bajo-core/method/log-levels.js +9 -0
- package/boot/class/bajo-core/method/num-unit.js +9 -0
- package/boot/{helper → class/bajo-core/method}/parse-object.js +24 -8
- package/boot/class/bajo-core/method/read-config.js +48 -0
- package/boot/{helper → class/bajo-core/method}/read-json.js +2 -2
- package/boot/class/bajo-core/method/run-hook.js +26 -0
- package/boot/{helper → class/bajo-core/method}/save-as-download.js +2 -2
- package/boot/class/bajo-core/method/slice-string.js +13 -0
- package/boot/class/bajo-core/method/titleize.js +23 -0
- package/boot/class/bajo-core.js +30 -0
- package/boot/class/bajo-plugin/helper/attach-method.js +14 -0
- package/boot/class/bajo-plugin/helper/build-config.js +10 -0
- package/boot/class/bajo-plugin/helper/check-clash.js +16 -0
- package/boot/class/bajo-plugin/helper/check-dependency.js +37 -0
- package/boot/class/bajo-plugin/helper/collect-exit-handlers.js +14 -0
- package/boot/class/bajo-plugin/helper/collect-hooks.js +29 -0
- package/boot/class/bajo-plugin/helper/run.js +20 -0
- package/boot/class/bajo-plugin.js +78 -0
- package/boot/class/error.js +59 -0
- package/boot/class/log.js +67 -0
- package/boot/class/plugin.js +51 -0
- package/boot/class/print.js +103 -0
- package/boot/index.js +4 -51
- package/boot/lib/create-method.js +30 -0
- package/boot/{helper → lib}/current-loc.js +1 -1
- package/boot/lib/get-global-module-path.js +189 -0
- package/boot/lib/omitted-plugin-keys.js +1 -1
- package/boot/lib/parse-args-argv.js +8 -11
- package/boot/lib/parse-env.js +7 -6
- package/boot/lib/read-all-configs.js +36 -0
- package/boot/lib/translate.js +18 -0
- package/docs/ecosystem.md +55 -0
- package/docs/hook.md +11 -0
- package/package.json +54 -56
- package/test/{helper-isSet.js → method/isSet.js} +6 -4
- package/waibuStatic/virtual.json +7 -0
- package/boot/attach-helper.js +0 -40
- package/boot/build-config.js +0 -99
- package/boot/create-scope.js +0 -36
- package/boot/helper/break-ns-path.js +0 -20
- package/boot/helper/build-collections.js +0 -43
- package/boot/helper/build-name.js +0 -17
- package/boot/helper/call-helper-or-handler.js +0 -15
- package/boot/helper/dump.js +0 -14
- package/boot/helper/each-plugins.js +0 -106
- package/boot/helper/envs.js +0 -14
- package/boot/helper/error.js +0 -77
- package/boot/helper/fatal.js +0 -13
- package/boot/helper/get-config.js +0 -19
- package/boot/helper/get-helper.js +0 -12
- package/boot/helper/get-item-by-name.js +0 -26
- package/boot/helper/get-plugin-file.js +0 -16
- package/boot/helper/get-plugin-name.js +0 -39
- package/boot/helper/get-plugin.js +0 -14
- package/boot/helper/join.js +0 -11
- package/boot/helper/log-levels.js +0 -19
- package/boot/helper/read-config.js +0 -48
- package/boot/helper/resolve-tpl-path.js +0 -15
- package/boot/helper/run-hook.js +0 -49
- package/boot/helper/spinner.js +0 -9
- package/boot/helper/start-plugin.js +0 -7
- package/boot/helper/titleize.js +0 -14
- package/boot/lib/build-helper.js +0 -60
- package/boot/lib/logger.js +0 -76
- package/boot/lib/print.js +0 -138
- package/boot/plugins/attach-helper.js +0 -20
- package/boot/plugins/build-config.js +0 -68
- package/boot/plugins/check-clash.js +0 -18
- package/boot/plugins/check-dependency.js +0 -37
- package/boot/plugins/collect-config-handlers.js +0 -22
- package/boot/plugins/collect-exit-handlers.js +0 -18
- package/boot/plugins/collect-hooks.js +0 -34
- package/boot/plugins/extend-config.js +0 -21
- package/boot/plugins/index.js +0 -27
- package/boot/plugins/run.js +0 -26
- package/boot/run-tool.js +0 -41
- package/docs/boot_build-config.js.html +0 -75
- package/docs/boot_create-scope.js.html +0 -25
- package/docs/boot_index.js.html +0 -43
- package/docs/data/search.json +0 -1
- 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/helper_emit.js.html +0 -18
- package/docs/helper_envs.js.html +0 -16
- package/docs/helper_error.js.html +0 -25
- package/docs/helper_get-bajo.js.html +0 -42
- package/docs/helper_index.js.html +0 -39
- package/docs/helper_log-levels.js.html +0 -20
- package/docs/helper_set-hook.js.html +0 -38
- package/docs/helper_walk-bajos.js.html +0 -51
- package/docs/index.html +0 -16
- package/docs/module-boot.html +0 -3
- package/docs/module-boot_buildConfig.html +0 -3
- package/docs/module-boot_createScope.html +0 -3
- package/docs/module-helper.html +0 -7
- package/docs/module-helper_setHook.html +0 -4
- package/docs/module-helper_walkBajos.html +0 -6
- package/docs/scripts/core.js +0 -655
- package/docs/scripts/core.min.js +0 -23
- package/docs/scripts/resize.js +0 -90
- package/docs/scripts/search.js +0 -265
- package/docs/scripts/search.min.js +0 -6
- package/docs/scripts/third-party/Apache-License-2.0.txt +0 -202
- package/docs/scripts/third-party/fuse.js +0 -9
- package/docs/scripts/third-party/hljs-line-num-original.js +0 -369
- package/docs/scripts/third-party/hljs-line-num.js +0 -1
- package/docs/scripts/third-party/hljs-original.js +0 -5171
- package/docs/scripts/third-party/hljs.js +0 -1
- package/docs/scripts/third-party/popper.js +0 -5
- package/docs/scripts/third-party/tippy.js +0 -1
- package/docs/scripts/third-party/tocbot.js +0 -672
- package/docs/scripts/third-party/tocbot.min.js +0 -1
- package/docs/styles/clean-jsdoc-theme-base.css +0 -975
- package/docs/styles/clean-jsdoc-theme-dark.css +0 -407
- package/docs/styles/clean-jsdoc-theme-light.css +0 -388
- package/docs/styles/clean-jsdoc-theme.min.css +0 -1
- package/test/helper-error.js +0 -25
- package/test/helper-pathResolve.js +0 -28
- /package/boot/{helper → class/bajo-core/method}/get-key-by-value.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/is-empty-dir.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/is-set.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/is-valid-plugin.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/paginate.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/pascal-case.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/pick.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/resolve-path.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/round.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/sec-to-hms.js +0 -0
- /package/boot/{helper → class/bajo-core/method}/white-space.js +0 -0
package/boot/build-config.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module boot/buildConfig
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import os from 'os'
|
|
6
|
-
import fs from 'fs-extra'
|
|
7
|
-
import { get, set, pick, values, keys, uniq, without, filter, map, isEmpty, trim } from 'lodash-es'
|
|
8
|
-
import omitDeep from 'omit-deep'
|
|
9
|
-
import resolvePath from './helper/resolve-path.js'
|
|
10
|
-
import readConfig from './helper/read-config.js'
|
|
11
|
-
import getKeyByValue from './helper/get-key-by-value.js'
|
|
12
|
-
import envs from './helper/envs.js'
|
|
13
|
-
import defaultsDeep from './helper/defaults-deep.js'
|
|
14
|
-
import parseArgsArgv from './lib/parse-args-argv.js'
|
|
15
|
-
import parseEnv from './lib/parse-env.js'
|
|
16
|
-
import error from './helper/error.js'
|
|
17
|
-
import currentLoc from './helper/current-loc.js'
|
|
18
|
-
|
|
19
|
-
const configFilePick = ['log', 'plugins', 'env', 'run', 'exitHandler']
|
|
20
|
-
const configFileOmit = ['tool', 'spawn', 'cwd', 'name', 'alias']
|
|
21
|
-
|
|
22
|
-
const defConfig = {
|
|
23
|
-
dir: {},
|
|
24
|
-
log: {
|
|
25
|
-
dateFormat: 'YYYY-MM-DDTHH:MM:ss.SSS[Z]',
|
|
26
|
-
report: [],
|
|
27
|
-
tool: false
|
|
28
|
-
},
|
|
29
|
-
lang: Intl.DateTimeFormat().resolvedOptions().lang ?? 'en-US',
|
|
30
|
-
plugins: ['app'],
|
|
31
|
-
env: 'dev',
|
|
32
|
-
tool: false,
|
|
33
|
-
exitHandler: true
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Building configuration object. Read configurtion file from app data directory, program
|
|
38
|
-
* arguments and envoronment variables with following priority: ```Env > Args > Config file >
|
|
39
|
-
* defaults config```
|
|
40
|
-
*
|
|
41
|
-
* If data directory is provided and doesn't exist yet, it will be automatically created.
|
|
42
|
-
*
|
|
43
|
-
* Config file must be located in: ```<data dir>/config/bajo.<format>```, and support either
|
|
44
|
-
* ```.json``` or ```.js``` format. JS format must be a nodejs module that wrap an async
|
|
45
|
-
* function and return an object
|
|
46
|
-
*
|
|
47
|
-
* If app run tool, by default log is in silent. To activate, set log.tool to true
|
|
48
|
-
*
|
|
49
|
-
* By default, if 'app' is a bajo app, it is always the last plugins to boot. To overide this
|
|
50
|
-
* behavior, you should configure it at plugin level (i.e. using .bootorder file)
|
|
51
|
-
*
|
|
52
|
-
* @instance
|
|
53
|
-
* @async
|
|
54
|
-
* @throws Will throw if data directory is not provided
|
|
55
|
-
*
|
|
56
|
-
* @returns {Object} config
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
async function buildConfig (cwd) {
|
|
60
|
-
const { args, argv } = await parseArgsArgv()
|
|
61
|
-
const env = parseEnv()
|
|
62
|
-
const envArgv = defaultsDeep({}, env.root, argv.root)
|
|
63
|
-
envArgv.name = 'bajo'
|
|
64
|
-
envArgv.alias = 'bajo'
|
|
65
|
-
// directories
|
|
66
|
-
set(envArgv, 'dir.base', cwd)
|
|
67
|
-
set(envArgv, 'dir.pkg', resolvePath(currentLoc(import.meta).dir + '/..'))
|
|
68
|
-
if (!get(envArgv, 'dir.data')) set(envArgv, 'dir.data', `${envArgv.dir.base}/data`)
|
|
69
|
-
envArgv.dir.data = resolvePath(envArgv.dir.data)
|
|
70
|
-
if (!envArgv.dir.tmp) {
|
|
71
|
-
envArgv.dir.tmp = resolvePath(os.tmpdir()) + '/bajo'
|
|
72
|
-
fs.ensureDirSync(envArgv.dir.tmp)
|
|
73
|
-
}
|
|
74
|
-
// config merging
|
|
75
|
-
let resp = await readConfig.call(this, `${envArgv.dir.data}/config/bajo.*`, { ignoreError: true })
|
|
76
|
-
resp = omitDeep(pick(resp, configFilePick), configFileOmit)
|
|
77
|
-
const config = defaultsDeep({}, envArgv, resp, defConfig)
|
|
78
|
-
// force init
|
|
79
|
-
config.args = args
|
|
80
|
-
config.env = config.env.toLowerCase()
|
|
81
|
-
if (values(envs).includes(config.env)) config.env = getKeyByValue(envs, config.env)
|
|
82
|
-
if (!keys(envs).includes(config.env)) config.env = 'dev'
|
|
83
|
-
process.env.NODE_ENV = envs[config.env]
|
|
84
|
-
if (!config.log.level) config.log.level = config.env === 'dev' ? 'debug' : 'info'
|
|
85
|
-
if (config.silent) config.log.level = 'silent'
|
|
86
|
-
// sanitize plugins
|
|
87
|
-
config.plugins = without(config.plugins, 'app')
|
|
88
|
-
// if (fs.existsSync(`${config.dir.base}/app/bajo`)) config.plugins.push('app')
|
|
89
|
-
config.plugins.push('app')
|
|
90
|
-
config.plugins = filter(uniq(map(config.plugins, b => trim(b))), b => !isEmpty(b))
|
|
91
|
-
if (config.tool) {
|
|
92
|
-
if (!config.plugins.includes('bajo-cli')) throw error('Sidetool needs to have \'bajo-cli\' package loaded first')
|
|
93
|
-
if (!config.log.tool) config.log.level = 'silent'
|
|
94
|
-
config.exitHandler = false
|
|
95
|
-
}
|
|
96
|
-
this.bajo.config = config
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export default buildConfig
|
package/boot/create-scope.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module boot/createScope
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { isFunction } from 'lodash-es'
|
|
6
|
-
import readJson from './helper/read-json.js'
|
|
7
|
-
import importModule from './helper/import-module.js'
|
|
8
|
-
|
|
9
|
-
async function defHandler (file) {
|
|
10
|
-
let mod = await importModule(file)
|
|
11
|
-
if (isFunction(mod)) mod = await mod.call(this)
|
|
12
|
-
return mod
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const configHandlers = [
|
|
16
|
-
{ ext: '.js', handler: defHandler },
|
|
17
|
-
{ ext: '.mjs', handler: defHandler },
|
|
18
|
-
{ ext: '.json', handler: readJson }
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
const bajo = {
|
|
22
|
-
runAt: new Date(),
|
|
23
|
-
configHandlers
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @instance
|
|
28
|
-
* @async
|
|
29
|
-
* @returns {Object} scope
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
function createScope () {
|
|
33
|
-
return { bajo }
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default createScope
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { isEmpty, find } from 'lodash-es'
|
|
2
|
-
|
|
3
|
-
function breakNsPath (item = '', defaultNs = 'bajo') {
|
|
4
|
-
const { error } = this.bajo.helper
|
|
5
|
-
let [ns, ...path] = item.split(':')
|
|
6
|
-
path = path.join(':')
|
|
7
|
-
if (isEmpty(path)) {
|
|
8
|
-
path = ns
|
|
9
|
-
ns = defaultNs
|
|
10
|
-
}
|
|
11
|
-
if (ns.length === 1) return [ns, path].join(':') // windows fs
|
|
12
|
-
if (!this[ns]) {
|
|
13
|
-
const ref = find(this.bajo.pluginRefs ?? [], { alias: ns })
|
|
14
|
-
if (ref) ns = ref.plugin
|
|
15
|
-
}
|
|
16
|
-
if (!this[ns]) throw error('Unknown plugin \'%s\' or plugin isn\'t loaded yet', ns)
|
|
17
|
-
return [ns, path]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default breakNsPath
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { filter, isArray, each, pullAt, camelCase, has, find, set, get, cloneDeep } from 'lodash-es'
|
|
2
|
-
|
|
3
|
-
async function buildCollections (options = {}) {
|
|
4
|
-
const { getConfig, getPluginName, fatal, runHook, error, join } = this.bajo.helper
|
|
5
|
-
let { plugin, handler, dupChecks = [], container = 'connections', useDefaultName } = options
|
|
6
|
-
useDefaultName = useDefaultName ?? true
|
|
7
|
-
if (!plugin) plugin = getPluginName(4)
|
|
8
|
-
const config = getConfig()
|
|
9
|
-
const cfg = getConfig(plugin, { full: true })
|
|
10
|
-
let data = get(cfg, container)
|
|
11
|
-
if (!data) return []
|
|
12
|
-
if (!isArray(data)) data = [data]
|
|
13
|
-
await runHook(`${plugin}:${camelCase(`before build ${container}`)}`)
|
|
14
|
-
const deleted = []
|
|
15
|
-
for (const index in data) {
|
|
16
|
-
const item = data[index]
|
|
17
|
-
if (useDefaultName) {
|
|
18
|
-
if (!has(item, 'name')) {
|
|
19
|
-
if (find(data, { name: 'default' })) throw error('Collection \'default\' already exists')
|
|
20
|
-
else item.name = 'default'
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
const result = await handler.call(this, { item, index, cfg })
|
|
24
|
-
if (result) data[index] = result
|
|
25
|
-
else if (result === false) deleted.push(index)
|
|
26
|
-
if (config.tool && item.skipOnTool && !deleted.includes(index)) deleted.push(index)
|
|
27
|
-
}
|
|
28
|
-
if (deleted.length > 0) pullAt(data, deleted)
|
|
29
|
-
|
|
30
|
-
// check for duplicity
|
|
31
|
-
each(data, c => {
|
|
32
|
-
each(dupChecks, d => {
|
|
33
|
-
const checker = set({}, d, c[d])
|
|
34
|
-
const match = filter(data, checker)
|
|
35
|
-
if (match.length > 1) fatal('One or more %s shared the same \'%s\'', container, join(dupChecks))
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
await runHook(`${plugin}:${camelCase(`after build ${container}`)}`)
|
|
39
|
-
set(cfg, container, data)
|
|
40
|
-
return cloneDeep(data)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default buildCollections
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import { isString, isFunction, keys, camelCase, kebabCase, snakeCase } from 'lodash-es'
|
|
3
|
-
import pascalCase from './pascal-case.js'
|
|
4
|
-
const converter = { camelCase, kebabCase, snakeCase, pascalCase }
|
|
5
|
-
|
|
6
|
-
function buildName (file, options = {}) {
|
|
7
|
-
if (isString(options)) options = { base: options }
|
|
8
|
-
if (!options.base) options.base = path.dirname(file)
|
|
9
|
-
if (!keys(converter).includes(options.converter)) options.converter = 'camelCase'
|
|
10
|
-
let name = file.replace(options.base, '')
|
|
11
|
-
name = name.slice(0, name.indexOf(path.extname(name)))
|
|
12
|
-
if (isFunction(options.converter)) name = options.converter.call(this, name)
|
|
13
|
-
else name = converter[options.converter](name)
|
|
14
|
-
return name
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export default buildName
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { isString, isFunction } from 'lodash-es'
|
|
2
|
-
import getHelper from './get-helper.js'
|
|
3
|
-
|
|
4
|
-
async function callHelperOrHandler (nameOrFn, ...args) {
|
|
5
|
-
let result
|
|
6
|
-
if (isString(nameOrFn)) {
|
|
7
|
-
const helper = getHelper.call(this, nameOrFn)
|
|
8
|
-
if (isFunction(helper)) result = await helper(...args)
|
|
9
|
-
} else if (isFunction(nameOrFn)) {
|
|
10
|
-
result = await nameOrFn.call(this, ...args)
|
|
11
|
-
}
|
|
12
|
-
return result
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default callHelperOrHandler
|
package/boot/helper/dump.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import util from 'util'
|
|
2
|
-
import { last } from 'lodash-es'
|
|
3
|
-
|
|
4
|
-
const dump = (...args) => {
|
|
5
|
-
const terminate = last(args) === true
|
|
6
|
-
if (terminate) args.pop()
|
|
7
|
-
for (const arg of args) {
|
|
8
|
-
const result = util.inspect(arg, false, null, true)
|
|
9
|
-
console.log(result)
|
|
10
|
-
}
|
|
11
|
-
if (terminate) process.kill(process.pid, 'SIGINT')
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default dump
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { camelCase, isString, omit, trim } from 'lodash-es'
|
|
2
|
-
import fastGlob from 'fast-glob'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import omittedPluginKeys from '../lib/omitted-plugin-keys.js'
|
|
5
|
-
|
|
6
|
-
async function _eachPlugins (handler, { key = 'name', glob, ns, useBajo } = {}) {
|
|
7
|
-
const { getConfig } = this.bajo.helper
|
|
8
|
-
const config = getConfig()
|
|
9
|
-
const result = {}
|
|
10
|
-
const plugins = [...config.plugins]
|
|
11
|
-
if (useBajo) plugins.unshift('bajo')
|
|
12
|
-
for (const pkg of plugins) {
|
|
13
|
-
const plugin = camelCase(pkg)
|
|
14
|
-
let cfg = getConfig(plugin, { full: true })
|
|
15
|
-
const { alias, dependencies } = cfg
|
|
16
|
-
const dir = cfg.dir.pkg
|
|
17
|
-
cfg = omit(cfg, omittedPluginKeys)
|
|
18
|
-
let r
|
|
19
|
-
if (glob) {
|
|
20
|
-
const base = `${dir}/${ns}`
|
|
21
|
-
let opts = isString(glob) ? { pattern: [glob] } : glob
|
|
22
|
-
let pattern = opts.pattern ?? []
|
|
23
|
-
if (isString(pattern)) pattern = [pattern]
|
|
24
|
-
opts = omit(opts, ['pattern'])
|
|
25
|
-
for (const i in pattern) {
|
|
26
|
-
if (!path.isAbsolute(pattern[i])) pattern[i] = `${base}/${pattern[i]}`
|
|
27
|
-
}
|
|
28
|
-
const files = await fastGlob(pattern, opts)
|
|
29
|
-
for (const f of files) {
|
|
30
|
-
if (path.basename(f)[0] === '_') continue
|
|
31
|
-
const resp = await handler.call(this, { plugin, pkg, cfg, alias, file: f, dir: base, dependencies })
|
|
32
|
-
if (resp === false) break
|
|
33
|
-
else if (resp === undefined) continue
|
|
34
|
-
else {
|
|
35
|
-
result[plugin] = result[plugin] ?? {}
|
|
36
|
-
result[plugin][f] = resp
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
r = await handler.call(this, { plugin, pkg, cfg, dir, alias, dependencies })
|
|
41
|
-
if (r === false) break
|
|
42
|
-
else if (r === undefined) continue
|
|
43
|
-
else result[plugin] = r
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return result
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @module helper/eachPlugins
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Callback function that will be executed while walking through all Bajos
|
|
55
|
-
*
|
|
56
|
-
* @callback handlerFn
|
|
57
|
-
* @async
|
|
58
|
-
* @param {Object} argument - Provides information about current Bajo
|
|
59
|
-
* @param {string} argument.name - Bajo's name
|
|
60
|
-
* @param {string} argument.pkgName - Bajo's package name
|
|
61
|
-
* @param {Object} argument.cfg - Bajo's config object
|
|
62
|
-
* @returns {Object|boolean|undefined}
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Walk through all plugins and execute the callback handler
|
|
67
|
-
*
|
|
68
|
-
* @instance
|
|
69
|
-
* @async
|
|
70
|
-
* @param {function} handlerFn - [The callback]{@link module:helper/eachPlugins~handlerFn}
|
|
71
|
-
* @param {Object} [options] - Optional parameter
|
|
72
|
-
* @param {string} [options.key=name] - Key of Bajo's config object that will be used as the key of returned object
|
|
73
|
-
* @returns {Object} Results from callback execution through all Bajos
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* const { eachPlugins } = this.bajo.helper
|
|
77
|
-
* await eachPlugins(async function ({ name }) => {
|
|
78
|
-
* console.log(name)
|
|
79
|
-
* })
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
async function eachPlugins (handler, options = {}) {
|
|
83
|
-
const { getConfig, getPluginName } = this.bajo.helper
|
|
84
|
-
if (typeof options === 'string') options = { glob: options }
|
|
85
|
-
let { key = 'name', glob, ns, extend, extendHandler, useBajo } = options
|
|
86
|
-
if (!extendHandler) extendHandler = handler
|
|
87
|
-
ns = ns ?? getPluginName(4)
|
|
88
|
-
const result = await _eachPlugins.call(this, handler, { key, glob, ns, useBajo })
|
|
89
|
-
if (extend && isString(glob)) {
|
|
90
|
-
let nsExtend = ns
|
|
91
|
-
if (isString(extend)) nsExtend += '/' + trim(extend, '/')
|
|
92
|
-
const cfg = getConfig('app', { full: true })
|
|
93
|
-
const ext = `${cfg.dir.pkg}/${nsExtend}/extend/*`
|
|
94
|
-
const exts = await fastGlob(ext, { onlyDirectories: true })
|
|
95
|
-
for (const e of exts) {
|
|
96
|
-
const plugin = path.basename(e)
|
|
97
|
-
const files = await fastGlob(`${e}/${glob}`)
|
|
98
|
-
for (const file of files) {
|
|
99
|
-
await extendHandler.call(this, { file, plugin, dir: e })
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return result // TODO: merge with extender
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export default eachPlugins
|
package/boot/helper/envs.js
DELETED
package/boot/helper/error.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { last, isPlainObject, each, isArray, get, isEmpty, merge } from 'lodash-es'
|
|
2
|
-
import getPluginName from './get-plugin-name.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* It's a shortcut to create an instance of Error with message and optional parameter
|
|
6
|
-
* in a single line
|
|
7
|
-
*
|
|
8
|
-
* @memberof helper
|
|
9
|
-
* @type Object
|
|
10
|
-
* @instance
|
|
11
|
-
* @param {string} msg - String that will be used as error message
|
|
12
|
-
* @param {options} [options] - Optional parameter
|
|
13
|
-
* @param {string} [options.code] - Error code
|
|
14
|
-
* @returns {error} Instance of Error
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
Error.stackTraceLimit = 15
|
|
18
|
-
|
|
19
|
-
function formatErrorDetails (value, ns) {
|
|
20
|
-
const { print } = this.bajo.helper
|
|
21
|
-
const result = {}
|
|
22
|
-
each(value, (v, i) => {
|
|
23
|
-
if (!v.context) {
|
|
24
|
-
v.error = print.__(v.error, { ns })
|
|
25
|
-
return undefined
|
|
26
|
-
}
|
|
27
|
-
v.context.message = v.message
|
|
28
|
-
if (v.type === 'any.only') v.context.ref = print.__(`field.${get(v, 'context.valids.0.key')}`, { ns })
|
|
29
|
-
const field = get(v, 'context.key')
|
|
30
|
-
const val = get(v, 'context.value')
|
|
31
|
-
value[i] = {
|
|
32
|
-
field,
|
|
33
|
-
error: print.__(`validation.${v.type}`, v.context, { ns }),
|
|
34
|
-
value: val
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
return result
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function error (msg = 'Internal server error', ...args) {
|
|
41
|
-
const { print } = this.bajo.helper
|
|
42
|
-
let payload = last(args)
|
|
43
|
-
let ns
|
|
44
|
-
if (isPlainObject(payload)) {
|
|
45
|
-
payload = args.pop()
|
|
46
|
-
ns = payload.ns
|
|
47
|
-
}
|
|
48
|
-
if (!ns) ns = getPluginName.call(this, 3)
|
|
49
|
-
const orgMsg = msg
|
|
50
|
-
args.push({ ns })
|
|
51
|
-
const message = print.__(msg, ...args)
|
|
52
|
-
let err
|
|
53
|
-
if (isPlainObject(payload) && payload.class) err = payload.class(message)
|
|
54
|
-
else err = Error(message)
|
|
55
|
-
const stacks = err.stack.split('\n')
|
|
56
|
-
stacks.splice(1, 1) // this file
|
|
57
|
-
if (stacks[1].includes('/helper/fatal.js')) stacks.splice(1, 1) // if it goes to fatal.js
|
|
58
|
-
stacks.splice(1, 1) // for buildHelper.js
|
|
59
|
-
err.stack = stacks.join('\n')
|
|
60
|
-
if (isPlainObject(payload)) {
|
|
61
|
-
delete payload.class
|
|
62
|
-
delete payload.ns
|
|
63
|
-
const values = {}
|
|
64
|
-
for (const key in payload) {
|
|
65
|
-
const value = payload[key]
|
|
66
|
-
if (key === 'details' && isArray(value) && orgMsg === 'Validation Error') {
|
|
67
|
-
const result = formatErrorDetails.call(this, value, ns)
|
|
68
|
-
if (result) merge(values, result)
|
|
69
|
-
}
|
|
70
|
-
err[key] = value
|
|
71
|
-
}
|
|
72
|
-
if (!isEmpty(values)) err.values = values
|
|
73
|
-
}
|
|
74
|
-
return err
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export default error
|
package/boot/helper/fatal.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import getPluginName from './get-plugin-name.js'
|
|
2
|
-
|
|
3
|
-
function fatal (...args) {
|
|
4
|
-
const { error } = this.bajo.helper
|
|
5
|
-
const ns = getPluginName.call(this, 3)
|
|
6
|
-
args.push({ ns })
|
|
7
|
-
const [msg, ...params] = args
|
|
8
|
-
const err = error(msg, ...params)
|
|
9
|
-
console.error(err)
|
|
10
|
-
process.kill(process.pid, 'SIGINT')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default fatal
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { isEmpty, isPlainObject, cloneDeep, omit, find } from 'lodash-es'
|
|
2
|
-
import omittedPluginKeys from '../lib/omitted-plugin-keys.js'
|
|
3
|
-
|
|
4
|
-
function getConfig (name, options = {}) {
|
|
5
|
-
const { full, clone } = options
|
|
6
|
-
if (name === 'bajo' || isEmpty(name)) return this.bajo.config
|
|
7
|
-
if (this[name] && isPlainObject(this[name].config) && this[name].config.name === name) {
|
|
8
|
-
const cfg = clone ? cloneDeep(this[name].config) : this[name].config
|
|
9
|
-
return full ? cfg : omit(cfg, omittedPluginKeys)
|
|
10
|
-
}
|
|
11
|
-
const ref = find(this.bajo.pluginRefs ?? [], { alias: name })
|
|
12
|
-
if (ref) {
|
|
13
|
-
const cfg = clone ? cloneDeep(this[ref.plugin].config) : this[ref.plugin].config
|
|
14
|
-
return full ? cfg : omit(cfg, omittedPluginKeys)
|
|
15
|
-
}
|
|
16
|
-
return {}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default getConfig
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { get } from 'lodash-es'
|
|
2
|
-
import error from './error.js'
|
|
3
|
-
import breakNsPath from './break-ns-path.js'
|
|
4
|
-
|
|
5
|
-
function getHelper (name = '', thrown = true) {
|
|
6
|
-
const [plugin, method] = breakNsPath.call(this, name)
|
|
7
|
-
const helper = get(this, `${plugin}.helper.${method}`)
|
|
8
|
-
if (helper) return helper
|
|
9
|
-
if (thrown) throw error.call(this, 'Can\'t find helper named \'%s\'', name)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default getHelper
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
|
|
3
|
-
async function getItemByName (name) {
|
|
4
|
-
const { resolvePath, getConfig, readConfig, error } = this.bajo.helper
|
|
5
|
-
const config = getConfig()
|
|
6
|
-
const [type, ...paths] = name.split(':')
|
|
7
|
-
let result
|
|
8
|
-
switch (type) {
|
|
9
|
-
case 'config': {
|
|
10
|
-
let file = paths.join(':')
|
|
11
|
-
if (!path.isAbsolute(file)) file = resolvePath(`${config.dir.data}/config/${file}`)
|
|
12
|
-
result = await readConfig(file)
|
|
13
|
-
break
|
|
14
|
-
}
|
|
15
|
-
case 'helper': {
|
|
16
|
-
const [ns, fn] = paths.join(':').split('.')
|
|
17
|
-
if (!(ns && fn)) throw error('Unknown helper \'%s.%s\'', ns, fn, { code: 'BAJO_UNKNOWN_HELPER' })
|
|
18
|
-
result = this[ns].helper[fn]
|
|
19
|
-
break
|
|
20
|
-
}
|
|
21
|
-
default: throw error('Unsupported type \'%s\'', type, { code: 'BAJO_UNSUPPORTED_TYPE' })
|
|
22
|
-
}
|
|
23
|
-
return result
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default getItemByName
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { get } from 'lodash-es'
|
|
2
|
-
import breakNsPath from './break-ns-path.js'
|
|
3
|
-
|
|
4
|
-
function getPluginFile (file) {
|
|
5
|
-
if (!get(this, 'bajo.helper')) return file
|
|
6
|
-
if (file.includes(':')) {
|
|
7
|
-
const [plugin, path] = breakNsPath.call(this, file)
|
|
8
|
-
if (plugin !== 'file' && this && this[plugin] && plugin.length > 1) {
|
|
9
|
-
const dir = get(this[plugin], 'config.dir.pkg')
|
|
10
|
-
file = `${dir}${path}`
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return file
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default getPluginFile
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { isString, isNumber, each, camelCase } from 'lodash-es'
|
|
2
|
-
import callsites from 'callsites'
|
|
3
|
-
import error from './error.js'
|
|
4
|
-
import resolvePath from './resolve-path.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Get the right Bajo name inside your app or plugins/Bajos. If parameter ```fname```
|
|
8
|
-
* is not provided, it will be set to the actual file this function is called.
|
|
9
|
-
*
|
|
10
|
-
* @memberof helper
|
|
11
|
-
* @instance
|
|
12
|
-
* @param {string} [fname] - File name (relative/absolute)
|
|
13
|
-
* @throws Will throw if Bajo name coldn't be resolved
|
|
14
|
-
* @returns {string} Bajo name
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
function getPluginName (fname) {
|
|
18
|
-
const config = this.bajo.config
|
|
19
|
-
let file
|
|
20
|
-
if (isString(fname)) file = fname
|
|
21
|
-
else file = callsites()[isNumber(fname) ? fname : 2].getFileName()
|
|
22
|
-
if (!file) throw error('Can\'t resolve bajo named \'%s\', sorry!', fname, { code: 'BAJO_UNABLE_TO_RESOLVE_BAJO_NAME' })
|
|
23
|
-
file = resolvePath(file)
|
|
24
|
-
let match
|
|
25
|
-
each(config.plugins, b => {
|
|
26
|
-
if (file.includes('/bajo/boot/')) {
|
|
27
|
-
match = 'bajo'
|
|
28
|
-
return false
|
|
29
|
-
}
|
|
30
|
-
if (file.includes('/' + b + '/')) {
|
|
31
|
-
match = b
|
|
32
|
-
return false
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
if (match) return camelCase(match)
|
|
36
|
-
return 'bajo'
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default getPluginName
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { find } from 'lodash-es'
|
|
2
|
-
|
|
3
|
-
function getPlugin (name) {
|
|
4
|
-
const { error } = this.bajo.helper
|
|
5
|
-
if (!this[name]) {
|
|
6
|
-
// alias?
|
|
7
|
-
const ref = find(this.bajo.pluginRefs ?? [], { alias: name })
|
|
8
|
-
if (!ref) throw error('\'%s\' is not loaded', name)
|
|
9
|
-
name = ref.plugin
|
|
10
|
-
}
|
|
11
|
-
return this[name]
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default getPlugin
|
package/boot/helper/join.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { isPlainObject } from 'lodash-es'
|
|
2
|
-
import isSet from './is-set.js'
|
|
3
|
-
|
|
4
|
-
const join = (array, sep) => {
|
|
5
|
-
if (isSet(sep) && !isPlainObject(sep)) return array.join(sep)
|
|
6
|
-
const { separator = ', ', joiner = 'and' } = sep ?? {}
|
|
7
|
-
const last = (array.pop() ?? '').trim()
|
|
8
|
-
return array.map(a => (a + '').trim()).join(separator) + ` ${joiner} ${last}`
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default join
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Supported logger levels including its level priority
|
|
3
|
-
*
|
|
4
|
-
* @memberof module:helper
|
|
5
|
-
* @type Object
|
|
6
|
-
* @instance
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const logLevels = {
|
|
10
|
-
trace: 10,
|
|
11
|
-
debug: 20,
|
|
12
|
-
info: 30,
|
|
13
|
-
warn: 40,
|
|
14
|
-
error: 50,
|
|
15
|
-
fatal: 60,
|
|
16
|
-
silent: 99
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default logLevels
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import resolvePath from './resolve-path.js'
|
|
3
|
-
import getPluginFile from './get-plugin-file.js'
|
|
4
|
-
import readJson from './read-json.js'
|
|
5
|
-
import parseObject from './parse-object.js'
|
|
6
|
-
import { find, map, isEmpty } from 'lodash-es'
|
|
7
|
-
import error from './error.js'
|
|
8
|
-
import fg from 'fast-glob'
|
|
9
|
-
|
|
10
|
-
async function readConfig (file, { pattern, globOptions = {}, ignoreError, defValue = {} } = {}) {
|
|
11
|
-
file = resolvePath(getPluginFile.call(this, file))
|
|
12
|
-
let ext = path.extname(file)
|
|
13
|
-
const fname = path.dirname(file) + '/' + path.basename(file, ext)
|
|
14
|
-
ext = ext.toLowerCase()
|
|
15
|
-
if (['.mjs', '.js'].includes(ext)) {
|
|
16
|
-
const { handler } = find(this.bajo.configHandlers, { ext })
|
|
17
|
-
return parseObject(await handler.call(this, file))
|
|
18
|
-
}
|
|
19
|
-
if (ext === '.json') return await readJson(file)
|
|
20
|
-
if (!['', '.*'].includes(ext)) {
|
|
21
|
-
const item = find(this.bajo.configHandlers, { ext })
|
|
22
|
-
if (!item) {
|
|
23
|
-
if (!ignoreError) throw error.call(this, 'Can\'t parse \'%s\'', file, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
24
|
-
return parseObject(defValue)
|
|
25
|
-
}
|
|
26
|
-
return parseObject(item.handler.call(this, file))
|
|
27
|
-
}
|
|
28
|
-
const item = pattern ?? `${fname}.{${map(map(this.bajo.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
|
|
29
|
-
const files = await fg(item, globOptions)
|
|
30
|
-
if (files.length === 0) {
|
|
31
|
-
if (!ignoreError) throw error.call(this, 'No config file found', { code: 'BAJO_CONFIG_FILE_NOT_FOUND' })
|
|
32
|
-
return parseObject(defValue)
|
|
33
|
-
}
|
|
34
|
-
let config = defValue
|
|
35
|
-
for (const f of files) {
|
|
36
|
-
const ext = path.extname(f).toLowerCase()
|
|
37
|
-
const item = find(this.bajo.configHandlers, { ext })
|
|
38
|
-
if (!item) {
|
|
39
|
-
if (!ignoreError) throw error.call(this, 'Can\'t parse \'%s\'', f, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
40
|
-
continue
|
|
41
|
-
}
|
|
42
|
-
config = await item.handler.call(this, f)
|
|
43
|
-
if (!isEmpty(config)) break
|
|
44
|
-
}
|
|
45
|
-
return parseObject(config)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default readConfig
|