bajo 0.0.1 → 0.1.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 +38 -0
- package/README.md +57 -3
- package/boot/attach-helper.js +26 -0
- package/boot/boot-order.js +34 -0
- package/boot/build-config.js +94 -0
- package/boot/create-scope.js +36 -0
- package/boot/exit-handler.js +60 -0
- package/boot/helper/build-collections.js +40 -0
- package/boot/helper/call-helper-or-handler.js +15 -0
- package/boot/helper/current-loc.js +11 -0
- package/boot/helper/defaults-deep.js +14 -0
- package/boot/helper/dump.js +10 -0
- package/boot/helper/each-plugins.js +94 -0
- package/boot/helper/envs.js +14 -0
- package/boot/helper/error.js +47 -0
- package/boot/helper/fatal.js +12 -0
- package/boot/helper/generate-id.js +19 -0
- package/boot/helper/get-config.js +18 -0
- package/boot/helper/get-global-module-dir.js +27 -0
- package/boot/helper/get-helper.js +11 -0
- package/boot/helper/get-item-by-name.js +26 -0
- package/boot/helper/get-key-by-value.js +5 -0
- package/boot/helper/get-module-dir.js +22 -0
- package/boot/helper/get-plugin-name.js +39 -0
- package/boot/helper/get-plugin.js +7 -0
- package/boot/helper/import-module.js +25 -0
- package/boot/helper/import-pkg.js +67 -0
- package/boot/helper/index.js +36 -0
- package/boot/helper/is-empty-dir.js +9 -0
- package/boot/helper/is-log-in-range.js +10 -0
- package/boot/helper/is-set.js +5 -0
- package/boot/helper/is-valid-app.js +12 -0
- package/boot/helper/is-valid-plugin.js +12 -0
- package/boot/helper/log-levels.js +19 -0
- package/boot/helper/pascal-case.js +7 -0
- package/boot/helper/print.js +89 -0
- package/boot/helper/read-config.js +46 -0
- package/boot/helper/read-json.js +10 -0
- package/boot/helper/resolve-path.js +15 -0
- package/boot/helper/resolve-tpl-path.js +21 -0
- package/boot/helper/run-hook.js +46 -0
- package/boot/helper/save-as-download.js +18 -0
- package/boot/helper/white-space.js +3 -0
- package/boot/index.js +60 -0
- package/boot/lib/bora.js +97 -0
- package/boot/lib/build-helper.js +58 -0
- package/boot/lib/logger.js +75 -0
- package/boot/lib/omitted-plugin-keys.js +3 -0
- package/boot/lib/parse-args-argv.js +75 -0
- package/boot/lib/parse-env.js +36 -0
- package/boot/lib/shim.js +14 -0
- package/boot/plugins/attach-helper.js +20 -0
- package/boot/plugins/build-config.js +75 -0
- package/boot/plugins/check-clash.js +18 -0
- package/boot/plugins/check-dependency.js +37 -0
- package/boot/plugins/collect-config-handlers.js +25 -0
- package/boot/plugins/collect-exit-handlers.js +23 -0
- package/boot/plugins/collect-hooks.js +33 -0
- package/boot/plugins/extend-config.js +21 -0
- package/boot/plugins/index.js +28 -0
- package/boot/plugins/run.js +31 -0
- package/boot/run-tool.js +34 -0
- package/docs/boot_build-config.js.html +75 -0
- package/docs/boot_create-scope.js.html +25 -0
- package/docs/boot_index.js.html +43 -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/helper_emit.js.html +18 -0
- package/docs/helper_envs.js.html +16 -0
- package/docs/helper_error.js.html +25 -0
- package/docs/helper_get-bajo.js.html +42 -0
- package/docs/helper_index.js.html +39 -0
- package/docs/helper_log-levels.js.html +20 -0
- package/docs/helper_set-hook.js.html +38 -0
- package/docs/helper_walk-bajos.js.html +51 -0
- package/docs/index.html +16 -0
- package/docs/module-boot.html +3 -0
- package/docs/module-boot_buildConfig.html +3 -0
- package/docs/module-boot_createScope.html +3 -0
- package/docs/module-helper.html +7 -0
- package/docs/module-helper_setHook.html +4 -0
- package/docs/module-helper_walkBajos.html +6 -0
- package/docs/scripts/core.js +655 -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 +975 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +407 -0
- package/docs/styles/clean-jsdoc-theme-light.css +388 -0
- package/docs/styles/clean-jsdoc-theme.min.css +1 -0
- package/package.json +36 -4
- package/test/helper-error.js +25 -0
- package/test/helper-isSet.js +41 -0
- package/test/helper-pathResolve.js +28 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import globalModulesPath from 'global-modules-path'
|
|
2
|
+
import resolvePath from './resolve-path.js'
|
|
3
|
+
import error from './error.js'
|
|
4
|
+
import { dropRight } from 'lodash-es'
|
|
5
|
+
import fs from 'fs-extra'
|
|
6
|
+
|
|
7
|
+
const getGlobalModuleDir = (pkgName, silent = true) => {
|
|
8
|
+
let nodeModulesDir = process.env.BAJO_GLOBAL_MODULE_DIR
|
|
9
|
+
if (!nodeModulesDir) {
|
|
10
|
+
const npmPath = globalModulesPath.getPath('npm')
|
|
11
|
+
if (!npmPath) {
|
|
12
|
+
if (silent) return
|
|
13
|
+
throw error(`Can't locate npm global module directory`, { code: 'BAJO_CANT_LOCATE_NPM_GLOBAL_DIR' })
|
|
14
|
+
}
|
|
15
|
+
nodeModulesDir = dropRight(resolvePath(npmPath).split('/'), 1).join('/')
|
|
16
|
+
process.env.BAJO_GLOBAL_MODULE_DIR = nodeModulesDir
|
|
17
|
+
}
|
|
18
|
+
if (!pkgName) return nodeModulesDir
|
|
19
|
+
const dir = `${nodeModulesDir}/${pkgName}`
|
|
20
|
+
if (!fs.existsSync(dir)) {
|
|
21
|
+
if (silent) return
|
|
22
|
+
throw error(`Can't locate '%s' global module directory`, pkgName, { code: 'BAJO_CANT_LOCATE_MODULE_GLOBAL_DIR' })
|
|
23
|
+
}
|
|
24
|
+
return dir
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default getGlobalModuleDir
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { get } from 'lodash-es'
|
|
2
|
+
import error from './error.js'
|
|
3
|
+
|
|
4
|
+
function getHelper (name = '', thrown = true) {
|
|
5
|
+
const [plugin, method] = name.split(':')
|
|
6
|
+
const helper = get(this, `${plugin}.helper.${method}`)
|
|
7
|
+
if (helper) return helper
|
|
8
|
+
if (thrown) throw error.call(this, 'Can\'t find helper named \'%s\'', name)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default getHelper
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import resolvePath from './resolve-path.js'
|
|
3
|
+
import { createRequire } from 'module'
|
|
4
|
+
const require = createRequire(import.meta.url)
|
|
5
|
+
|
|
6
|
+
const getModuleDir = (pkgName, base) => {
|
|
7
|
+
if (base === 'app') base = process.env.BAJOCWD
|
|
8
|
+
let pkgPath = pkgName + '/package.json'
|
|
9
|
+
if (base) pkgPath = `${base}/node_modules/${pkgPath}`
|
|
10
|
+
const paths = require.resolve.paths(pkgPath)
|
|
11
|
+
paths.unshift(path.join(process.env.BAJOCWD, 'node_modules', pkgName))
|
|
12
|
+
let resolved
|
|
13
|
+
try {
|
|
14
|
+
resolved = require.resolve(pkgPath, { paths })
|
|
15
|
+
} catch (err) {
|
|
16
|
+
return null
|
|
17
|
+
}
|
|
18
|
+
const dir = resolvePath(path.dirname(resolved))
|
|
19
|
+
return dir
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default getModuleDir
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import resolvePath from './resolve-path.js'
|
|
2
|
+
import { isFunction, isPlainObject } from 'lodash-es'
|
|
3
|
+
import error from './error.js'
|
|
4
|
+
|
|
5
|
+
async function load (file, asDefaultImport = true) {
|
|
6
|
+
const imported = await import(resolvePath(file, true))
|
|
7
|
+
if (asDefaultImport) return imported.default
|
|
8
|
+
return imported
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function importModule (file, { asDefaultImport, asHandler } = {}) {
|
|
12
|
+
let mod = await load(file, asDefaultImport)
|
|
13
|
+
if (!asHandler) return mod
|
|
14
|
+
if (isFunction(mod)) mod = { level: 999, handler: mod }
|
|
15
|
+
if (!isPlainObject(mod)) throw error.call(this, 'File \'%s\' is NOT a handler module', file)
|
|
16
|
+
if (mod.forceAsync && mod.handler.constructor.name !== 'AsyncFunction') {
|
|
17
|
+
const oldHandler = mod.handler
|
|
18
|
+
mod.handler = async function (...args) {
|
|
19
|
+
oldHandler.call(this, ...args)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return mod
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default importModule
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { isPlainObject, map, last, isEmpty, has, keys, values, trim, get } from 'lodash-es'
|
|
2
|
+
import os from 'os'
|
|
3
|
+
import getModuleDir from './get-module-dir.js'
|
|
4
|
+
import resolvePath from './resolve-path.js'
|
|
5
|
+
import readJson from './read-json.js'
|
|
6
|
+
import defaultsDeep from './defaults-deep.js'
|
|
7
|
+
import path from 'path'
|
|
8
|
+
import fs from 'fs-extra'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load/import a package dynamically. You can import package one-by-one or multiple
|
|
12
|
+
* packages at once.
|
|
13
|
+
*
|
|
14
|
+
* Package 'pkg' must be in the following format: ```<original name>:<new name>:<bajo package name>```
|
|
15
|
+
* ```<new name>``` can be omitted, so the format will be: ```<name>::<bajo package name>```
|
|
16
|
+
*
|
|
17
|
+
* If you only import one package, returned value is the imported package itself
|
|
18
|
+
* If multiple packages are imported, returned value is an object with ```<new name>``` as its
|
|
19
|
+
* keys and imported packages as its values
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
* ```
|
|
23
|
+
* const imported = await importPkg('ora::bajo-cli')
|
|
24
|
+
* const multiple = await importPkg('ora::bajo-cli', 'lodash:_:bajo')
|
|
25
|
+
*
|
|
26
|
+
* @param {...string} pkg
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
const importPkg = async (...pkg) => {
|
|
31
|
+
const result = {}
|
|
32
|
+
let opts = { returnDefault: true }
|
|
33
|
+
if (isPlainObject(last(pkg))) {
|
|
34
|
+
opts = defaultsDeep(pkg.pop(), opts)
|
|
35
|
+
}
|
|
36
|
+
for (const p of pkg) {
|
|
37
|
+
const parts = map(p.split(':'), i => trim(i))
|
|
38
|
+
let [ns, orgName, name] = parts
|
|
39
|
+
if (parts.length === 1) {
|
|
40
|
+
orgName = ns
|
|
41
|
+
ns = 'bajo'
|
|
42
|
+
name = orgName
|
|
43
|
+
} else if (parts.length === 2) {
|
|
44
|
+
name = orgName
|
|
45
|
+
}
|
|
46
|
+
if (isEmpty(name)) name = orgName
|
|
47
|
+
const dir = getModuleDir(orgName, ns)
|
|
48
|
+
const pkg = readJson(`${dir}/package.json`)
|
|
49
|
+
const mainFileOrg = dir + '/' + (pkg.main ?? get(pkg, 'exports.default', 'index.js'))
|
|
50
|
+
let mainFile = resolvePath(mainFileOrg, os.platform() === 'win32')
|
|
51
|
+
if (isEmpty(path.extname(mainFile))) {
|
|
52
|
+
if (fs.existsSync(`${mainFileOrg}/index.js`)) mainFile += '/index.js'
|
|
53
|
+
else mainFile += '.js'
|
|
54
|
+
}
|
|
55
|
+
let mod = await import(mainFile)
|
|
56
|
+
if (opts.returnDefault && has(mod, 'default')) {
|
|
57
|
+
mod = mod.default
|
|
58
|
+
if (opts.returnDefault && has(mod, 'default')) mod = mod.default
|
|
59
|
+
}
|
|
60
|
+
result[name] = mod
|
|
61
|
+
}
|
|
62
|
+
if (pkg.length === 1) return result[keys(result)[0]]
|
|
63
|
+
if (opts.asObject) return result
|
|
64
|
+
return values(result)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default importPkg
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bajo Helper is a general-purpose container that consists of functions, objects, or arrays
|
|
3
|
+
* that are accessible across all plugins/Bajos and applications. It also serves as a proxy
|
|
4
|
+
* to some exported third-party libraries.
|
|
5
|
+
*
|
|
6
|
+
* To use it, simply deconstruct the variables you want from Bajo Helper as shown in the
|
|
7
|
+
* example below.
|
|
8
|
+
*
|
|
9
|
+
* @module helper
|
|
10
|
+
* @example
|
|
11
|
+
* module.exports = async function () {
|
|
12
|
+
* const { fs, getConfig } = this.bajo.helper
|
|
13
|
+
* const config = getConfig('bajoExtra')
|
|
14
|
+
* await fs.writeFile('./bajo-extra-config.json', JSON.stringify(config), 'utf8')
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* | Attached As | Package Name | Usage |
|
|
20
|
+
* |-------------|--------------|-------|
|
|
21
|
+
* | _ | [lodash](https://lodash.com/) | ```const { _ } = this.bajo.helper``` |
|
|
22
|
+
* | callsites | [callsites](https://github.com/sindresorhus/callsites) | ```const { _ } = this.bajo.helper``` |
|
|
23
|
+
* | dateFormat | [dateformat](https://github.com/felixge/node-dateformat) | ```const { dateFormat } = this.bajo.helper``` |
|
|
24
|
+
* | fastGlob | [fast-glob](https://github.com/mrmlnc/fast-glob) | ```const { fastGlob } = this.bajo.helper``` |
|
|
25
|
+
* | flatten | [flat](https://github.com/hughsk/flat) | ```const { flatten } = this.bajo.helper``` |
|
|
26
|
+
* | freeze | [deep-freeze-strict](https://github.com/jsdf/deep-freeze) | ```const { freeze } = this.bajo.helper``` |
|
|
27
|
+
* | fs | [fs-extra](https://github.com/jprichardson/node-fs-extra) | ```const { fs } = this.bajo.helper``` |
|
|
28
|
+
* | lockfile | [proper-lockfile](https://github.com/moxystudio/node-proper-lockfile) | ```const { lockfile } = this.bajo.helper``` |
|
|
29
|
+
* | outmatch | [outmatch](https://github.com/axtgr/outmatch) | ```const { outmatch } = this.bajo.helper``` |
|
|
30
|
+
* | semver | [semver](https://github.com/npm/node-semver) | ```const { semver } = this.bajo.helper``` |
|
|
31
|
+
* | unflatten | [flat](https://github.com/hughsk/flat) | ```const { unflatten } = this.bajo.helper``` |
|
|
32
|
+
*
|
|
33
|
+
* @memberof module:helper/3rdPartyLibs
|
|
34
|
+
* @name 3rd Party Libraries
|
|
35
|
+
* @instance
|
|
36
|
+
*/
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import logLevels from './log-levels.js'
|
|
2
|
+
import { keys, indexOf } from 'lodash-es'
|
|
3
|
+
|
|
4
|
+
function isLogInRange (level) {
|
|
5
|
+
const levels = keys(logLevels)
|
|
6
|
+
const logLevel = indexOf(levels, this.bajo.config.log.level)
|
|
7
|
+
return indexOf(levels, level) >= logLevel
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default isLogInRange
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fs from 'fs-extra'
|
|
2
|
+
import resolvePath from './resolve-path.js'
|
|
3
|
+
|
|
4
|
+
const isValidApp = (dir) => {
|
|
5
|
+
if (!dir) dir = process.env.BAJOCWD
|
|
6
|
+
dir = resolvePath(dir)
|
|
7
|
+
const hasAppDir = fs.existsSync(`${dir}/app/bajo`)
|
|
8
|
+
const hasPackageJson = fs.existsSync(`${dir}/package.json`)
|
|
9
|
+
return hasAppDir && hasPackageJson
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default isValidApp
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fs from 'fs-extra'
|
|
2
|
+
import resolvePath from './resolve-path.js'
|
|
3
|
+
|
|
4
|
+
const isValidPlugin = (dir) => {
|
|
5
|
+
if (!dir) dir = process.env.BAJOCWD
|
|
6
|
+
dir = resolvePath(dir)
|
|
7
|
+
const hasBajoDir = fs.existsSync(`${dir}/bajo`)
|
|
8
|
+
const hasPackageJson = fs.existsSync(`${dir}/package.json`)
|
|
9
|
+
return hasBajoDir && hasPackageJson
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default isValidPlugin
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import bora from '../lib/bora.js'
|
|
2
|
+
import Sprintf from 'sprintf-js'
|
|
3
|
+
import { last, isPlainObject, get } from 'lodash-es'
|
|
4
|
+
import defaultsDeep from './defaults-deep.js'
|
|
5
|
+
import getPluginName from './get-plugin-name.js'
|
|
6
|
+
|
|
7
|
+
const { sprintf } = Sprintf
|
|
8
|
+
|
|
9
|
+
function prep (args) {
|
|
10
|
+
let opts = { type: 'bora', exit: false, skipSilent: false }
|
|
11
|
+
const l = last(args)
|
|
12
|
+
if (isPlainObject(l)) opts = defaultsDeep(args.pop(), opts)
|
|
13
|
+
const [pkg, msg, ...params] = args
|
|
14
|
+
opts.pkg = pkg
|
|
15
|
+
opts.ns = pkg === 'bajo' ? 'bajoI18N' : pkg
|
|
16
|
+
return { ns: opts.ns, pkg, msg, params, opts }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function format (...args) {
|
|
20
|
+
const { ns, msg, params, opts } = prep(args)
|
|
21
|
+
if (!msg) return ''
|
|
22
|
+
const i18n = get(this, 'bajoI18N.instance')
|
|
23
|
+
if (i18n) {
|
|
24
|
+
if (isPlainObject(params[0])) return i18n.t(msg, params[0])
|
|
25
|
+
return i18n.t(msg, { ns, pkg: opts.pkg, postProcess: 'sprintf', sprintf: params })
|
|
26
|
+
}
|
|
27
|
+
return sprintf(msg, ...params)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const print = {
|
|
31
|
+
__: function (...args) {
|
|
32
|
+
const [msg, ...params] = args
|
|
33
|
+
const pkg = getPluginName.call(this, 2)
|
|
34
|
+
return format.call(this, pkg, msg, ...params)
|
|
35
|
+
},
|
|
36
|
+
_format: format,
|
|
37
|
+
fail: function (...args) {
|
|
38
|
+
args.unshift(getPluginName.call(this, 2))
|
|
39
|
+
const { ns, opts, msg, params } = prep(args)
|
|
40
|
+
if (msg) {
|
|
41
|
+
if (opts.type === 'bora') bora.call(this, ns, opts).fail(msg, ...params)
|
|
42
|
+
else console.error(format.call(this, ns, msg, ...params))
|
|
43
|
+
}
|
|
44
|
+
if (opts.exit) process.exit(1)
|
|
45
|
+
},
|
|
46
|
+
succeed: function (...args) {
|
|
47
|
+
args.unshift(getPluginName.call(this, 2))
|
|
48
|
+
const { ns, opts, msg, params } = prep(args)
|
|
49
|
+
if (msg) {
|
|
50
|
+
if (opts.type === 'bora') bora.call(this, ns, opts).succeed(msg, ...params)
|
|
51
|
+
else console.log(format.call(this, ns, msg, ...params))
|
|
52
|
+
}
|
|
53
|
+
if (opts.exit) process.exit(0)
|
|
54
|
+
},
|
|
55
|
+
warn: function (...args) {
|
|
56
|
+
args.unshift(getPluginName.call(this, 2))
|
|
57
|
+
const { ns, opts, msg, params } = prep(args)
|
|
58
|
+
if (msg) {
|
|
59
|
+
if (opts.type === 'bora') bora.call(this, ns, opts).warn(msg, ...params)
|
|
60
|
+
else console.log(format.call(this, ns, msg, ...params))
|
|
61
|
+
}
|
|
62
|
+
if (opts.exit) process.exit(0)
|
|
63
|
+
},
|
|
64
|
+
info: function (...args) {
|
|
65
|
+
args.unshift(getPluginName.call(this, 2))
|
|
66
|
+
const { ns, opts, msg, params } = prep(args)
|
|
67
|
+
if (msg) {
|
|
68
|
+
if (opts.type === 'bora') bora.call(this, ns, opts).info(msg, ...params)
|
|
69
|
+
else console.log(format.call(this, ns, msg, ...params))
|
|
70
|
+
}
|
|
71
|
+
if (opts.exit) process.exit(0)
|
|
72
|
+
},
|
|
73
|
+
fatal: function (...args) {
|
|
74
|
+
args.unshift(getPluginName.call(this, 2))
|
|
75
|
+
const { ns, opts, msg, params } = prep(args)
|
|
76
|
+
if (msg) {
|
|
77
|
+
if (opts.type === 'bora') bora.call(this, ns, opts).fatal(msg, ...params)
|
|
78
|
+
else console.error(format.call(this, ns, msg, ...params))
|
|
79
|
+
}
|
|
80
|
+
process.exit(0)
|
|
81
|
+
},
|
|
82
|
+
bora: function (...args) {
|
|
83
|
+
let ns = getPluginName.call(this, 2)
|
|
84
|
+
if (ns === 'bajo') ns = 'bajoI18N'
|
|
85
|
+
return bora.call(this, ns, ...args)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default print
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import resolvePath from './resolve-path.js'
|
|
3
|
+
import readJson from './read-json.js'
|
|
4
|
+
import { find, map, isEmpty } from 'lodash-es'
|
|
5
|
+
import error from './error.js'
|
|
6
|
+
import fg from 'fast-glob'
|
|
7
|
+
|
|
8
|
+
async function readConfig (file, { pattern, globOptions = {}, ignoreError, defValue = {} } = {}) {
|
|
9
|
+
file = resolvePath(file)
|
|
10
|
+
let ext = path.extname(file)
|
|
11
|
+
const fname = path.dirname(file) + '/' + path.basename(file, ext)
|
|
12
|
+
ext = ext.toLowerCase()
|
|
13
|
+
if (['.mjs', '.js'].includes(ext)) {
|
|
14
|
+
const { handler } = find(this.bajo.configHandlers, { ext })
|
|
15
|
+
return await handler.call(this, file)
|
|
16
|
+
}
|
|
17
|
+
if (ext === '.json') return await readJson(file)
|
|
18
|
+
if (!['', '.*'].includes(ext)) {
|
|
19
|
+
const item = find(this.bajo.configHandlers, { ext })
|
|
20
|
+
if (!item) {
|
|
21
|
+
if (!ignoreError) throw error.call(this, 'Can\'t parse \'%s\'', file, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
22
|
+
return defValue
|
|
23
|
+
}
|
|
24
|
+
return item.handler.call(this, file)
|
|
25
|
+
}
|
|
26
|
+
const item = pattern ?? `${fname}.{${map(map(this.bajo.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
|
|
27
|
+
const files = await fg(item, globOptions)
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
if (!ignoreError) throw error.call(this, 'No config file found', { code: 'BAJO_CONFIG_FILE_NOT_FOUND' })
|
|
30
|
+
return defValue
|
|
31
|
+
}
|
|
32
|
+
let config = defValue
|
|
33
|
+
for (const f of files) {
|
|
34
|
+
const ext = path.extname(f).toLowerCase()
|
|
35
|
+
const item = find(this.bajo.configHandlers, { ext })
|
|
36
|
+
if (!item) {
|
|
37
|
+
if (!ignoreError) throw error.call(this, 'Can\'t parse \'%s\'', f, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
38
|
+
continue
|
|
39
|
+
}
|
|
40
|
+
config = await item.handler.call(this, f)
|
|
41
|
+
if (!isEmpty(config)) break
|
|
42
|
+
}
|
|
43
|
+
return config
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default readConfig
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { fileURLToPath } from 'url'
|
|
3
|
+
import os from 'os'
|
|
4
|
+
|
|
5
|
+
const resolvePath = (item, asFileUrl) => {
|
|
6
|
+
if (item.startsWith('file://')) item = fileURLToPath(item)
|
|
7
|
+
item = path.resolve(item)
|
|
8
|
+
if (os.platform() === 'win32') {
|
|
9
|
+
item = item.replace(/\\/g, '/')
|
|
10
|
+
}
|
|
11
|
+
if (asFileUrl) item = `file:///${item}`
|
|
12
|
+
return item
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default resolvePath
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isEmpty, trim } from 'lodash-es'
|
|
2
|
+
import fs from 'fs-extra'
|
|
3
|
+
|
|
4
|
+
function resolveTplPath (name, baseTpl, extTpl = '') {
|
|
5
|
+
const { error, getConfig } = this.bajo.helper
|
|
6
|
+
let [ns, path] = name.split(':')
|
|
7
|
+
if (isEmpty(path)) {
|
|
8
|
+
path = ns
|
|
9
|
+
ns = 'app'
|
|
10
|
+
}
|
|
11
|
+
if (path.startsWith('.')) throw error('Path \'%s\' must be an absolute path', path)
|
|
12
|
+
if (!this[ns]) throw error('Unknown plugin \'%s\' or plugin isn\'t loaded yet', ns)
|
|
13
|
+
const cfgNs = getConfig(ns, { full: true })
|
|
14
|
+
const cfgApp = getConfig('app', { full: true })
|
|
15
|
+
let file = `${cfgNs.dir}/${baseTpl}/${trim(path, '/')}${extTpl}`
|
|
16
|
+
const override = `${cfgApp.dir}/${baseTpl}/override/${ns}/${trim(path, '/')}${extTpl}`
|
|
17
|
+
if (fs.existsSync(override)) file = override
|
|
18
|
+
return file
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default resolveTplPath
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { filter, isEmpty, orderBy } from 'lodash-es'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module helper/runHook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Set hook defined by parameter ```hookName```. Hook name should be in this following format:
|
|
9
|
+
* ```<namespace>:<identifier>``` - where namespace is a valid Bajo name and
|
|
10
|
+
* identifier is a unique string set by Bajo developer to identify a hook inside a Bajo
|
|
11
|
+
*
|
|
12
|
+
* @instance
|
|
13
|
+
* @async
|
|
14
|
+
* @param {string} hookName - Hook's name
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const { runHook } = this.bajo.helper
|
|
18
|
+
* await runHook('myBajo:afterStartApp')
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
async function runHook (hookName, ...args) {
|
|
22
|
+
// const { log } = this.bajo.helper
|
|
23
|
+
// log.trace('Run hook: %s', hookName)
|
|
24
|
+
const [ns, path] = (hookName ?? '').split(':')
|
|
25
|
+
let fns = filter(this.bajo.hooks, { ns, path })
|
|
26
|
+
if (isEmpty(fns)) return
|
|
27
|
+
fns = orderBy(fns, ['level'])
|
|
28
|
+
const results = []
|
|
29
|
+
for (const i in fns) {
|
|
30
|
+
const fn = fns[i]
|
|
31
|
+
/*
|
|
32
|
+
if (config.log.report.includes(id)) {
|
|
33
|
+
log.trace({ args }, 'Call hook: %s', id)
|
|
34
|
+
}
|
|
35
|
+
*/
|
|
36
|
+
const res = await fn.handler.call(this, ...args)
|
|
37
|
+
results.push({
|
|
38
|
+
hook: hookName,
|
|
39
|
+
tag: fn.tag,
|
|
40
|
+
resp: res
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
return results
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default runHook
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import fs from 'fs-extra'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { trim } from 'lodash-es'
|
|
4
|
+
import increment from 'add-filename-increment'
|
|
5
|
+
|
|
6
|
+
async function saveAsDownload (file, obj, printSaved = true) {
|
|
7
|
+
const { print, getPluginName, resolvePath } = this.bajo.helper
|
|
8
|
+
const config = this.bajo.config
|
|
9
|
+
const plugin = getPluginName(4)
|
|
10
|
+
const fname = resolvePath(increment(`${config.dir.data}/plugins/${plugin}/${trim(file, '/')}`, { fs: true }))
|
|
11
|
+
const dir = path.dirname(fname)
|
|
12
|
+
if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
|
|
13
|
+
await fs.writeFile(fname, obj, 'utf8')
|
|
14
|
+
if (printSaved) print.bora('Saved as \'%s\'', path.resolve(fname), { skipSilence: true }).succeed()
|
|
15
|
+
return fname
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default saveAsDownload
|