waibu 2.16.2 → 2.18.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/extend/bajo/intl/en-US.json +1 -1
- package/extend/bajo/intl/id.json +1 -1
- package/index.js +23 -10
- package/lib/handle-not-found.js +1 -2
- package/lib/web-app.js +1 -6
- package/lib/webapp-scope/handle-multipart-body.js +1 -2
- package/package.json +1 -1
- package/wiki/CHANGES.md +11 -0
- package/lib/webapp-scope/is-route-disabled.js +0 -33
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"bootApp%s": "Boot app: %s",
|
|
9
9
|
"cantParseXmlBodyWithout%s": "Can't parse XML body unless package '%s' is loaded first",
|
|
10
10
|
"routesL": "routes",
|
|
11
|
-
"routeDisabled%s
|
|
11
|
+
"routeDisabled%s": "Route '%s' is disabled",
|
|
12
12
|
"rerouted%s%s": "Rerouted %s -> %s",
|
|
13
13
|
"bootSubApp%s": "Boot sub app: %s",
|
|
14
14
|
"routeNotFound%s%s": "Route '%s (%s)' not found",
|
package/extend/bajo/intl/id.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"bootApp%s": "Jalankan aplikasi: %s",
|
|
9
9
|
"cantParseXmlBodyWithout%s": "Tidak bisa memparse bodi XML sebelum paket '%s' dimuat terlebih dahulu",
|
|
10
10
|
"routesL": "jalur",
|
|
11
|
-
"routeDisabled%s
|
|
11
|
+
"routeDisabled%s": "Jalur '%s' dimatikan",
|
|
12
12
|
"rerouted%s%s": "Jalur dipindahkan %s -> %s",
|
|
13
13
|
"bootSubApp%s": "Boot sub app: %s",
|
|
14
14
|
"routeNotFound%s%s": "Jalur '%s (%s)' tidak ditemukan",
|
package/index.js
CHANGED
|
@@ -110,7 +110,10 @@ async function factory (pkgName) {
|
|
|
110
110
|
lang: 'lang'
|
|
111
111
|
},
|
|
112
112
|
paramsCharMap: {},
|
|
113
|
-
|
|
113
|
+
route: {
|
|
114
|
+
print: true,
|
|
115
|
+
disabled: []
|
|
116
|
+
},
|
|
114
117
|
pageTitleFormat: '%s : %s',
|
|
115
118
|
siteInfo: {
|
|
116
119
|
title: 'My Website',
|
|
@@ -184,7 +187,7 @@ async function factory (pkgName) {
|
|
|
184
187
|
}
|
|
185
188
|
cfg.factory.genReqId = req => generateId()
|
|
186
189
|
cfg.factory.disableRequestLogging = true
|
|
187
|
-
cfg.factory.querystringParser = str => this.qs.parse(str)
|
|
190
|
+
cfg.factory.routerOptions.querystringParser = str => this.qs.parse(str)
|
|
188
191
|
|
|
189
192
|
this.instance = fastify(cfg.factory)
|
|
190
193
|
this.routes = this.routes || []
|
|
@@ -201,7 +204,7 @@ async function factory (pkgName) {
|
|
|
201
204
|
await handleHome.call(this)
|
|
202
205
|
await handleNotFound.call(this)
|
|
203
206
|
await this.instance.listen(cfg.server)
|
|
204
|
-
if (cfg.
|
|
207
|
+
if (cfg.route.print) printRoutes.call(this)
|
|
205
208
|
}
|
|
206
209
|
|
|
207
210
|
/**
|
|
@@ -391,10 +394,9 @@ async function factory (pkgName) {
|
|
|
391
394
|
* @returns {(Object|Array)} - Returns object if ```returnDir``` is ```true```, array of files otherwise
|
|
392
395
|
*/
|
|
393
396
|
getUploadedFiles = async (reqId, fileUrl = false, returnDir = false) => {
|
|
394
|
-
const { getPluginDataDir } = this.app.bajo
|
|
395
397
|
const { resolvePath } = this.app.lib.aneka
|
|
396
398
|
const { fastGlob } = this.app.lib
|
|
397
|
-
const dir = `${getPluginDataDir(this.ns)}/upload/${reqId}`
|
|
399
|
+
const dir = `${this.app.getPluginDataDir(this.ns)}/upload/${reqId}`
|
|
398
400
|
const result = await fastGlob(`${dir}/*`)
|
|
399
401
|
if (!fileUrl) return returnDir ? { dir, files: result } : result
|
|
400
402
|
const files = result.map(f => resolvePath(f, true))
|
|
@@ -468,16 +470,17 @@ async function factory (pkgName) {
|
|
|
468
470
|
* @returns {string}
|
|
469
471
|
*/
|
|
470
472
|
routePath = (name = '', options = {}) => {
|
|
471
|
-
const { getPlugin } = this.app.bajo
|
|
472
473
|
const { defaultsDeep } = this.app.lib.aneka
|
|
473
474
|
const { isEmpty, get, trimEnd, trimStart } = this.app.lib._
|
|
474
475
|
const { breakNsPath } = this.app.bajo
|
|
475
476
|
const { query = {}, ns = this.ns, params = {}, guessHost, defaults = {}, uriEncoded } = options
|
|
476
477
|
|
|
477
|
-
const plugin = getPlugin(ns)
|
|
478
|
+
const plugin = this.app.getPlugin(ns)
|
|
478
479
|
const cfg = plugin.config ?? {}
|
|
479
480
|
let info = {}
|
|
481
|
+
const neg = name[0] === '!'
|
|
480
482
|
if (name.startsWith('mailto:') || name.startsWith('tel:')) return name
|
|
483
|
+
if (neg) name = name.slice(1)
|
|
481
484
|
if (name.slice(0, 2) === ':/') name = ns + name
|
|
482
485
|
if (['%', '.', '/', '?', '#'].includes(name[0]) || name.slice(1, 2) === ':') info.path = name
|
|
483
486
|
else if (['~'].includes(name[0])) info.path = name.slice(1)
|
|
@@ -485,8 +488,8 @@ async function factory (pkgName) {
|
|
|
485
488
|
info = breakNsPath(name)
|
|
486
489
|
}
|
|
487
490
|
if (info.path.slice(0, 2) === './') info.path = info.path.slice(2)
|
|
488
|
-
if (this.routePathHandlers[info.subNs]) return this.routePathHandlers[info.subNs].handler(name, options)
|
|
489
|
-
if (info.path.includes('//')) return info.path
|
|
491
|
+
if (this.routePathHandlers[info.subNs]) return (neg ? '!' : '') + this.routePathHandlers[info.subNs].handler(name, options)
|
|
492
|
+
if (info.path.includes('//')) return (neg ? '!' : '') + info.path
|
|
490
493
|
|
|
491
494
|
info.path = info.path.split('/').map(p => {
|
|
492
495
|
if (!(p[0] === ':' || (p[0] === '{' && p[p.length - 1] === '}'))) return p
|
|
@@ -503,7 +506,7 @@ async function factory (pkgName) {
|
|
|
503
506
|
info.qs = defaultsDeep({}, query, info.qs)
|
|
504
507
|
if (!isEmpty(info.qs)) url += '?' + this.qs.stringify(info.qs)
|
|
505
508
|
if (!url.startsWith('http') && guessHost) url = `http://${this.config.server.host}:${this.config.server.port}/${trimStart(url, '/')}`
|
|
506
|
-
return url
|
|
509
|
+
return (neg ? '!' : '') + url
|
|
507
510
|
}
|
|
508
511
|
|
|
509
512
|
/**
|
|
@@ -605,6 +608,16 @@ async function factory (pkgName) {
|
|
|
605
608
|
if (isPlainObject(cfgValue) || isArray(cfgValue)) return defaultsDeep({}, reqValue, cfgValue, defValue)
|
|
606
609
|
return reqValue ?? cfgValue ?? defValue
|
|
607
610
|
}
|
|
611
|
+
|
|
612
|
+
isRouteDisabled = (path, warning = true) => {
|
|
613
|
+
const { outmatch } = this.app.lib
|
|
614
|
+
path = this.routePath(path)
|
|
615
|
+
const result = this.config.route.disabled.find(item => {
|
|
616
|
+
return outmatch(this.routePath(item))(path)
|
|
617
|
+
})
|
|
618
|
+
if (result && warning) this.log.warn('routeDisabled%s', path)
|
|
619
|
+
return result
|
|
620
|
+
}
|
|
608
621
|
}
|
|
609
622
|
|
|
610
623
|
return Waibu
|
package/lib/handle-not-found.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
export function writeHtml (req, reply, tpl, payload) {
|
|
2
|
-
const { getPluginFile } = this.app.bajo
|
|
3
2
|
const { fs } = this.app.lib
|
|
4
3
|
const { template } = this.app.lib._
|
|
5
4
|
reply.header('Content-Type', 'text/html')
|
|
6
5
|
reply.header('Content-Language', req.lang)
|
|
7
|
-
const file = getPluginFile(tpl)
|
|
6
|
+
const file = this.app.getPluginFile(tpl)
|
|
8
7
|
const content = fs.readFileSync(file, 'utf8')
|
|
9
8
|
const compiled = template(content)
|
|
10
9
|
return compiled(payload)
|
package/lib/web-app.js
CHANGED
|
@@ -8,7 +8,7 @@ export async function collect (glob = 'boot.js', baseNs) {
|
|
|
8
8
|
const { ns, alias, config } = this
|
|
9
9
|
const mod = await importModule(file, { asHandler: true })
|
|
10
10
|
mod.prefix = get(config, 'waibu.prefix', alias)
|
|
11
|
-
if (get(config, 'intl.detectors', []).includes('path')) mod.prefix =
|
|
11
|
+
if (get(config, 'intl.detectors', []).includes('path')) mod.prefix = `:lang${mod.prefix === '' ? '' : ('/' + mod.prefix)}`
|
|
12
12
|
mod.ns = ns
|
|
13
13
|
mod.alias = alias
|
|
14
14
|
mods.push(mod)
|
|
@@ -28,11 +28,6 @@ async function webApp () {
|
|
|
28
28
|
await runHook(`${this.ns}:beforeAppBoot`)
|
|
29
29
|
// build routes
|
|
30
30
|
for (const m of this.webApps) {
|
|
31
|
-
const disabled = this.app[m.ns].config.disabled
|
|
32
|
-
if (Array.isArray(disabled) && disabled.length === 1 && ['*', 'all'].includes(disabled[0])) {
|
|
33
|
-
this.log.warn('allRoutesConfigDisabled%s', m.ns)
|
|
34
|
-
continue
|
|
35
|
-
}
|
|
36
31
|
const plugin = this.app[m.ns]
|
|
37
32
|
await runHook(`${this.ns}.${m.ns}:beforeAppBoot`)
|
|
38
33
|
this.log.debug('bootApp%s', m.ns)
|
|
@@ -13,9 +13,8 @@ function normalizeValue (value) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async function onFileHandler () {
|
|
16
|
-
const { getPluginDataDir } = this.app.bajo
|
|
17
16
|
const { fs } = this.app.lib
|
|
18
|
-
const dir = `${getPluginDataDir('waibu')}/upload`
|
|
17
|
+
const dir = `${this.app.getPluginDataDir('waibu')}/upload`
|
|
19
18
|
return async function (part) {
|
|
20
19
|
// 'this' is the fastify context here
|
|
21
20
|
const filePath = `${dir}/${this.id}/${part.fieldname}@${part.filename}`
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-06-12
|
|
4
|
+
|
|
5
|
+
- [2.18.0] Necessary updates to ```bajo@2.18.0``` specs
|
|
6
|
+
|
|
7
|
+
## 2026-06-10
|
|
8
|
+
|
|
9
|
+
- [2.17.0] Add ```config.print```
|
|
10
|
+
- [2.17.0] Bug fix in ```factory.routeOptions```
|
|
11
|
+
- [2.17.0] Add support for inversed route in ```routePath()```
|
|
12
|
+
- [2.17.0] Disabled routes now handled directly by ```waibu```, not its web apps
|
|
13
|
+
|
|
3
14
|
## 2026-06-05
|
|
4
15
|
|
|
5
16
|
- [2.16.2] Bug fix in ```build-locals.js```
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
function santizeMethods (methods = '*') {
|
|
2
|
-
if (['*', 'all'].includes(methods)) methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
|
|
3
|
-
else methods = methods.split(',').map(s => s.trim())
|
|
4
|
-
return methods
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
async function isRouteDisabled (url, method, matchers = []) {
|
|
8
|
-
const { outmatch } = this.app.lib
|
|
9
|
-
const { isString, intersection, cloneDeep } = this.app.lib._
|
|
10
|
-
const items = []
|
|
11
|
-
for (let m of cloneDeep(matchers)) {
|
|
12
|
-
if (isString(m)) m = { path: m }
|
|
13
|
-
try {
|
|
14
|
-
m.path = this.app.waibu.routePath(m.path)
|
|
15
|
-
m.methods = santizeMethods(m.methods)
|
|
16
|
-
items.push(m)
|
|
17
|
-
} catch (err) {
|
|
18
|
-
throw this.error(`${m.path}: ${err.message}`)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const matcher = items.find(i => {
|
|
22
|
-
const isMatch = outmatch(i.path)
|
|
23
|
-
return isMatch(url)
|
|
24
|
-
})
|
|
25
|
-
if (!matcher) return false
|
|
26
|
-
if (Array.isArray(method)) {
|
|
27
|
-
const result = intersection(method, matcher.methods)
|
|
28
|
-
return result.length > 0
|
|
29
|
-
}
|
|
30
|
-
return matcher.methods.includes(method)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default isRouteDisabled
|