bajo 1.1.3 → 1.1.4

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.
@@ -131,7 +131,7 @@
131
131
  "file": "File",
132
132
  "applet": "Applet",
133
133
  "unsupported%s%s": "Unsupported %s '%s'",
134
- "error%": "Error: %s",
134
+ "error%s": "Error: %s",
135
135
  "savedAs%%": "%s saved as '%s'",
136
136
  "loaded%s": "Loaded %s",
137
137
  "production": "production",
@@ -155,6 +155,6 @@
155
155
  "adminArea": "Admin Area",
156
156
  "instanceCreatedOnConn%s%s": "Instance '%s' created on connection '%s'",
157
157
  "fileNotModuleHandler%s": "File '%s' is NOT a module handler",
158
- "error%s": "Error: %s",
158
+ "error%s%s%s": "%s error (%s): %s",
159
159
  "invalid%s%s": "Invalid %s (%s)"
160
160
  }
package/bajo/intl/id.json CHANGED
@@ -131,7 +131,7 @@
131
131
  "file": "Berkas",
132
132
  "applet": "Applet",
133
133
  "unsupported%s%s": "%s '%s' tidak didukung",
134
- "error%": "Kesalahan: %s",
134
+ "error%s": "Kesalahan: %s",
135
135
  "savedAs%%": "%s disimpan sbg '%s'",
136
136
  "loaded%s": "%s termuat",
137
137
  "production": "produksi",
@@ -155,6 +155,6 @@
155
155
  "adminArea": "Area Admin",
156
156
  "instanceCreatedOnConn%s%s": "Instance '%s' telah dibuat pada koneksi '%s'",
157
157
  "fileNotModuleHandler%s": "Berkas '%s' BUKAN merupakan module handler",
158
- "error%s": "Kesalahan: %s",
158
+ "error%s%s%s": "Kesalahan %s (%s): %s",
159
159
  "invalid%s%s": "%s tidak valid (%s)"
160
160
  }
package/boot/class/app.js CHANGED
@@ -60,7 +60,7 @@ class App {
60
60
  // boot complete
61
61
  const elapsed = new Date() - bajo.runAt
62
62
  bajo.log.info('bootCompleted%s', bajo.secToHms(elapsed, true))
63
- await bajo.runHook('bajo:bootComplete')
63
+ await bajo.runHook('bajo:afterBootComplete')
64
64
  if (bajo.applet) await runAsApplet.call(bajo)
65
65
  }
66
66
  }
@@ -73,4 +73,5 @@ export async function buildExtConfig () {
73
73
  this.initPrint()
74
74
  this.initLog()
75
75
  this.log.debug('configHandlers%s', this.join(exts))
76
+ this.config = this.parseObject(this.config, { parseValue: true })
76
77
  }
@@ -113,14 +113,14 @@ class BajoCore extends Plugin {
113
113
 
114
114
  breakNsPath = (item = '', defaultNs = 'bajo', checkNs = true) => {
115
115
  let [ns, ...path] = item.split(':')
116
+ const fullNs = ns
116
117
  let subNs
117
118
  let subSubNs
118
119
  path = path.join(':')
119
- if (path.startsWith('//')) return { ns: undefined, path: item } // for: http:// etc
120
- if (isEmpty(path)) {
121
- path = ns
122
- ns = defaultNs
120
+ if (path.startsWith('//')) {
121
+ return { path: item } // for: http:// etc
123
122
  }
123
+
124
124
  [ns, subNs, subSubNs] = ns.split('.')
125
125
  if (checkNs) {
126
126
  if (!this.app[ns]) {
@@ -133,7 +133,7 @@ class BajoCore extends Plugin {
133
133
  let qs
134
134
  [path, qs] = path.split('?')
135
135
  qs = querystring.parse(qs) ?? {}
136
- return { ns, path, subNs, subSubNs, qs, fullPath }
136
+ return { ns, path, subNs, subSubNs, qs, fullPath, fullNs }
137
137
  }
138
138
 
139
139
  buildCollections = async (options = {}) => {
@@ -189,8 +189,12 @@ class BajoCore extends Plugin {
189
189
  const applet = find(bajo.applets, a => (a.ns === ns || a.alias === ns))
190
190
  if (applet) result = await bajo.runApplet(applet, path, ...args)
191
191
  } else {
192
- const method = bajo.getMethod(item)
193
- if (method) result = await method(...args)
192
+ const [ns, method, ...params] = item.split(':')
193
+ const fn = bajo.getMethod(`${ns}:${method}`)
194
+ if (fn) {
195
+ if (params.length > 0) args.unshift(...params)
196
+ result = await fn(...args)
197
+ }
194
198
  }
195
199
  } else if (isFunction(item)) {
196
200
  result = await item.call(scope, ...args)
@@ -688,7 +692,6 @@ class BajoCore extends Plugin {
688
692
  if (isEmpty(fns)) return
689
693
  fns = orderBy(fns, ['level'])
690
694
  const results = []
691
- const removed = []
692
695
  for (const i in fns) {
693
696
  const fn = fns[i]
694
697
  const scope = this.app[fn.src]
@@ -697,11 +700,8 @@ class BajoCore extends Plugin {
697
700
  hook: hookName,
698
701
  resp: res
699
702
  })
700
- if (path.startsWith('once')) removed.push(i)
701
703
  if (this.config.log.traceHook) scope.log.trace('hookExecuted%s', hookName)
702
704
  }
703
- if (removed.length > 0) pullAt(this.app.bajo.hooks, removed)
704
-
705
705
  return results
706
706
  }
707
707
 
@@ -13,7 +13,7 @@ class BajoPlugin extends Plugin {
13
13
  }
14
14
 
15
15
  loadConfig = async () => {
16
- const { log, getModuleDir, readJson, defaultsDeep } = this.app.bajo
16
+ const { log, getModuleDir, readJson, defaultsDeep, parseObject } = this.app.bajo
17
17
  log.trace('- %s', this.name)
18
18
  const dir = this.name === this.app.bajo.mainNs ? (`${this.app.bajo.dir.base}/${this.app.bajo.mainNs}`) : getModuleDir(this.pkgName)
19
19
  let cfg = await readAllConfigs.call(this.app, `${dir}/plugin/config`)
@@ -46,7 +46,7 @@ class BajoPlugin extends Plugin {
46
46
  this.dependencies = this.dependencies ?? []
47
47
  const depFile = `${dir}/plugin/.dependencies`
48
48
  if (fs.existsSync(depFile)) this.dependencies = without(fs.readFileSync(depFile, 'utf8').split('\n').map(item => trim(item)), '')
49
- this.config = omit(cfg, ['title', 'dependencies'])
49
+ this.config = parseObject(omit(cfg, ['title', 'dependencies']), { parseValue: true })
50
50
  }
51
51
 
52
52
  _onoff = async (item, ...args) => {
package/boot/class/log.js CHANGED
@@ -5,6 +5,18 @@ import logLevels from '../lib/log-levels.js'
5
5
 
6
6
  const { isEmpty, without, merge, upperFirst } = lodash
7
7
 
8
+ export function isIgnored (level) {
9
+ const { filter, isArray } = this.lib._
10
+ let ignore = this.app.bajo.config.log.ignore ?? []
11
+ if (!isArray(ignore)) ignore = [ignore]
12
+ const items = filter(ignore, i => {
13
+ const [ns, lvl] = i.split(':')
14
+ if (lvl) return ns === this.name && lvl === level
15
+ return ns === this.name
16
+ })
17
+ return items.length > 0
18
+ }
19
+
8
20
  class Log {
9
21
  constructor (plugin) {
10
22
  this.plugin = plugin
@@ -23,6 +35,10 @@ class Log {
23
35
  return this.plugin.app[this.bajoLog] && this.plugin.app[this.bajoLog].logger
24
36
  }
25
37
 
38
+ isIgnored = level => {
39
+ return isIgnored.call(this.plugin, level)
40
+ }
41
+
26
42
  child = () => {
27
43
  if (this.isExtLogger()) return this.plugin.app[this.bajoLog].logger.child()
28
44
  return this.plugin.app
@@ -53,7 +69,7 @@ class Log {
53
69
  text = `[${dayjs(dt).utc(true).format(this.format)}] ${upperFirst(level)}: ${msg}`
54
70
  if (!isEmpty(data)) text += '\n' + JSON.stringify(data)
55
71
  }
56
- console.log(text)
72
+ if (!this.isIgnored(level)) console.log(text)
57
73
  }
58
74
  }
59
75
  }
@@ -9,6 +9,19 @@ import outmatch from 'outmatch'
9
9
  import dayjs from '../lib/dayjs.js'
10
10
  import fs from 'fs-extra'
11
11
 
12
+ function outmatchNs (source, pattern) {
13
+ const { breakNsPath } = this.app.bajo
14
+ const [src, subSrc] = source.split(':')
15
+ if (!subSrc) return pattern === src
16
+ try {
17
+ const { fullNs, path } = breakNsPath(pattern)
18
+ const isMatch = outmatch(path)
19
+ return src === fullNs && isMatch(subSrc)
20
+ } catch (err) {
21
+ return false
22
+ }
23
+ }
24
+
12
25
  const lib = {
13
26
  _: lodash,
14
27
  fs,
@@ -27,6 +40,7 @@ class Plugin {
27
40
  this.app = app
28
41
  this.config = {}
29
42
  this.lib = lib
43
+ this.lib.outmatchNs = outmatchNs.bind(this)
30
44
  this.exitHandler = undefined
31
45
  }
32
46
 
@@ -3,11 +3,12 @@ import path from 'path'
3
3
  import lodash from 'lodash'
4
4
  import resolvePath from './resolve-path.js'
5
5
 
6
- const { camelCase, isFunction, isPlainObject, forOwn } = lodash
6
+ const { camelCase, isFunction } = lodash
7
7
 
8
8
  export default async function (dir, pkg = 'bajo') {
9
9
  dir = resolvePath(dir)
10
10
  const files = await fastGlob([`!${dir}/**/_*.{js,json}`, `${dir}/**/*.{js,json}`])
11
+ const me = this
11
12
  for (const f of files) {
12
13
  const ext = path.extname(f)
13
14
  const base = f.replace(dir, '').replace(ext, '')
@@ -16,13 +17,15 @@ export default async function (dir, pkg = 'bajo') {
16
17
  if (ext === '.json') mod = this.app.bajo.readJson(f)
17
18
  else mod = await this.app.bajo.importModule(f)
18
19
  if (isFunction(mod)) {
19
- mod = mod.bind(this)
20
- } else if (isPlainObject(mod)) {
21
- if (!mod.exec) { // mod.exec offer unbind, nacked function people can bind to anything else later
22
- forOwn(mod, (v, k) => {
23
- if (isFunction(v)) mod[k] = v.bind(this)
24
- })
25
- }
20
+ const fn = mod.bind(this)
21
+ if (mod.constructor.name === 'AsyncFunction') {
22
+ mod = async (...args) => {
23
+ await me.app.bajo.runHook(`${me.name}.${name}:beforeExec`, ...args)
24
+ const result = await fn(...args)
25
+ await me.app.bajo.runHook(`${me.name}.${name}:afterExec`, result, ...args)
26
+ return result
27
+ }
28
+ } else mod = fn
26
29
  }
27
30
  this[name] = mod
28
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bajo",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "A framework to build a giant monstrous app rapidly",
5
5
  "main": "boot/index.js",
6
6
  "scripts": {