bajo 2.1.0 → 2.2.1
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/.github/FUNDING.yml +0 -0
- package/.github/workflows/repo-lockdown.yml +0 -0
- package/.jsdoc.conf.json +0 -0
- package/.mocharc.json +4 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/class/{misc → app}/log.js +8 -2
- package/class/app.js +63 -50
- package/class/bajo.js +43 -211
- package/class/base.js +25 -22
- package/class/helper/bajo.js +55 -53
- package/class/helper/base.js +37 -75
- package/class/{misc → plugin}/err.js +23 -18
- package/class/{misc → plugin}/print.js +7 -16
- package/class/plugin/tools.js +42 -0
- package/class/plugin.js +58 -54
- package/docs/App.html +0 -0
- package/docs/Bajo.html +0 -0
- package/docs/Base.html +0 -0
- package/docs/Err.html +0 -0
- package/docs/Log.html +0 -0
- package/docs/Plugin.html +0 -0
- package/docs/Print.html +0 -0
- package/docs/class_app.js.html +0 -0
- package/docs/class_bajo.js.html +0 -0
- package/docs/class_base.js.html +0 -0
- package/docs/class_helper_bajo.js.html +0 -0
- package/docs/class_helper_base.js.html +0 -0
- package/docs/class_misc_err.js.html +0 -0
- package/docs/class_misc_log.js.html +0 -0
- package/docs/class_misc_print.js.html +0 -0
- package/docs/class_plugin.js.html +0 -0
- package/docs/data/search.json +0 -0
- package/docs/fonts/Inconsolata-Regular.ttf +0 -0
- package/docs/fonts/OpenSans-Regular.ttf +0 -0
- package/docs/fonts/WorkSans-Bold.ttf +0 -0
- package/docs/global.html +0 -0
- package/docs/index.html +0 -0
- package/docs/index.js.html +0 -0
- package/docs/lib_current-loc.js.html +0 -0
- package/docs/lib_formats.js.html +0 -0
- package/docs/lib_import-module.js.html +0 -0
- package/docs/lib_log-levels.js.html +0 -0
- package/docs/lib_parse-args-argv.js.html +0 -0
- package/docs/lib_parse-env.js.html +0 -0
- package/docs/lib_resolve-path.js.html +0 -0
- package/docs/lib_shim.js.html +0 -0
- package/docs/module-Helper_Bajo.html +0 -0
- package/docs/module-Helper_Base.html +0 -0
- package/docs/module-Lib.html +0 -0
- package/docs/scripts/core.js +476 -477
- package/docs/scripts/core.min.js +0 -0
- package/docs/scripts/resize.js +36 -36
- package/docs/scripts/search.js +105 -105
- package/docs/scripts/search.min.js +0 -0
- package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
- package/docs/scripts/third-party/fuse.js +1 -1
- package/docs/scripts/third-party/hljs-line-num-original.js +282 -285
- package/docs/scripts/third-party/hljs-line-num.js +1 -1
- package/docs/scripts/third-party/hljs-original.js +1195 -1202
- package/docs/scripts/third-party/hljs.js +1 -1
- package/docs/scripts/third-party/popper.js +1 -1
- package/docs/scripts/third-party/tippy.js +1 -1
- package/docs/scripts/third-party/tocbot.js +508 -509
- package/docs/scripts/third-party/tocbot.min.js +0 -0
- package/docs/static/bitcoin.jpeg +0 -0
- package/docs/static/home.md +0 -0
- package/docs/static/logo-ecosystem.png +0 -0
- package/docs/static/logo.png +0 -0
- package/docs/styles/clean-jsdoc-theme-base.css +0 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
- package/docs/styles/clean-jsdoc-theme-light.css +0 -0
- package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
- package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
- package/docs/styles/clean-jsdoc-theme.min.css +0 -0
- package/extend/bajo/intl/en-US.json +10 -5
- package/extend/bajo/intl/id.json +10 -5
- package/extend/waibuStatic/virtual.json +0 -0
- package/index.js +9 -1
- package/lib/find-deep.js +24 -0
- package/lib/formats.js +0 -0
- package/lib/freeze.js +16 -0
- package/lib/import-module.js +5 -3
- package/lib/index.js +6 -0
- package/lib/log-levels.js +0 -0
- package/package.json +5 -11
- package/test/base.test.js +108 -0
- package/wiki/CHANGES.md +68 -0
- package/wiki/CONFIG.md +0 -0
- package/wiki/CONTRIBUTING.md +0 -0
- package/wiki/DEV_GUIDE.md +0 -0
- package/wiki/ECOSYSTEM.md +0 -0
- package/wiki/GETTING-STARTED.md +1 -1
- package/wiki/USER-GUIDE.md +0 -0
- package/lib/current-loc.js +0 -33
- package/lib/parse-args-argv.js +0 -80
- package/lib/parse-env.js +0 -50
- package/lib/resolve-path.js +0 -24
- package/lib/shim.js +0 -37
|
File without changes
|
package/docs/static/bitcoin.jpeg
CHANGED
|
File without changes
|
package/docs/static/home.md
CHANGED
|
File without changes
|
|
File without changes
|
package/docs/static/logo.png
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -23,11 +23,10 @@
|
|
|
23
23
|
"setupBootOrder": "Setup boot order",
|
|
24
24
|
"configHandlers%s": "Config handlers: %s",
|
|
25
25
|
"dataDir%s": "Data dir: %s",
|
|
26
|
-
"exited": "
|
|
26
|
+
"exited%s": "- %s exited",
|
|
27
27
|
"appShutdown": "App shutdown",
|
|
28
28
|
"appletModeActivated": "Applet mode activated",
|
|
29
|
-
"collected%s%d": "%s
|
|
30
|
-
"attachMethods": "Attach methods",
|
|
29
|
+
"collected%s%d": "Collected %s: %d",
|
|
31
30
|
"readConfigs": "Read configurations",
|
|
32
31
|
"checkAliasNameClash": "Checking alias & name clashes",
|
|
33
32
|
"checkDeps": "Checking dependencies",
|
|
@@ -127,7 +126,7 @@
|
|
|
127
126
|
"offlineL": "offline",
|
|
128
127
|
"reconnectingL": "reconnecting",
|
|
129
128
|
"connMustHave%s": "Connection must have '%s'",
|
|
130
|
-
"notFound%s%s": "%s '%s' not found",
|
|
129
|
+
"notFound%s%s": "%s|upperFirst '%s' not found",
|
|
131
130
|
"connection": "Connection",
|
|
132
131
|
"file": "File",
|
|
133
132
|
"applet": "Applet",
|
|
@@ -175,5 +174,11 @@
|
|
|
175
174
|
"buildPluginsComplete": "Building plugins completed",
|
|
176
175
|
"pluginPackageNotFound%s": "Plugin package '%s' file not found!",
|
|
177
176
|
"pluginPackageInvalid%s": "`Plugin package '%s' should be an instance of Base class`",
|
|
178
|
-
"appletNeedsBajoCli": "Applet needs to have 'bajo-cli' loaded"
|
|
177
|
+
"appletNeedsBajoCli": "Applet needs to have 'bajo-cli' loaded",
|
|
178
|
+
"unknown%s%s": "Unknown %s|toLower '%s'",
|
|
179
|
+
"notImplemented%s%s": "%s|upperFirst '%s' not implemented yet",
|
|
180
|
+
"method": "Method",
|
|
181
|
+
"exist%s%s": "%s|upperFirst '%s' exists already",
|
|
182
|
+
"fieldError%s%s": "'%s': %s|lowerFirst",
|
|
183
|
+
"reservedName%s%s": "%s|upperFirst name '%s' is a reserved name. Please rename to something else"
|
|
179
184
|
}
|
package/extend/bajo/intl/id.json
CHANGED
|
@@ -23,11 +23,10 @@
|
|
|
23
23
|
"setupBootOrder": "Atur urutan booting",
|
|
24
24
|
"configHandlers%s": "Pengatur konfigurasi: %s",
|
|
25
25
|
"dataDir%s": "Dir data: %s",
|
|
26
|
-
"exited": "
|
|
26
|
+
"exited%s": "- %s keluar",
|
|
27
27
|
"appShutdown": "Aplikasi ditutup",
|
|
28
28
|
"appletModeActivated": "Mode applet diaktifkan",
|
|
29
|
-
"collected%s%d": "%s terkoleksi: %d",
|
|
30
|
-
"attachMethods": "Tempelkan metode",
|
|
29
|
+
"collected%s%d": "%s|upperFirst terkoleksi: %d",
|
|
31
30
|
"readConfigs": "Baca konfigurasi",
|
|
32
31
|
"checkAliasNameClash": "Cek bentrokan nama dan alias",
|
|
33
32
|
"checkDeps": "Cek ketergantungan",
|
|
@@ -127,7 +126,7 @@
|
|
|
127
126
|
"offlineL": "offline",
|
|
128
127
|
"reconnectingL": "mencoba menghubung kembali",
|
|
129
128
|
"connMustHave%s": "Koneksi harus memiliki '%s'",
|
|
130
|
-
"notFound%s%s": "%s '%s' tidak ditemukan",
|
|
129
|
+
"notFound%s%s": "%s|upperFirst '%s' tidak ditemukan",
|
|
131
130
|
"connection": "Koneksi",
|
|
132
131
|
"file": "Berkas",
|
|
133
132
|
"applet": "Applet",
|
|
@@ -175,5 +174,11 @@
|
|
|
175
174
|
"buildPluginsComplete": "Pemuatan plugin komplit",
|
|
176
175
|
"pluginPackageNotFound%s": "Berkas paket plugin '%s' tidak ditemukan!",
|
|
177
176
|
"pluginPackageInvalid%s": "Paket plugin '%s' harus berupa instan dari kelas Base",
|
|
178
|
-
"appletNeedsBajoCli": "Applet membutuhkan 'bajo-cli' yang harus termuat terlebih dahulu"
|
|
177
|
+
"appletNeedsBajoCli": "Applet membutuhkan 'bajo-cli' yang harus termuat terlebih dahulu",
|
|
178
|
+
"unknown%s%s": "%s|upperFirst '%s' tidak dikenal",
|
|
179
|
+
"notImplemented%s%s": "%s|upperFirst '%s' belum diimplementasikan",
|
|
180
|
+
"method": "Metode",
|
|
181
|
+
"exist%s%s": "%s|upperFirst '%s' sudah ada",
|
|
182
|
+
"fieldError%s%s": "'%s': %s|lowerFirst",
|
|
183
|
+
"reservedName%s%s": "Nama %s|lowerFirst '%s' adalah nama tang di reserve. Silahkan gunakan nama lainnya"
|
|
179
184
|
}
|
|
File without changes
|
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import App from './class/app.js'
|
|
2
|
-
import shim from '
|
|
2
|
+
import { shim } from 'aneka'
|
|
3
|
+
import fs from 'fs-extra'
|
|
3
4
|
|
|
4
5
|
shim()
|
|
5
6
|
|
|
@@ -25,6 +26,13 @@ shim()
|
|
|
25
26
|
* @returns {App}
|
|
26
27
|
*/
|
|
27
28
|
async function boot (cwd) {
|
|
29
|
+
if (!cwd) cwd = process.cwd()
|
|
30
|
+
const pkgFile = `${cwd}/package.json`
|
|
31
|
+
const pkg = fs.readJsonSync(pkgFile)
|
|
32
|
+
if (pkg.type !== 'module') {
|
|
33
|
+
console.error(`Please turn on ES6 parsing by adding "type": "module" to ${pkgFile}!`)
|
|
34
|
+
process.exit(1)
|
|
35
|
+
}
|
|
28
36
|
const app = new App(cwd)
|
|
29
37
|
return await app.boot()
|
|
30
38
|
}
|
package/lib/find-deep.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Find item deep in paths
|
|
5
|
+
*
|
|
6
|
+
* @method
|
|
7
|
+
* @memberof module:Lib
|
|
8
|
+
* @param {string} item - Item to find
|
|
9
|
+
* @param {Array} paths - Array of path to look for
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
12
|
+
function findDeep (item, paths) {
|
|
13
|
+
let dir
|
|
14
|
+
for (const p of paths) {
|
|
15
|
+
const d = `${p}/${item}`
|
|
16
|
+
if (fs.existsSync(d)) {
|
|
17
|
+
dir = d
|
|
18
|
+
break
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return dir
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default findDeep
|
package/lib/formats.js
CHANGED
|
File without changes
|
package/lib/freeze.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import deepFreezeStrict from 'deep-freeze-strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Freeze object
|
|
5
|
+
*
|
|
6
|
+
* @method
|
|
7
|
+
* @memberof module:Lib
|
|
8
|
+
* @param {Object} obj - Object to freeze
|
|
9
|
+
* @param {boolean} [shallow=false] - If ```false``` (default), deep freeze object
|
|
10
|
+
*/
|
|
11
|
+
function freeze (obj, shallow = false) {
|
|
12
|
+
if (shallow) Object.freeze(obj)
|
|
13
|
+
else deepFreezeStrict(obj)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default freeze
|
package/lib/import-module.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import resolvePath from './resolve-path.js'
|
|
2
1
|
import fs from 'fs-extra'
|
|
3
2
|
import lodash from 'lodash'
|
|
3
|
+
import aneka from 'aneka'
|
|
4
|
+
|
|
5
|
+
const { resolvePath } = aneka
|
|
4
6
|
const { isFunction, isPlainObject } = lodash
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -32,8 +34,8 @@ const { isFunction, isPlainObject } = lodash
|
|
|
32
34
|
* @returns {any}
|
|
33
35
|
* @see Bajo#importModule
|
|
34
36
|
*/
|
|
35
|
-
async function importModule (file, { asDefaultImport, asHandler, noCache } = {}) {
|
|
36
|
-
const load = async (file, asDefaultImport
|
|
37
|
+
async function importModule (file, { asDefaultImport = true, asHandler, noCache } = {}) {
|
|
38
|
+
const load = async (file, asDefaultImport, noCache = false) => {
|
|
37
39
|
file = resolvePath(file, true)
|
|
38
40
|
if (noCache) file += `?_=${Date.now()}`
|
|
39
41
|
const imported = await import(file)
|
package/lib/index.js
ADDED
package/lib/log-levels.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bajo",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "The ultimate framework for whipping up massive apps in no time",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build-doc": "jsdoc -c .jsdoc.conf.json",
|
|
8
|
-
"test": "mocha"
|
|
8
|
+
"test": "mocha --recursive"
|
|
9
9
|
},
|
|
10
10
|
"type": "module",
|
|
11
11
|
"repository": {
|
|
@@ -26,29 +26,23 @@
|
|
|
26
26
|
"homepage": "https://github.com/ardhi/bajo#readme",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"add-filename-increment": "^1.0.0",
|
|
29
|
-
"aneka": "^0.
|
|
29
|
+
"aneka": "^0.10.0",
|
|
30
30
|
"chalk": "^5.6.0",
|
|
31
31
|
"dayjs": "^1.11.13",
|
|
32
32
|
"deep-freeze-strict": "^1.1.1",
|
|
33
33
|
"delay": "^6.0.0",
|
|
34
|
-
"dotenv": "^17.2.1",
|
|
35
|
-
"dotenv-parse-variables": "^2.0.0",
|
|
36
34
|
"empty-dir": "^3.0.0",
|
|
37
35
|
"fast-glob": "^3.3.3",
|
|
38
|
-
"flat": "^6.0.1",
|
|
39
36
|
"fs-extra": "^11.3.1",
|
|
40
37
|
"get-global-path": "^0.0.1",
|
|
41
38
|
"lodash": "^4.17.21",
|
|
42
|
-
"ms": "^2.1.3",
|
|
43
|
-
"nanoid": "^5.1.5",
|
|
44
39
|
"omit-deep": "^0.3.0",
|
|
45
40
|
"ora": "^8.2.0",
|
|
46
41
|
"outmatch": "^1.0.0",
|
|
47
|
-
"semver": "^7.7.2"
|
|
48
|
-
"sprintf-js": "^1.1.3",
|
|
49
|
-
"yargs": "^18.0.0"
|
|
42
|
+
"semver": "^7.7.2"
|
|
50
43
|
},
|
|
51
44
|
"devDependencies": {
|
|
45
|
+
"chai": "^6.2.1",
|
|
52
46
|
"clean-jsdoc-theme": "^4.3.0",
|
|
53
47
|
"docdash": "^2.0.2"
|
|
54
48
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
import Base from '../class/base.js'
|
|
3
|
+
|
|
4
|
+
function makeMockApp ({ mainNs = 'app-main', throwOnDataConfig = false } = {}) {
|
|
5
|
+
// small lodash-like helpers used by Base.loadConfig
|
|
6
|
+
const _ = {
|
|
7
|
+
get: (obj, path, defVal) => {
|
|
8
|
+
if (!obj) return defVal
|
|
9
|
+
const parts = String(path).split('.')
|
|
10
|
+
let cur = obj
|
|
11
|
+
for (const p of parts) {
|
|
12
|
+
if (cur == null) return defVal
|
|
13
|
+
cur = cur[p]
|
|
14
|
+
}
|
|
15
|
+
return cur === undefined ? defVal : cur
|
|
16
|
+
},
|
|
17
|
+
kebabCase: s => String(s).replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[\s_]+/g, '-').toLowerCase(),
|
|
18
|
+
keys: obj => obj ? Object.keys(obj) : [],
|
|
19
|
+
pick: (obj, keys) => {
|
|
20
|
+
const out = {}
|
|
21
|
+
if (!obj) return out
|
|
22
|
+
for (const k of keys) if (k in obj) out[k] = obj[k]
|
|
23
|
+
return out
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// simple defaultsDeep-ish helper suitable for these tests:
|
|
28
|
+
// later objects in args take precedence over earlier ones (shallow)
|
|
29
|
+
const defaultsDeep = (...objs) => Object.assign({}, ...objs.filter(Boolean))
|
|
30
|
+
|
|
31
|
+
// bajo helpers (file reads etc). readAllConfigs will be called twice by Base.loadConfig:
|
|
32
|
+
// - once for module dir config
|
|
33
|
+
// - once for data dir config (may throw)
|
|
34
|
+
let readAllCalls = 0
|
|
35
|
+
const readAllConfigs = async (path) => {
|
|
36
|
+
readAllCalls += 1
|
|
37
|
+
if (throwOnDataConfig && readAllCalls === 2) throw new Error('readAllConfigs data dir error')
|
|
38
|
+
// return a small config object to test merge/path logic
|
|
39
|
+
return { alpha: 'file', title: 'FromFile', other: 'ignore-me' }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
mainNs,
|
|
44
|
+
lib: { aneka: { defaultsDeep }, _ },
|
|
45
|
+
bajo: {
|
|
46
|
+
dir: { base: '/base', data: '/data' },
|
|
47
|
+
readAllConfigs,
|
|
48
|
+
readJson: async (p) => ({ name: 'bajo-foo', version: '1.2.3', description: 'pkg' }),
|
|
49
|
+
parseObject: (o) => o,
|
|
50
|
+
getModuleDir: (pkgName) => `/modules/${pkgName}`,
|
|
51
|
+
log: { trace: () => {} }
|
|
52
|
+
},
|
|
53
|
+
env: {},
|
|
54
|
+
argv: {}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
describe('Base.loadConfig', () => {
|
|
59
|
+
it('derives alias from pkgName starting with "bajo-" using kebabCase', async () => {
|
|
60
|
+
const app = makeMockApp()
|
|
61
|
+
const inst = new Base('bajo-MyPlugin', app)
|
|
62
|
+
// ensure namespace used by loadConfig
|
|
63
|
+
inst.ns = 'myplugin'
|
|
64
|
+
// set an initial config shape so defKeys isn't empty
|
|
65
|
+
inst.config = { alpha: 'default', title: 'Default' }
|
|
66
|
+
|
|
67
|
+
await inst.loadConfig()
|
|
68
|
+
|
|
69
|
+
// alias is stored on the constructor
|
|
70
|
+
expect(inst.constructor.alias).to.equal('my-plugin')
|
|
71
|
+
// dir pkg should be set according to mainNs mismatch
|
|
72
|
+
expect(inst.dir.pkg).to.equal('/modules/bajo-MyPlugin')
|
|
73
|
+
// config should keep keys only from defKeys (alpha & title), parseObject ran (no throw)
|
|
74
|
+
expect(Object.keys(inst.config)).to.include('alpha')
|
|
75
|
+
expect(Object.keys(inst.config)).to.include('title')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('when ns === app.mainNs uses app.mainNs as alias and sets title to alias', async () => {
|
|
79
|
+
const app = makeMockApp({ mainNs: 'mainns' })
|
|
80
|
+
const inst = new Base('bajo-mainpkg', app)
|
|
81
|
+
inst.ns = 'mainns'
|
|
82
|
+
inst.config = { title: undefined } // start with no title
|
|
83
|
+
|
|
84
|
+
await inst.loadConfig()
|
|
85
|
+
|
|
86
|
+
expect(inst.constructor.alias).to.equal('mainns')
|
|
87
|
+
// title should be set to alias when ns is mainNs
|
|
88
|
+
expect(inst.title).to.equal(inst.constructor.alias)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('continues when readAllConfigs for data dir throws (tolerant behavior)', async () => {
|
|
92
|
+
const app = makeMockApp({ throwOnDataConfig: true })
|
|
93
|
+
const inst = new Base('bajo-throwtest', app)
|
|
94
|
+
inst.ns = 'throwtest'
|
|
95
|
+
inst.config = { alpha: 'start' }
|
|
96
|
+
|
|
97
|
+
// should not throw even if second readAllConfigs throws
|
|
98
|
+
let threw = false
|
|
99
|
+
try {
|
|
100
|
+
await inst.loadConfig()
|
|
101
|
+
} catch (err) {
|
|
102
|
+
threw = true
|
|
103
|
+
}
|
|
104
|
+
expect(threw).to.equal(false)
|
|
105
|
+
// config should still be an object and title present (or undefined but not crash)
|
|
106
|
+
expect(inst.config).to.be.an('object')
|
|
107
|
+
})
|
|
108
|
+
})
|
package/wiki/CHANGES.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Changes
|
|
2
|
+
|
|
3
|
+
## 2026-01-16
|
|
4
|
+
|
|
5
|
+
- [2.2.1] Bug fix on multiple appearance of loaded plugins info
|
|
6
|
+
- [2.2.1] Bug fix on ```app.lib.parseObject()``` wrapper
|
|
7
|
+
|
|
8
|
+
## 2026-01-11
|
|
9
|
+
|
|
10
|
+
- [2.2.0] Simplify numerous things by putting most of static properties back as normal class properties
|
|
11
|
+
|
|
12
|
+
## 2025-12-29
|
|
13
|
+
|
|
14
|
+
- [2.2.0] Add ```this.selfBind()``` to class ```Plugin```
|
|
15
|
+
|
|
16
|
+
## 2025-12-27
|
|
17
|
+
|
|
18
|
+
- [2.2.0] Add some translations
|
|
19
|
+
|
|
20
|
+
## 2025-12-27
|
|
21
|
+
|
|
22
|
+
- [2.2.0] Add config object ```this.config.runtime``` to adjust some runtime settings
|
|
23
|
+
|
|
24
|
+
## 2025-12-24
|
|
25
|
+
|
|
26
|
+
- [2.2.0] Pass ```true``` to ```this.app.exit()``` to exit abruptly. Defaults to ```SIGINT```
|
|
27
|
+
- [2.2.0] Add ```detailsMessage``` to ```Err``` class if error object has ```details``` in payload
|
|
28
|
+
- [2.2.0] Upgrade ```aneka@0.10.0```
|
|
29
|
+
- [2.2.0] Bugfix: program arguments should not parsed as object
|
|
30
|
+
|
|
31
|
+
## 2025-12-21
|
|
32
|
+
|
|
33
|
+
- [2.2.0] ```runHook()``` now accept both ```alias``` & ```ns``` prefixed name
|
|
34
|
+
- [2.2.0] In case of unknown plugin or plugin isn't loaded, ```runHook``` simply exit silently
|
|
35
|
+
- [2.2.0] ```this.app.pluginClass``` is now ```this.app.baseClass``` and all containing class definition keys are pascal cased to match with their constructor names
|
|
36
|
+
|
|
37
|
+
## 2025-12-20
|
|
38
|
+
|
|
39
|
+
- [2.2.0] Removing dynamically attached methods because its problematic and leads to confusion
|
|
40
|
+
|
|
41
|
+
## 2025-12-19
|
|
42
|
+
|
|
43
|
+
- [2.2.0] Upgrade to ```aneka@0.9.0```
|
|
44
|
+
|
|
45
|
+
## 2025-12-13
|
|
46
|
+
|
|
47
|
+
- [2.2.0] Add ```app.lib.formatText()```
|
|
48
|
+
- [2.2.0] Move most bajo methods that doesn't relate to Bajo to app.lib functions
|
|
49
|
+
|
|
50
|
+
## 2025-12-11
|
|
51
|
+
|
|
52
|
+
- [2.1.1] Upgrade to ```aneka@0.5.0```
|
|
53
|
+
|
|
54
|
+
## 2025-12-09
|
|
55
|
+
|
|
56
|
+
- [2.1.1] Upgrade to ```aneka@0.2.3```
|
|
57
|
+
- [2.1.1] Some organizatory file location changes
|
|
58
|
+
- [2.1.1] Typo on class ```Tools```
|
|
59
|
+
|
|
60
|
+
## 2025-12-05
|
|
61
|
+
|
|
62
|
+
- [2.1.1] Upgrade to ```aneka@0.2.1```
|
|
63
|
+
- [2.1.1] New class ```Tools```, serves as anchestor for ```Err``` & ```Print```
|
|
64
|
+
|
|
65
|
+
## 2025-12-03
|
|
66
|
+
|
|
67
|
+
- [2.1.1] Add method ```getPkgInfo()``` to plugins main class.
|
|
68
|
+
- [2.1.1] Now you can put your plugins either in ```{dataDir}/config/.plugins``` or directly as an array in your app ```package.json``` under the ```bajo.plugins``` tree. The later takes precedence.
|
package/wiki/CONFIG.md
CHANGED
|
File without changes
|
package/wiki/CONTRIBUTING.md
CHANGED
|
File without changes
|
package/wiki/DEV_GUIDE.md
CHANGED
|
File without changes
|
package/wiki/ECOSYSTEM.md
CHANGED
|
File without changes
|
package/wiki/GETTING-STARTED.md
CHANGED
|
@@ -139,7 +139,7 @@ This file is the main plugin factory. It gets created automatically if it's not
|
|
|
139
139
|
async function factory (pkgName) {
|
|
140
140
|
const me = this
|
|
141
141
|
|
|
142
|
-
return class Main extends this.app.
|
|
142
|
+
return class Main extends this.app.baseClass.Base {
|
|
143
143
|
constructor () {
|
|
144
144
|
super(pkgName, me.app)
|
|
145
145
|
this.config = {}
|
package/wiki/USER-GUIDE.md
CHANGED
|
File without changes
|
package/lib/current-loc.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import resolvePath from './resolve-path.js'
|
|
3
|
-
import { fileURLToPath } from 'url'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Get current directory & file. An attempt to brings back the old ```__dirname``` and ```__filename```
|
|
7
|
-
* to the ES6 era.
|
|
8
|
-
*
|
|
9
|
-
* Returns object with the following keys:
|
|
10
|
-
* - ```__dirname``` (aliases to ```dir```) - current directory name
|
|
11
|
-
* - ```__filename``` (aliases to ```file```) - current file path
|
|
12
|
-
*
|
|
13
|
-
* Example:
|
|
14
|
-
* ```javascript
|
|
15
|
-
* const { importModule } = this.app.bajo
|
|
16
|
-
* const currentLoc = await importModule('bajo:/lib/current-loc.js')
|
|
17
|
-
*
|
|
18
|
-
* const { __dirname, __filename } = currentLoc(import.meta)
|
|
19
|
-
* console.log(__dirname, __filename)
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* @method
|
|
23
|
-
* @memberof module:Lib
|
|
24
|
-
* @param {Object} metaImport - ```import.meta``` object
|
|
25
|
-
* @returns {Object}
|
|
26
|
-
*/
|
|
27
|
-
const currentLoc = (metaImport) => {
|
|
28
|
-
const file = resolvePath(fileURLToPath(metaImport.url))
|
|
29
|
-
const dir = path.dirname(file)
|
|
30
|
-
return { dir, file, __dirname: dir, __filename: file }
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default currentLoc
|
package/lib/parse-args-argv.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import yargs from 'yargs'
|
|
2
|
-
import { Parser } from 'yargs/helpers'
|
|
3
|
-
import { unflatten } from 'flat'
|
|
4
|
-
import dotenvParseVariables from 'dotenv-parse-variables'
|
|
5
|
-
import lodash from 'lodash'
|
|
6
|
-
import fs from 'fs-extra'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
|
|
9
|
-
const { find, each, set, camelCase, forOwn } = lodash
|
|
10
|
-
const delimiter = '-'
|
|
11
|
-
const splitter = ':'
|
|
12
|
-
|
|
13
|
-
const parseItem = (data, delimiter) => {
|
|
14
|
-
return unflatten(data, {
|
|
15
|
-
delimiter,
|
|
16
|
-
safe: true,
|
|
17
|
-
overwrite: true
|
|
18
|
-
})
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function parseWithParser () {
|
|
22
|
-
return Parser(process.argv.slice(2), {
|
|
23
|
-
configuration: {
|
|
24
|
-
'camel-case-expansion': false
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function parseWithYargs () {
|
|
30
|
-
const pkg = fs.readJSONSync(`${this.dir}/package.json`)
|
|
31
|
-
let name = `node ${pkg.main}`
|
|
32
|
-
if (pkg.bin) name = path.basename(pkg.bin, '.js')
|
|
33
|
-
const cli = yargs(process.argv.slice(2))
|
|
34
|
-
.usage('Usage: $0 [args...]')
|
|
35
|
-
.scriptName(name)
|
|
36
|
-
.positional('args', {
|
|
37
|
-
describe: 'Optional one or more arguments'
|
|
38
|
-
})
|
|
39
|
-
.parserConfiguration({
|
|
40
|
-
'camel-case-expansion': false
|
|
41
|
-
})
|
|
42
|
-
.version(pkg.version).alias('version', 'v')
|
|
43
|
-
.help().alias('help', 'h')
|
|
44
|
-
.alias('applet', 'a')
|
|
45
|
-
if (pkg.homepage) cli.epilog(`For more information please visit ${pkg.homepage}`)
|
|
46
|
-
return cli.argv
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Parse program arguments (args) & options (argv). See {@link App#args|args} & {@link App#argv|argv} for examples
|
|
51
|
-
*
|
|
52
|
-
* @method
|
|
53
|
-
* @async
|
|
54
|
-
* @memberof module:Lib
|
|
55
|
-
* @param {boolean} [useParser] - If ```true```, skip {@link https://github.com/yargs/yargs|yargs}
|
|
56
|
-
* @returns {{args: Array, argv: Object}} An object containing ```args``` and ```argv```
|
|
57
|
-
* @see App#args
|
|
58
|
-
* @see App#argv
|
|
59
|
-
*/
|
|
60
|
-
async function parseArgsArgv (useParser) {
|
|
61
|
-
if (!useParser) useParser = find(process.argv, a => a.startsWith('--spawn'))
|
|
62
|
-
let argv = useParser ? await parseWithParser.call(this) : await parseWithYargs.call(this)
|
|
63
|
-
const args = argv._
|
|
64
|
-
delete argv._
|
|
65
|
-
delete argv.$0
|
|
66
|
-
argv = dotenvParseVariables(argv)
|
|
67
|
-
const all = { _: {} }
|
|
68
|
-
each(argv, (v, k) => {
|
|
69
|
-
const parts = k.split(splitter)
|
|
70
|
-
if (!parts[1]) all._[parts[0]] = v
|
|
71
|
-
else set(all, `${camelCase(parts[0])}.${parts[1]}`, v)
|
|
72
|
-
})
|
|
73
|
-
const result = {}
|
|
74
|
-
forOwn(all, (v, k) => {
|
|
75
|
-
result[k] = parseItem(v, delimiter)
|
|
76
|
-
})
|
|
77
|
-
return { args, argv: this.bajo.parseObject(result, { parseValue: true }) }
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export default parseArgsArgv
|
package/lib/parse-env.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import dotenvParseVariables from 'dotenv-parse-variables'
|
|
2
|
-
import { unflatten } from 'flat'
|
|
3
|
-
import dotEnv from 'dotenv'
|
|
4
|
-
import lodash from 'lodash'
|
|
5
|
-
|
|
6
|
-
const { each, set, camelCase, forOwn } = lodash
|
|
7
|
-
const parse = (data, delimiter) => {
|
|
8
|
-
return unflatten(data, {
|
|
9
|
-
delimiter,
|
|
10
|
-
safe: true,
|
|
11
|
-
overwrite: true,
|
|
12
|
-
transformKey: k => {
|
|
13
|
-
return camelCase(k.toLowerCase())
|
|
14
|
-
}
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const delimiter = '__'
|
|
19
|
-
const splitter = '.'
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Parse environment variables. See {@link App#envVars|envVars} for examples
|
|
23
|
-
*
|
|
24
|
-
* @method
|
|
25
|
-
* @memberof module:Lib
|
|
26
|
-
* @returns {Object}
|
|
27
|
-
* @see App#envVars
|
|
28
|
-
*/
|
|
29
|
-
function parseEnv () {
|
|
30
|
-
let env
|
|
31
|
-
try {
|
|
32
|
-
env = dotEnv.config({ quiet: true })
|
|
33
|
-
} catch (err) {
|
|
34
|
-
}
|
|
35
|
-
env = dotenvParseVariables(process.env, { assignToProcessEnv: false })
|
|
36
|
-
const all = { _: {} }
|
|
37
|
-
each(env, (v, k) => {
|
|
38
|
-
const parts = k.split(splitter)
|
|
39
|
-
if (!parts[1]) all._[parts[0]] = v
|
|
40
|
-
else set(all, `${camelCase(parts[0])}.${parts[1]}`, v)
|
|
41
|
-
})
|
|
42
|
-
const result = {}
|
|
43
|
-
forOwn(all, (v, k) => {
|
|
44
|
-
result[k] = parse(v, delimiter)
|
|
45
|
-
})
|
|
46
|
-
if (result._.lang) result._.lang = result._.lang.split('.')[0].replaceAll('_', '-')
|
|
47
|
-
return this.bajo.parseObject(result, { parseValue: true })
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default parseEnv
|
package/lib/resolve-path.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import { fileURLToPath } from 'url'
|
|
3
|
-
import os from 'os'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Resolve file name to filesystem's path. Windows path separator ```\```
|
|
7
|
-
* is normalized to Unix's ```/```
|
|
8
|
-
*
|
|
9
|
-
* @memberof module:Lib
|
|
10
|
-
* @param {string} file - File to resolve
|
|
11
|
-
* @param {boolean} [asFileUrl=false] - Return as file URL format ```file:///<name>```
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
function resolvePath (item, asFileUrl) {
|
|
15
|
-
if (item.startsWith('file://')) item = fileURLToPath(item)
|
|
16
|
-
item = path.resolve(item)
|
|
17
|
-
if (os.platform() === 'win32') {
|
|
18
|
-
item = item.replace(/\\/g, '/')
|
|
19
|
-
}
|
|
20
|
-
if (asFileUrl) item = `file:///${item}`
|
|
21
|
-
return item
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default resolvePath
|