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
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { filter, isArray, pullAt, camelCase, has, find, set, get, isFunction } from 'lodash-es'
|
|
2
|
+
|
|
3
|
+
async function buildCollections (options = {}) {
|
|
4
|
+
const { runHook, join } = this.app.bajo
|
|
5
|
+
let { ns, handler, dupChecks = [], container, useDefaultName } = options
|
|
6
|
+
useDefaultName = useDefaultName ?? true
|
|
7
|
+
if (!ns) ns = this.name
|
|
8
|
+
const cfg = this.app[ns].getConfig()
|
|
9
|
+
let items = get(cfg, container, [])
|
|
10
|
+
if (!isArray(items)) items = [items]
|
|
11
|
+
this.app[ns].log.trace('Collecting %s', this.app[ns].print.write(container))
|
|
12
|
+
await runHook(`${ns}:${camelCase('beforeBuildCollection')}`, container)
|
|
13
|
+
const deleted = []
|
|
14
|
+
for (const index in items) {
|
|
15
|
+
const item = items[index]
|
|
16
|
+
if (useDefaultName) {
|
|
17
|
+
if (!has(item, 'name')) {
|
|
18
|
+
if (find(items, { name: 'default' })) throw this.app[ns].error('Collection \'default\' already exists')
|
|
19
|
+
else item.name = 'default'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
this.app[ns].log.trace('- %s', item.name)
|
|
23
|
+
const result = await handler.call(this.app[ns], { item, index, cfg })
|
|
24
|
+
if (result) items[index] = result
|
|
25
|
+
else if (result === false) deleted.push(index)
|
|
26
|
+
if (this.app.bajo.applet && item.skipOnTool && !deleted.includes(index)) deleted.push(index)
|
|
27
|
+
}
|
|
28
|
+
if (deleted.length > 0) pullAt(items, deleted)
|
|
29
|
+
|
|
30
|
+
// check for duplicity
|
|
31
|
+
for (const c of items) {
|
|
32
|
+
for (const d of dupChecks) {
|
|
33
|
+
if (isFunction(d)) await d.call(this.app[ns], c, items)
|
|
34
|
+
else {
|
|
35
|
+
const checker = set({}, d, c[d])
|
|
36
|
+
const match = filter(items, checker)
|
|
37
|
+
if (match.length > 1) this.app[ns].fatal('One or more %s shared the same \'%s\'', container, join(dupChecks.filter(i => !isFunction(i))))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
await runHook(`${ns}:${camelCase('afterBuildCollection')}`, container)
|
|
42
|
+
this.app[ns].log.debug('%s collected: %d', this.app[ns].print.write(container), items.length)
|
|
43
|
+
return items
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default buildCollections
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isString, isFunction, isPlainObject, find } from 'lodash-es'
|
|
2
|
+
import BajoPlugin from '../../bajo-plugin.js'
|
|
3
|
+
|
|
4
|
+
async function callHandler (item, ...args) {
|
|
5
|
+
let result
|
|
6
|
+
let scope = this
|
|
7
|
+
if (item instanceof BajoPlugin) {
|
|
8
|
+
scope = item
|
|
9
|
+
item = args.shift()
|
|
10
|
+
}
|
|
11
|
+
const bajo = scope.app.bajo
|
|
12
|
+
if (isString(item)) {
|
|
13
|
+
if (item.startsWith('applet:') && bajo.applets.length > 0) {
|
|
14
|
+
const [, ns, path] = item.split(':')
|
|
15
|
+
const applet = find(bajo.applets, a => (a.ns === ns || a.alias === ns))
|
|
16
|
+
if (applet) result = await bajo.runApplet(applet, path, ...args)
|
|
17
|
+
} else {
|
|
18
|
+
const method = bajo.getMethod(item)
|
|
19
|
+
if (method) result = await method(...args)
|
|
20
|
+
}
|
|
21
|
+
} else if (isFunction(item)) {
|
|
22
|
+
result = await item.call(scope, ...args)
|
|
23
|
+
} else if (isPlainObject(item) && item.handler) {
|
|
24
|
+
result = await item.handler.call(scope, ...args)
|
|
25
|
+
}
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default callHandler
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mergeWith, isArray } from 'lodash-es'
|
|
2
|
-
//
|
|
2
|
+
// based on https://github.com/nodeutils/defaults-deep/blob/master/lib/index.js
|
|
3
3
|
|
|
4
4
|
const defaultsDeep = (...args) => {
|
|
5
5
|
const output = {}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { camelCase, isString, omit, cloneDeep } from 'lodash-es'
|
|
2
|
+
import fastGlob from 'fast-glob'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
|
|
5
|
+
async function eachPlugins (handler, options = {}) {
|
|
6
|
+
if (typeof options === 'string') options = { glob: options }
|
|
7
|
+
const result = {}
|
|
8
|
+
const pluginPkgs = cloneDeep(this.app.bajo.pluginPkgs) ?? []
|
|
9
|
+
const { glob, useBajo, prefix = '', noUnderscore = true, returnItems } = options
|
|
10
|
+
if (useBajo) pluginPkgs.unshift('bajo')
|
|
11
|
+
for (const pkgName of pluginPkgs) {
|
|
12
|
+
const ns = camelCase(pkgName)
|
|
13
|
+
const config = this.app[ns].config
|
|
14
|
+
const alias = this.app[ns].alias
|
|
15
|
+
let r
|
|
16
|
+
if (glob) {
|
|
17
|
+
const base = prefix === '' ? this.app[ns].dir.pkg : `${this.app[ns].dir.pkg}/${prefix}`
|
|
18
|
+
let opts = isString(glob) ? { pattern: [glob] } : glob
|
|
19
|
+
let pattern = opts.pattern ?? []
|
|
20
|
+
if (isString(pattern)) pattern = [pattern]
|
|
21
|
+
opts = omit(opts, ['pattern'])
|
|
22
|
+
for (const i in pattern) {
|
|
23
|
+
if (!path.isAbsolute(pattern[i])) pattern[i] = `${base}/${pattern[i]}`
|
|
24
|
+
}
|
|
25
|
+
const files = await fastGlob(pattern, opts)
|
|
26
|
+
for (const f of files) {
|
|
27
|
+
if (path.basename(f)[0] === '_' && noUnderscore) continue
|
|
28
|
+
const resp = await handler.call(this.app[ns], { ns, pkgName, config, alias, file: f, dir: base })
|
|
29
|
+
if (resp === false) break
|
|
30
|
+
else if (resp === undefined) continue
|
|
31
|
+
else {
|
|
32
|
+
result[ns] = result[ns] ?? {}
|
|
33
|
+
result[ns][f] = resp
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
r = await handler.call(this.app[ns], { ns, pkgName, config, dir: this.app[ns].dir.pkg, alias })
|
|
38
|
+
if (r === false) break
|
|
39
|
+
else if (r === undefined) continue
|
|
40
|
+
else result[ns] = r
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (returnItems) {
|
|
44
|
+
const data = []
|
|
45
|
+
for (const r in result) {
|
|
46
|
+
for (const f in result[r]) {
|
|
47
|
+
data.push(result[r][f])
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return data
|
|
51
|
+
}
|
|
52
|
+
return result
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default eachPlugins
|
|
@@ -2,9 +2,13 @@ import { customAlphabet } from 'nanoid'
|
|
|
2
2
|
|
|
3
3
|
const generateId = (options = {}) => {
|
|
4
4
|
let type
|
|
5
|
+
if (options === true) options = 'alpha'
|
|
5
6
|
if (options === 'int') {
|
|
6
7
|
type = options
|
|
7
8
|
options = { pattern: '0123456789', length: 15 }
|
|
9
|
+
} else if (options === 'alpha') {
|
|
10
|
+
type = options
|
|
11
|
+
options = { pattern: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', length: 15 }
|
|
8
12
|
}
|
|
9
13
|
let { pattern, length = 13, returnInstance } = options
|
|
10
14
|
pattern = pattern ?? 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import getGlobalModulePath from '../../../lib/get-global-module-path.js'
|
|
2
2
|
import resolvePath from './resolve-path.js'
|
|
3
|
-
import error from './error.js'
|
|
4
3
|
import { dropRight } from 'lodash-es'
|
|
5
4
|
import fs from 'fs-extra'
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
function getGlobalModuleDir (pkgName, silent = true) {
|
|
8
7
|
let nodeModulesDir = process.env.BAJO_GLOBAL_MODULE_DIR
|
|
9
8
|
if (!nodeModulesDir) {
|
|
10
|
-
const npmPath =
|
|
9
|
+
const npmPath = getGlobalModulePath('npm')
|
|
11
10
|
if (!npmPath) {
|
|
12
11
|
if (silent) return
|
|
13
|
-
throw error('Can\'t locate npm global module directory', { code: 'BAJO_CANT_LOCATE_NPM_GLOBAL_DIR' })
|
|
12
|
+
throw this.error('Can\'t locate npm global module directory', { code: 'BAJO_CANT_LOCATE_NPM_GLOBAL_DIR' })
|
|
14
13
|
}
|
|
15
14
|
nodeModulesDir = dropRight(resolvePath(npmPath).split('/'), 1).join('/')
|
|
16
15
|
process.env.BAJO_GLOBAL_MODULE_DIR = nodeModulesDir
|
|
@@ -19,7 +18,7 @@ const getGlobalModuleDir = (pkgName, silent = true) => {
|
|
|
19
18
|
const dir = `${nodeModulesDir}/${pkgName}`
|
|
20
19
|
if (!fs.existsSync(dir)) {
|
|
21
20
|
if (silent) return
|
|
22
|
-
throw error('Can\'t locate \'%s\' global module directory', pkgName, { code: 'BAJO_CANT_LOCATE_MODULE_GLOBAL_DIR' })
|
|
21
|
+
throw this.error('Can\'t locate \'%s\' global module directory', pkgName, { code: 'BAJO_CANT_LOCATE_MODULE_GLOBAL_DIR' })
|
|
23
22
|
}
|
|
24
23
|
return dir
|
|
25
24
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { get, isFunction } from 'lodash-es'
|
|
2
|
+
|
|
3
|
+
function getMethod (name = '', thrown = true) {
|
|
4
|
+
const { ns, path } = this.breakNsPath(name)
|
|
5
|
+
const method = get(this.app, `${ns}.${path}`)
|
|
6
|
+
if (method && isFunction(method)) return method
|
|
7
|
+
if (thrown) throw this.error('Can\'t find method named \'%s\'', name)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default getMethod
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs-extra'
|
|
3
|
-
import { get } from 'lodash-es'
|
|
4
3
|
import getGlobalModuleDir from './get-global-module-dir.js'
|
|
5
4
|
import resolvePath from './resolve-path.js'
|
|
6
5
|
import { createRequire } from 'module'
|
|
@@ -19,9 +18,9 @@ function findDeep (item, paths) {
|
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
function getModuleDir (pkgName, base) {
|
|
22
|
-
if (pkgName === '
|
|
23
|
-
if (base === '
|
|
24
|
-
else if (this && this[base]) base =
|
|
21
|
+
if (pkgName === 'main') return resolvePath(process.env.BAJOCWD)
|
|
22
|
+
if (base === 'main') base = process.env.BAJOCWD
|
|
23
|
+
else if (this && this.app && this.app[base]) base = this.app[base].pkgName
|
|
25
24
|
const pkgPath = pkgName + '/package.json'
|
|
26
25
|
const paths = require.resolve.paths(pkgPath)
|
|
27
26
|
const gdir = getGlobalModuleDir()
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import fs from 'fs-extra'
|
|
2
2
|
|
|
3
3
|
function getPluginDataDir (name, ensureDir = true) {
|
|
4
|
-
const { getPlugin
|
|
4
|
+
const { getPlugin } = this.app.bajo
|
|
5
5
|
const plugin = getPlugin(name)
|
|
6
|
-
const
|
|
7
|
-
const dir = `${cfg.dir.data}/plugins/${plugin.config.name}`
|
|
6
|
+
const dir = `${this.app.bajo.dir.data}/plugins/${plugin.name}`
|
|
8
7
|
if (ensureDir) fs.ensureDirSync(dir)
|
|
9
8
|
return dir
|
|
10
9
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import breakNsPath from './break-ns-path.js'
|
|
2
|
+
import currentLoc from '../../../lib/current-loc.js'
|
|
3
|
+
import { trim } from 'lodash-es'
|
|
4
|
+
|
|
5
|
+
function getPluginFile (file) {
|
|
6
|
+
if (file[0] === '.') file = `${currentLoc(import.meta).dir}/${trim(file.slice(1), '/')}`
|
|
7
|
+
if (!this) return file
|
|
8
|
+
if (file.includes(':')) {
|
|
9
|
+
if (file.slice(1, 2) === ':') return file // windows fs
|
|
10
|
+
const { ns, path } = breakNsPath.call(this, file)
|
|
11
|
+
if (ns !== 'file' && this && this.app && this.app[ns] && ns.length > 1) {
|
|
12
|
+
file = `${this.app[ns].dir.pkg}${path}`
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return file
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default getPluginFile
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import BajoPlugin from '../../bajo-plugin.js'
|
|
2
|
+
|
|
3
|
+
function getPlugin (name, silent) {
|
|
4
|
+
if (!this.app[name]) {
|
|
5
|
+
// alias?
|
|
6
|
+
let plugin
|
|
7
|
+
for (const key in this.app) {
|
|
8
|
+
const item = this.app[key]
|
|
9
|
+
if (item instanceof BajoPlugin && (item.alias === name || item.pkgName === name)) {
|
|
10
|
+
plugin = item
|
|
11
|
+
break
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if (!plugin) {
|
|
15
|
+
if (silent) return false
|
|
16
|
+
throw this.error('Plugin with alias \'%s\' is not loaded', name)
|
|
17
|
+
}
|
|
18
|
+
name = plugin.name
|
|
19
|
+
}
|
|
20
|
+
return this.app[name]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default getPlugin
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import resolvePath from './resolve-path.js'
|
|
2
2
|
import getPluginFile from './get-plugin-file.js'
|
|
3
3
|
import { isFunction, isPlainObject } from 'lodash-es'
|
|
4
|
-
import error from './error.js'
|
|
5
4
|
import fs from 'fs-extra'
|
|
6
5
|
|
|
7
|
-
async function load (file, asDefaultImport = true, noCache =
|
|
6
|
+
async function load (file, asDefaultImport = true, noCache = false) {
|
|
8
7
|
file = resolvePath(file, true)
|
|
9
8
|
if (noCache) file += `?_=${Date.now()}`
|
|
10
9
|
const imported = await import(file)
|
|
@@ -13,18 +12,13 @@ async function load (file, asDefaultImport = true, noCache = true) {
|
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
async function importModule (file, { asDefaultImport, asHandler, noCache } = {}) {
|
|
16
|
-
|
|
15
|
+
const me = this
|
|
16
|
+
file = getPluginFile.call(me, file)
|
|
17
17
|
if (!fs.existsSync(file)) return
|
|
18
18
|
let mod = await load(file, asDefaultImport, noCache)
|
|
19
19
|
if (!asHandler) return mod
|
|
20
20
|
if (isFunction(mod)) mod = { level: 999, handler: mod }
|
|
21
|
-
if (!isPlainObject(mod)) throw error.call(
|
|
22
|
-
if (mod.forceAsync && mod.handler.constructor.name !== 'AsyncFunction') {
|
|
23
|
-
const oldHandler = mod.handler
|
|
24
|
-
mod.handler = async function (...args) {
|
|
25
|
-
oldHandler.call(this, ...args)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
21
|
+
if (!isPlainObject(mod)) throw this.error.call(me.app, 'File \'%s\' is NOT a handler module', file)
|
|
28
22
|
return mod
|
|
29
23
|
}
|
|
30
24
|
|
|
@@ -10,13 +10,18 @@ import fs from 'fs-extra'
|
|
|
10
10
|
|
|
11
11
|
async function importPkg (...pkgs) {
|
|
12
12
|
const result = {}
|
|
13
|
-
|
|
13
|
+
const notFound = []
|
|
14
|
+
let opts = { returnDefault: true, thrownNotFound: false }
|
|
14
15
|
if (isPlainObject(last(pkgs))) {
|
|
15
16
|
opts = defaultsDeep(pkgs.pop(), opts)
|
|
16
17
|
}
|
|
17
18
|
for (const pkg of pkgs) {
|
|
18
|
-
const
|
|
19
|
-
const dir = getModuleDir.call(this, name,
|
|
19
|
+
const { ns, path: name } = breakNsPath.call(this, pkg)
|
|
20
|
+
const dir = getModuleDir.call(this, name, ns)
|
|
21
|
+
if (!dir) {
|
|
22
|
+
notFound.push(pkg)
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
20
25
|
const p = readJson(`${dir}/package.json`, opts.thrownNotFound)
|
|
21
26
|
const mainFileOrg = dir + '/' + (p.main ?? get(p, 'exports.default', 'index.js'))
|
|
22
27
|
let mainFile = resolvePath(mainFileOrg, os.platform() === 'win32')
|
|
@@ -32,6 +37,7 @@ async function importPkg (...pkgs) {
|
|
|
32
37
|
}
|
|
33
38
|
result[name] = mod
|
|
34
39
|
}
|
|
40
|
+
if (notFound.length > 0) throw this.error('Can\'t find %s', this.join(notFound))
|
|
35
41
|
if (pkgs.length === 1) return result[keys(result)[0]]
|
|
36
42
|
if (opts.asObject) return result
|
|
37
43
|
return values(result)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isString } from 'lodash-es'
|
|
2
|
+
|
|
3
|
+
function includes (matcher = [], array = []) {
|
|
4
|
+
if (isString(matcher)) matcher = [matcher]
|
|
5
|
+
let found = false
|
|
6
|
+
for (const m of matcher) {
|
|
7
|
+
found = array.includes(m)
|
|
8
|
+
if (found) break
|
|
9
|
+
}
|
|
10
|
+
return found
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default includes
|
|
@@ -3,7 +3,7 @@ import { keys, indexOf } from 'lodash-es'
|
|
|
3
3
|
|
|
4
4
|
function isLogInRange (level) {
|
|
5
5
|
const levels = keys(logLevels)
|
|
6
|
-
const logLevel = indexOf(levels, this.bajo.config.log.level)
|
|
6
|
+
const logLevel = indexOf(levels, this.app.bajo.config.log.level)
|
|
7
7
|
return indexOf(levels, level) >= logLevel
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -4,9 +4,9 @@ import resolvePath from './resolve-path.js'
|
|
|
4
4
|
const isValidApp = (dir) => {
|
|
5
5
|
if (!dir) dir = process.env.BAJOCWD
|
|
6
6
|
dir = resolvePath(dir)
|
|
7
|
-
const
|
|
7
|
+
const hasMainDir = fs.existsSync(`${dir}/main/bajo`)
|
|
8
8
|
const hasPackageJson = fs.existsSync(`${dir}/package.json`)
|
|
9
|
-
return
|
|
9
|
+
return hasMainDir && hasPackageJson
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export default isValidApp
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isPlainObject } from 'lodash-es'
|
|
2
|
+
import isSet from './is-set.js'
|
|
3
|
+
|
|
4
|
+
function join (array, sep) {
|
|
5
|
+
const isI18n = this && this.app && this.app.bajoI18N
|
|
6
|
+
if (array.length === 0) return isI18n ? this.app.bajoI18N.t('none') : 'none'
|
|
7
|
+
if (array.length === 1) return array[0]
|
|
8
|
+
if (isSet(sep) && !isPlainObject(sep)) return array.join(sep)
|
|
9
|
+
let { separator = ', ', joiner = 'and' } = sep ?? {}
|
|
10
|
+
if (isI18n && this.app.bajoI18N.t) joiner = this.app.bajoI18N.t(joiner)
|
|
11
|
+
const last = (array.pop() ?? '').trim()
|
|
12
|
+
return array.map(a => (a + '').trim()).join(separator) + ` ${joiner} ${last}`
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default join
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { isPlainObject, isArray, isNumber, set, cloneDeep } from 'lodash-es'
|
|
1
|
+
import { isPlainObject, isArray, isNumber, set, cloneDeep, isString, omit } from 'lodash-es'
|
|
2
2
|
import dotenvParseVariables from 'dotenv-parse-variables'
|
|
3
3
|
import ms from 'ms'
|
|
4
|
-
import dayjs from '
|
|
4
|
+
import dayjs from '../../../lib/dayjs.js'
|
|
5
5
|
import isSet from './is-set.js'
|
|
6
|
+
import translate from '../../../lib/translate.js'
|
|
6
7
|
|
|
7
8
|
const statics = ['*']
|
|
8
9
|
|
|
@@ -12,13 +13,15 @@ function parseDur (val) {
|
|
|
12
13
|
|
|
13
14
|
function parseDt (val) {
|
|
14
15
|
const dt = dayjs(val)
|
|
15
|
-
if (!dt.isValid()) throw
|
|
16
|
+
if (!dt.isValid()) throw this.error('Unparsed date/time \'%s\'', val)
|
|
16
17
|
return dt.toDate()
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
function parseObject (input, silent = true, parseValue = false) {
|
|
20
|
-
|
|
20
|
+
function parseObject (input, { silent = true, parseValue = false, i18n, ns } = {}) {
|
|
21
|
+
let obj = cloneDeep(input)
|
|
21
22
|
const keys = Object.keys(obj)
|
|
23
|
+
const me = this
|
|
24
|
+
const mutated = []
|
|
22
25
|
keys.forEach(k => {
|
|
23
26
|
const v = obj[k]
|
|
24
27
|
if (isPlainObject(v)) obj[k] = parseObject(v)
|
|
@@ -32,18 +35,31 @@ function parseObject (input, silent = true, parseValue = false) {
|
|
|
32
35
|
} else if (isSet(v)) {
|
|
33
36
|
try {
|
|
34
37
|
if (statics.includes(v)) obj[k] = v
|
|
35
|
-
else if (
|
|
38
|
+
else if (k.startsWith('t:') && isString(v)) {
|
|
39
|
+
const newK = k.slice(2)
|
|
40
|
+
if (i18n) {
|
|
41
|
+
const scope = ns ? me.app[ns] : me
|
|
42
|
+
let [text, ...args] = v.split('|')
|
|
43
|
+
args = args.map(a => {
|
|
44
|
+
if (a.slice(0, 2) === 't:') a = translate.call(scope, i18n, a.slice(2))
|
|
45
|
+
return a
|
|
46
|
+
})
|
|
47
|
+
obj[newK] = translate.call(scope, i18n, text, ...args)
|
|
48
|
+
} else obj[newK] = v
|
|
49
|
+
mutated.push(k)
|
|
50
|
+
} else if (parseValue) {
|
|
36
51
|
obj[k] = dotenvParseVariables(set({}, 'item', v), { assignToProcessEnv: false }).item
|
|
37
52
|
if (isArray(obj[k])) obj[k] = obj[k].map(item => typeof item === 'string' ? item.trim() : item)
|
|
38
53
|
}
|
|
39
|
-
if (k.slice(-3) === 'Dur') obj[k] = parseDur(v)
|
|
40
|
-
if (k.slice(-2) === 'Dt') obj[k] = parseDt(v)
|
|
54
|
+
if (k.slice(-3) === 'Dur') obj[k] = parseDur.call(me, v)
|
|
55
|
+
if (k.slice(-2) === 'Dt') obj[k] = parseDt.call(me, v)
|
|
41
56
|
} catch (err) {
|
|
42
57
|
obj[k] = undefined
|
|
43
58
|
if (!silent) throw err
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
61
|
})
|
|
62
|
+
if (mutated.length > 0) obj = omit(obj, mutated)
|
|
47
63
|
return obj
|
|
48
64
|
}
|
|
49
65
|
|
|
@@ -0,0 +1,48 @@
|
|
|
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 fg from 'fast-glob'
|
|
8
|
+
|
|
9
|
+
async function readConfig (file, { ns, pattern, globOptions = {}, ignoreError, defValue = {}, opts = {} } = {}) {
|
|
10
|
+
if (!ns) ns = this.name
|
|
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 { readHandler } = find(this.app.bajo.configHandlers, { ext })
|
|
17
|
+
return parseObject(await readHandler.call(this.app[ns], file, opts))
|
|
18
|
+
}
|
|
19
|
+
if (ext === '.json') return await readJson(file)
|
|
20
|
+
if (!['', '.*'].includes(ext)) {
|
|
21
|
+
const item = find(this.app.bajo.configHandlers, { ext })
|
|
22
|
+
if (!item) {
|
|
23
|
+
if (!ignoreError) throw this.error('Can\'t parse \'%s\'', file, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
24
|
+
return parseObject(defValue)
|
|
25
|
+
}
|
|
26
|
+
return parseObject(await item.readHandler.call(this.app[ns], file, opts))
|
|
27
|
+
}
|
|
28
|
+
const item = pattern ?? `${fname}.{${map(map(this.app.bajo.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
|
|
29
|
+
const files = await fg(item, globOptions)
|
|
30
|
+
if (files.length === 0) {
|
|
31
|
+
if (!ignoreError) throw this.error('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.app.bajo.configHandlers, { ext })
|
|
38
|
+
if (!item) {
|
|
39
|
+
if (!ignoreError) throw this.error('Can\'t parse \'%s\'', f, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
config = await item.readHandler.call(this.app[ns], f, opts)
|
|
43
|
+
if (!isEmpty(config)) break
|
|
44
|
+
}
|
|
45
|
+
return parseObject(config)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default readConfig
|
|
@@ -2,8 +2,8 @@ import fs from 'fs-extra'
|
|
|
2
2
|
import { isEmpty } from 'lodash-es'
|
|
3
3
|
import parseObject from './parse-object.js'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
if (!fs.existsSync(file) && thrownNotFound) throw
|
|
5
|
+
function readJson (file, thrownNotFound) {
|
|
6
|
+
if (!fs.existsSync(file) && thrownNotFound) throw this.error('File \'%s\' not found', file)
|
|
7
7
|
let resp = fs.readFileSync(file, 'utf8')
|
|
8
8
|
if (isEmpty(resp)) resp = '{}'
|
|
9
9
|
return parseObject(JSON.parse(resp))
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { filter, isEmpty, orderBy, pullAt } from 'lodash-es'
|
|
2
|
+
|
|
3
|
+
async function runHook (hookName, ...args) {
|
|
4
|
+
const [ns, path] = (hookName ?? '').split(':')
|
|
5
|
+
let fns = filter(this.app.bajo.hooks, { ns, path })
|
|
6
|
+
if (isEmpty(fns)) return
|
|
7
|
+
fns = orderBy(fns, ['level'])
|
|
8
|
+
const results = []
|
|
9
|
+
const removed = []
|
|
10
|
+
for (const i in fns) {
|
|
11
|
+
const fn = fns[i]
|
|
12
|
+
const scope = this.app[fn.src]
|
|
13
|
+
const res = await fn.handler.call(scope, ...args)
|
|
14
|
+
results.push({
|
|
15
|
+
hook: hookName,
|
|
16
|
+
resp: res
|
|
17
|
+
})
|
|
18
|
+
if (path.startsWith('once')) removed.push(i)
|
|
19
|
+
if (this.config.log.traceHook) scope.log.trace('Hook \'%s\' executed', hookName)
|
|
20
|
+
}
|
|
21
|
+
if (removed.length > 0) pullAt(this.app.bajo.hooks, removed)
|
|
22
|
+
|
|
23
|
+
return results
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default runHook
|
|
@@ -4,8 +4,8 @@ import { trim } from 'lodash-es'
|
|
|
4
4
|
import increment from 'add-filename-increment'
|
|
5
5
|
|
|
6
6
|
async function saveAsDownload (file, obj, printSaved = true) {
|
|
7
|
-
const { print,
|
|
8
|
-
const plugin =
|
|
7
|
+
const { print, getPluginDataDir } = this.app.bajo
|
|
8
|
+
const plugin = this.name
|
|
9
9
|
const fname = increment(`${getPluginDataDir(plugin)}/${trim(file, '/')}`, { fs: true })
|
|
10
10
|
const dir = path.dirname(fname)
|
|
11
11
|
if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function sliceString (content, start, end) {
|
|
2
|
+
const idx1 = content.indexOf(start)
|
|
3
|
+
if (idx1 === -1) return false
|
|
4
|
+
let idx2 = content.indexOf(end)
|
|
5
|
+
if (idx2 === -1) return false
|
|
6
|
+
if (idx2 < idx1) {
|
|
7
|
+
const tmp = content.slice(idx1)
|
|
8
|
+
idx2 = tmp.indexOf(end) + idx1
|
|
9
|
+
}
|
|
10
|
+
return content.slice(idx1, idx2 + end.length)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default sliceString
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { words, upperFirst, map, concat, uniq, forOwn } from 'lodash-es'
|
|
2
|
+
import generateId from './generate-id.js'
|
|
3
|
+
|
|
4
|
+
const defIgnores = ['or', 'and', 'of', 'with']
|
|
5
|
+
|
|
6
|
+
const titleize = (text, { ignores = [], replacement = {} } = {}) => {
|
|
7
|
+
const replacer = {}
|
|
8
|
+
forOwn(replacement, (v, k) => {
|
|
9
|
+
const id = generateId('int')
|
|
10
|
+
replacer[id] = k
|
|
11
|
+
text = text.replace(k, ` ${id} `)
|
|
12
|
+
})
|
|
13
|
+
return map(words(text), t => {
|
|
14
|
+
forOwn(replacer, (v, k) => {
|
|
15
|
+
if (k === t) t = replacement[replacer[k]]
|
|
16
|
+
})
|
|
17
|
+
ignores = uniq(concat(ignores, defIgnores))
|
|
18
|
+
if (ignores.includes(t)) return t
|
|
19
|
+
return upperFirst(t)
|
|
20
|
+
}).join(' ')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default titleize
|