waibu 1.0.0 → 1.0.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.
Files changed (44) hide show
  1. package/README.md +5 -5
  2. package/bajo/.alias +1 -0
  3. package/bajo/config.json +3 -7
  4. package/bajo/hook/on-request.js +4 -1
  5. package/bajo/hook/on-response.js +1 -1
  6. package/bajo/hook/on-route.js +1 -1
  7. package/bajo/init.js +3 -0
  8. package/bajo/logo.png +0 -0
  9. package/bajo/method/escape-chars.js +6 -0
  10. package/bajo/method/escape.js +11 -0
  11. package/bajo/method/fetch.js +19 -0
  12. package/bajo/method/get-plugin-by-prefix.js +13 -0
  13. package/bajo/method/get-plugin-prefix.js +7 -0
  14. package/bajo/method/not-found.js +1 -1
  15. package/bajo/method/qs.js +17 -0
  16. package/bajo/method/route-dir.js +5 -3
  17. package/bajo/method/route-path.js +22 -17
  18. package/bajo/method/unescape.js +12 -0
  19. package/bajo/start.js +7 -3
  20. package/lib/app-hook.js +2 -4
  21. package/lib/app.js +12 -4
  22. package/lib/collect-route-path-handlers.js +15 -0
  23. package/lib/handle-forward.js +8 -5
  24. package/lib/handle-redirect.js +4 -3
  25. package/lib/home.js +2 -2
  26. package/lib/webapp-scope/attach-i18n.js +15 -8
  27. package/lib/webapp-scope/error-handler.js +4 -7
  28. package/lib/webapp-scope/is-route-disabled.js +1 -1
  29. package/{bajo/method → lib/webapp-scope}/merge-route-hooks.js +3 -3
  30. package/lib/webapp-scope/rerouted-path.js +1 -1
  31. package/lib/webapp-scope/route-hook.js +3 -3
  32. package/package.json +19 -17
  33. package/bajo/hook/bajoI18N@before-init.js +0 -6
  34. package/bajo/method/get-params.js +0 -18
  35. package/bajo/method/method-map.js +0 -9
  36. package/bajo/method/record/create.js +0 -13
  37. package/bajo/method/record/find-one.js +0 -19
  38. package/bajo/method/record/find.js +0 -20
  39. package/bajo/method/record/get.js +0 -14
  40. package/bajo/method/record/remove.js +0 -10
  41. package/bajo/method/record/update.js +0 -13
  42. package/bajo/method/stat/aggregate.js +0 -13
  43. package/bajo/method/stat/histogram.js +0 -13
  44. package/lib/prep-crud.js +0 -17
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # wakatobi
1
+ # waibu
2
2
 
3
- Plugin name: **wakatobi**, alias: **wktb**
3
+ Plugin name: **waibu**, alias: **waibu**
4
4
 
5
- ![GitHub package.json version](https://img.shields.io/github/package-json/v/ardhi/wakatobi) ![NPM Version](https://img.shields.io/npm/v/wakatobi)
5
+ ![GitHub package.json version](https://img.shields.io/github/package-json/v/ardhi/waibu) ![NPM Version](https://img.shields.io/npm/v/waibu)
6
6
 
7
7
  > <br />**Attention**: I do NOT accept any pull request at the moment, thanks!<br /><br />
8
8
 
@@ -13,10 +13,10 @@ Plugin name: **wakatobi**, alias: **wktb**
13
13
  Goto your ```<bajo-base-dir>``` and type:
14
14
 
15
15
  ```bash
16
- $ npm install wakatobi
16
+ $ npm install waibu
17
17
  ```
18
18
 
19
- Now open your ```<bajo-data-dir>/config/.plugins``` and put ```wakatobi``` in it
19
+ Now open your ```<bajo-data-dir>/config/.plugins``` and put ```waibu``` in it
20
20
 
21
21
  ## License
22
22
 
package/bajo/.alias ADDED
@@ -0,0 +1 @@
1
+ w
package/bajo/config.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
- "alias": "wktb",
3
2
  "server": {
4
3
  "host": "localhost",
5
4
  "port": 7777
6
5
  },
7
6
  "factory": {
8
- "trustProxy": true
7
+ "trustProxy": true,
8
+ "bodyLimit": 10485760
9
9
  },
10
+ "prefixVirtual": "~",
10
11
  "qsKey": {
11
12
  "bbox": "bbox",
12
13
  "bboxLatField": "bboxLatField",
@@ -21,11 +22,6 @@
21
22
  "lang": "lang"
22
23
  },
23
24
  "paramsCharMap": {},
24
- "dbColl": {
25
- "dataOnly": false,
26
- "count": false,
27
- "patchEnabled": false
28
- },
29
25
  "logRoutes": false,
30
26
  "siteInfo": {
31
27
  "title": "My Website",
@@ -1,7 +1,10 @@
1
1
  const onRequest = {
2
2
  level: 5,
3
- handler: async function onRequest (ctx, req, reply) {
3
+ handler: async function onRequest (req, reply) {
4
+ const { get } = this.app.bajo.lib._
5
+
4
6
  req.site = this.config.siteInfo
7
+ req.ns = get(reply.request, 'routeOptions.config.ns')
5
8
  let msg = '< %s:%s from IP %s'
6
9
  if (req.headers['content-length']) msg += ', content length: %s'
7
10
  this.log.info(msg, req.method, req.url, this.getIp(req), req.headers['content-length'])
@@ -1,6 +1,6 @@
1
1
  const onResponse = {
2
2
  level: 5,
3
- handler: async function onResponse (ctx, req, reply) {
3
+ handler: async function onResponse (req, reply) {
4
4
  let method = 'info'
5
5
  if (reply.statusCode >= 300 && reply.statusCode < 400) method = 'warn'
6
6
  else if (reply.statusCode >= 400) method = 'error'
@@ -1,6 +1,6 @@
1
1
  const onRoute = {
2
2
  level: 5,
3
- handler: async function (ctx, opts) {
3
+ handler: async function (opts) {
4
4
  this.routes.push(opts)
5
5
  }
6
6
  }
package/bajo/init.js CHANGED
@@ -1,5 +1,8 @@
1
+ import collectRoutePathHandlers from '../lib/collect-route-path-handlers.js'
2
+
1
3
  async function init () {
2
4
  if (this.config.home === '/') this.config.home = false
5
+ await collectRoutePathHandlers.call(this)
3
6
  }
4
7
 
5
8
  export default init
package/bajo/logo.png ADDED
Binary file
@@ -0,0 +1,6 @@
1
+ export default {
2
+ '<': '&lt;',
3
+ '>': '&gt;',
4
+ '"': '&quot;',
5
+ "'": '&apos;'
6
+ }
@@ -0,0 +1,11 @@
1
+ import escapeChars from './escape-chars.js'
2
+
3
+ function escape (text) {
4
+ const { forOwn } = this.app.bajo.lib._
5
+ forOwn(escapeChars, (v, k) => {
6
+ text = text.replaceAll(k, v)
7
+ })
8
+ return text
9
+ }
10
+
11
+ export default escape
@@ -0,0 +1,19 @@
1
+ async function fetch (url, opts = {}, extra = {}) {
2
+ const { getPlugin } = this.app.bajo
3
+ getPlugin('bajoExtra')
4
+ const { fetch } = this.app.bajoExtra
5
+ extra.rawResponse = true
6
+
7
+ url = this.routePath(url, { guessHost: true })
8
+ const resp = await fetch(url, opts, extra)
9
+ const result = await resp.json()
10
+ if (!resp.ok) {
11
+ throw this.error(result.message, {
12
+ statusCode: resp.status,
13
+ success: false
14
+ })
15
+ }
16
+ return result
17
+ }
18
+
19
+ export default fetch
@@ -0,0 +1,13 @@
1
+ function getPluginByPrefix (prefix) {
2
+ const { get } = this.app.bajo.lib._
3
+ let plugin
4
+ for (const p of this.app.bajo.pluginNames) {
5
+ if (get(this, `app.${p}.config.waibu.prefix`) === prefix) {
6
+ plugin = this.app[p]
7
+ break
8
+ }
9
+ }
10
+ return plugin
11
+ }
12
+
13
+ export default getPluginByPrefix
@@ -0,0 +1,7 @@
1
+ function getPluginPrefix (base) {
2
+ const { get, trim } = this.app.bajo.lib._
3
+ const prefix = get(this, `app.${base}.config.waibu.prefix`, this.app[base].alias)
4
+ return trim(prefix, '/')
5
+ }
6
+
7
+ export default getPluginPrefix
@@ -1,5 +1,5 @@
1
1
  function notFound (name, options) {
2
- throw this.error('notfound', { path: name })
2
+ throw this.error('notFound', { path: name })
3
3
  }
4
4
 
5
5
  export default notFound
@@ -0,0 +1,17 @@
1
+ import queryString from 'query-string'
2
+
3
+ function parse (item) {
4
+ return queryString.parse(item, {
5
+ parseBooleans: true,
6
+ parseNumbers: true
7
+ })
8
+ }
9
+
10
+ const qs = {
11
+ parse,
12
+ parseUrl: queryString.parseUrl,
13
+ stringify: queryString.stringify,
14
+ stringifyUrl: queryString.stringifyUrl
15
+ }
16
+
17
+ export default qs
@@ -1,10 +1,12 @@
1
1
  function routeDir (ns, base) {
2
+ const { get } = this.app.bajo.lib._
2
3
  if (!base) base = ns
3
4
  const cfg = this.app[base].config
4
- const dir = cfg.prefix === '' ? '' : `/${cfg.prefix || this.app[base].alias}`
5
+ const prefix = get(cfg, 'waibu.prefix', this.app[base].alias)
6
+ const dir = prefix === '' ? '' : `/${prefix}`
5
7
  if (!ns) return dir
6
- if (ns === base || (ns === this.app.bajo.mainNs && cfg.mountAppAsRoot)) return dir
7
- return dir + '/' + this.app[ns].alias
8
+ if (ns === base || (ns === this.app.bajo.mainNs && cfg.mountMainAsRoot)) return dir
9
+ return dir + `/${get(this.app[ns].config, 'waibu.prefix', this.app[ns].alias)}`
8
10
  }
9
11
 
10
12
  export default routeDir
@@ -1,24 +1,29 @@
1
- import qs from 'querystring'
2
-
3
- function routePath (name, { query = {}, base = 'wakatobiMpa', params = {} } = {}) {
4
- // TODO: what if wakatobiMpa isn't loaded?
5
- const { defaultsDeep } = this.app.bajo
6
- const { isEmpty, get } = this.app.bajo.lib._
1
+ function routePath (name = '', { query = {}, base = 'waibuMpa', params = {}, guessHost } = {}) {
2
+ const { defaultsDeep, getPlugin } = this.app.bajo
3
+ const { isEmpty, get, trimEnd, trimStart } = this.app.bajo.lib._
7
4
  const { breakNsPath } = this.app.bajo
8
- const cfg = this.app[base].config ?? {}
9
- let ns
10
- let fullPath
11
- if (name.startsWith('/')) fullPath = name
12
- else [ns, fullPath] = breakNsPath(name)
13
- let [path, queryString] = fullPath.split('?')
14
- path = path.split('/').map(p => {
5
+
6
+ const plugin = getPlugin(base)
7
+ const cfg = plugin.config ?? {}
8
+ let info = {}
9
+ if (['.', '/', '?', '#'].includes(name[0]) || name.slice(1, 2) === ':') info.path = name
10
+ else if (['~'].includes(name[0])) info.path = name.slice(1)
11
+ else {
12
+ info = breakNsPath(name)
13
+ }
14
+ if (info.path.slice(0, 2) === './') info.path = info.path.slice(2)
15
+ if (this.routePathHandlers[info.subNs]) return this.routePathHandlers[info.subNs](name)
16
+ if (info.path.includes('//')) return info.path
17
+
18
+ info.path = info.path.split('/').map(p => {
15
19
  return p[0] === ':' && params[p.slice(1)] ? params[p.slice(1)] : p
16
20
  }).join('/')
17
- let url = path
21
+ let url = info.path
18
22
  const langDetector = get(cfg, 'i18n.detectors', [])
19
- if (ns) url = langDetector.includes('path') ? `/${params.lang ?? ''}${this.routeDir(ns)}${path}` : `${this.routeDir(ns)}${path}`
20
- queryString = defaultsDeep(query, qs.parse(queryString))
21
- if (!isEmpty(queryString)) url += '?' + qs.stringify(queryString)
23
+ if (info.ns) url = trimEnd(langDetector.includes('path') ? `/${params.lang ?? ''}${this.routeDir(info.ns)}${info.path}` : `${this.routeDir(info.ns)}${info.path}`, '/')
24
+ info.qs = defaultsDeep({}, query, info.qs)
25
+ if (!isEmpty(info.qs)) url += '?' + this.qs.stringify(info.qs)
26
+ if (!url.startsWith('http') && guessHost) url = `http://${this.config.server.host}:${this.config.server.port}/${trimStart(url, '/')}`
22
27
  return url
23
28
  }
24
29
 
@@ -0,0 +1,12 @@
1
+ import escapeChars from './escape-chars.js'
2
+
3
+ function unescape (text) {
4
+ const { forOwn, invert } = this.app.bajo.lib._
5
+ const mapping = invert(escapeChars)
6
+ forOwn(mapping, (v, k) => {
7
+ text = text.replaceAll(k, v)
8
+ })
9
+ return text
10
+ }
11
+
12
+ export default unescape
package/bajo/start.js CHANGED
@@ -12,20 +12,24 @@ import handleRedirect from '../lib/handle-redirect.js'
12
12
  async function start () {
13
13
  const { generateId, runHook } = this.app.bajo
14
14
  const cfg = this.getConfig()
15
- cfg.factory.logger = this.app.bajoLogger.instance.child(
15
+ cfg.factory.loggerInstance = this.app.bajoLogger.instance.child(
16
16
  {},
17
- { msgPrefix: '[wakatobi] ' }
17
+ { msgPrefix: '[waibu] ' }
18
18
  )
19
19
  cfg.factory.genReqId = req => generateId()
20
20
  cfg.factory.disableRequestLogging = true
21
+ cfg.factory.querystringParser = str => this.qs.parse(str)
21
22
 
22
23
  const instance = fastify(cfg.factory)
23
24
  instance.decorateRequest('lang', null)
25
+ instance.decorateRequest('i18n', null)
26
+ instance.decorateRequest('t', () => {})
24
27
  instance.decorateRequest('langDetector', null)
25
28
  instance.decorateRequest('site', null)
29
+ instance.decorateRequest('ns', null)
26
30
  this.instance = instance
27
31
  this.routes = this.routes || []
28
- await runHook('wakatobi:afterCreateContext', instance)
32
+ await runHook('waibu:afterCreateContext', instance)
29
33
  await instance.register(sensible)
30
34
  if (cfg.underPressure) await instance.register(underPressure)
31
35
  if (cfg.noIcon) await instance.register(noIcon)
package/lib/app-hook.js CHANGED
@@ -4,11 +4,9 @@ async function appHook () {
4
4
  const me = this
5
5
  for (const hook of hooks) {
6
6
  me.instance.addHook(hook, async function (...args) {
7
+ args.push(this)
7
8
  if (['onClose', 'onReady'].includes(hook)) await runHook(`${me.name}:${hook}`, ...args)
8
- else {
9
- const ctx = this // encapsulated fastify scope
10
- await runHook(`${me.name}:${hook}`, ctx, ...args)
11
- }
9
+ else await runHook(`${me.name}:${hook}`, ...args)
12
10
  })
13
11
  }
14
12
  }
package/lib/app.js CHANGED
@@ -2,15 +2,18 @@ import home from './home.js'
2
2
 
3
3
  export async function collect (glob = 'boot.js', baseNs) {
4
4
  const { eachPlugins, importModule } = this.app.bajo
5
- const { orderBy } = this.app.bajo.lib._
5
+ const { orderBy, get } = this.app.bajo.lib._
6
6
  if (!baseNs) baseNs = this.name
7
7
  const mods = []
8
+
8
9
  await eachPlugins(async function ({ config, file, ns, alias }) {
9
10
  const mod = await importModule(file, { asHandler: true })
10
- mod.prefix = config.prefix ?? alias
11
+ mod.prefix = get(config, 'waibu.prefix', alias)
12
+ if (get(config, 'i18n.detectors', []).includes('path')) mod.prefix = `/:lang${mod.prefix}`
11
13
  mod.ns = ns
14
+ mod.alias = alias
12
15
  mods.push(mod)
13
- }, { glob, baseNs })
16
+ }, { glob, prefix: baseNs })
14
17
  const prefixes = {}
15
18
  mods.forEach(m => {
16
19
  if (!prefixes[m.prefix]) prefixes[m.prefix] = []
@@ -27,7 +30,12 @@ export async function boot () {
27
30
  for (const m of mods) {
28
31
  await runHook(`${this.name}.${m.ns}:beforeAppBoot`)
29
32
  this.log.debug('Boot app: %s', m.ns)
30
- await m.handler.call(this.app[m.ns])
33
+ await this.instance.register(async (ctx) => {
34
+ const plugin = this.app[m.ns]
35
+ plugin.instance = ctx
36
+ await runHook(`${plugin.name}:afterCreateContext`, ctx)
37
+ await m.handler.call(plugin, ctx, m.prefix)
38
+ }, { prefix: m.prefix })
31
39
  await runHook(`${this.name}.${m.ns}:afterAppBoot`)
32
40
  }
33
41
  await runHook(`${this.name}:afterAppBoot`)
@@ -0,0 +1,15 @@
1
+ async function collectRoutePathHandlers () {
2
+ const { eachPlugins } = this.app.bajo
3
+ const { isEmpty } = this.app.bajo.lib._
4
+ this.routePathHandlers = this.routePathHandlers ?? {}
5
+ const me = this
6
+
7
+ await eachPlugins(async function ({ alias }) {
8
+ if (isEmpty(this.routePathHandlers) || !this.routePath) return undefined
9
+ for (const key of this.routePathHandlers) {
10
+ me.routePathHandlers[key] = this.routePath
11
+ }
12
+ })
13
+ }
14
+
15
+ export default collectRoutePathHandlers
@@ -15,11 +15,14 @@ async function handleForward (ctx) {
15
15
  const options = defaultsDeep({ base }, this.config.forwardOpts)
16
16
  await ctx.register(replyFrom, options)
17
17
 
18
- await ctx.decorateReply('forwardTo', async function (url, options = {}) {
19
- if (url.startsWith('http')) return await me.redirectTo(url)
20
- return this.from(me.routePath(url, options), {
21
- rewriteHeaders
22
- })
18
+ ctx.decorateReply('forwardTo', async function (url, options = {}) {
19
+ if (url.startsWith('http')) this.redirectTo(url)
20
+ else {
21
+ this.from(me.routePath(url, options), {
22
+ rewriteHeaders
23
+ })
24
+ }
25
+ return this
23
26
  })
24
27
  }
25
28
 
@@ -2,9 +2,10 @@ import path from 'path'
2
2
 
3
3
  async function handleRedirect (ctx, options) {
4
4
  const me = this
5
- ctx.decorateReply('redirectTo', async function (url, options = {}) {
6
- if (url.startsWith('http') || path.isAbsolute(url)) return this.redirect(url)
7
- return this.redirect(me.routePath(url, options))
5
+ ctx.decorateReply('redirectTo', function (url, options = {}) {
6
+ if (url.startsWith('http') || path.isAbsolute(url)) this.redirect(url)
7
+ else this.redirect(me.routePath(url, options))
8
+ return this
8
9
  })
9
10
  }
10
11
 
package/lib/home.js CHANGED
@@ -5,9 +5,9 @@ async function home () {
5
5
  if (config.home) {
6
6
  if (isString(config.home)) config.home = { path: config.home }
7
7
  await this.instance.get('/', async function (req, reply) {
8
- if (!config.home.forward) return await reply.redirectTo(config.home.path)
8
+ if (!config.home.forward) return reply.redirectTo(config.home.path)
9
9
  const opts = defaultsDeep(pick(req, ['params', 'query']), pick(config.home, ['params', 'query']))
10
- return await reply.forwardTo(config.home.path, opts)
10
+ return reply.forwardTo(config.home.path, opts)
11
11
  })
12
12
  }
13
13
  }
@@ -14,13 +14,12 @@ function detect (detector = [], req, reply) {
14
14
  const length = req.url.split('/').length
15
15
  let url = req.url.replace(`/${lang}`, `/${defLang}`)
16
16
  if (length > 2) url = req.url.replace(`/${lang}/`, `/${defLang}/`)
17
- reply.redirectTo(url)
18
- return
17
+ return reply.redirectTo(url)
19
18
  }
20
19
  // by query string
21
20
  lang = null
22
21
  if (detector.includes('qs')) {
23
- lang = req.query[this.app.wakatobi.config.qsKey.lang]
22
+ lang = req.query[this.app.waibu.config.qsKey.lang]
24
23
  if (lang && supported.includes(lang)) {
25
24
  req.lang = lang
26
25
  req.langDetector = 'qs'
@@ -51,13 +50,21 @@ function detect (detector = [], req, reply) {
51
50
 
52
51
  async function attachI18N (detector = [], req, reply) {
53
52
  if (!this.app.bajoI18N) return
53
+ const { importModule } = this.app.bajo
54
54
  const { get } = this.app.bajo.lib._
55
+ const translate = await importModule('bajo:/boot/lib/translate.js')
55
56
  detect.call(this, detector, req, reply)
56
- const i18n = this.app.bajoI18N.instance.cloneInstance()
57
- const defNs = get(req, 'routeOptions.config.ns', 'wakatobi')
58
- i18n.setDefaultNamespace(defNs)
59
- await i18n.changeLanguage(req.lang)
60
- req.i18n = i18n
57
+ const defNs = get(req, 'routeOptions.config.ns', this.name)
58
+ const opts = { defaultNS: defNs }
59
+ if (req.lang) opts.lng = req.lang
60
+ req.i18n = this.app.bajoI18N.instance.cloneInstance(opts)
61
+ req.t = (...args) => {
62
+ // const defNs = get(req, 'routeOptions.config.ns', this.name)
63
+ return translate.call(this.app[defNs], req.i18n, ...args)
64
+ }
65
+ req.format = (value, type = 'auto', opts) => {
66
+ return this.app.bajoI18N.format(value, type, req.lang, opts)
67
+ }
61
68
  }
62
69
 
63
70
  export default attachI18N
@@ -1,17 +1,14 @@
1
1
  async function errorHandler (ctx, extHandler) {
2
2
  const me = this
3
3
  ctx.setErrorHandler(async function (err, req, reply) {
4
- if (err.redirect) {
5
- reply.redirect(err.redirect)
6
- return
7
- }
4
+ if (err.redirect) return reply.redirect(err.redirect)
8
5
  if (err.print) {
9
6
  reply.send(err.print)
10
7
  return
11
8
  }
12
- if (me.app.bajo.config.log.level === 'trace' && !['notfound', 'redirect'].includes(err.message)) console.error(err)
13
- if (extHandler) return await extHandler.call(me, ctx, err, req, reply)
14
- if (err.message === 'notfound' || err.statusCode === 404) {
9
+ if (me.app.bajo.config.log.level === 'trace' && !['notFound', 'redirect'].includes(err.message)) console.error(err)
10
+ if (extHandler) return await extHandler.call(me, err, req, reply, ctx)
11
+ if (err.message === 'notFound' || err.statusCode === 404) {
15
12
  reply.code(err.statusCode)
16
13
  return
17
14
  }
@@ -9,7 +9,7 @@ async function isRouteDisabled (url, method, matchers = []) {
9
9
  const { intersection, cloneDeep } = this.app.bajo.lib._
10
10
  const items = []
11
11
  for (const m of cloneDeep(matchers)) {
12
- m.path = this.app.wakatobi.routePath(m.path)
12
+ m.path = this.app.waibu.routePath(m.path)
13
13
  m.methods = santizeMethods(m.methods)
14
14
  items.push(m)
15
15
  }
@@ -1,7 +1,6 @@
1
- import hookTypes from './hook-types.js'
2
-
3
1
  async function mergeRouteHooks (def, withHandler = true) {
4
2
  const { last, isFunction } = this.app.bajo.lib._
3
+ const { hookTypes } = this.app.waibu
5
4
  const hooks = [...hookTypes]
6
5
  const me = this
7
6
  if (withHandler) hooks.push('handler')
@@ -11,7 +10,8 @@ async function mergeRouteHooks (def, withHandler = true) {
11
10
  def[h] = async function (...args) {
12
11
  // TODO: hooks can be array of functions
13
12
  if (isFunction(last(args))) args.pop()
14
- return await oldH.call(me, this, ...args)
13
+ args.push(this)
14
+ return await oldH.call(me, ...args)
15
15
  }
16
16
  }
17
17
  }
@@ -1,5 +1,5 @@
1
1
  async function reroutedPath (path, mapper = {}) {
2
- const { routePath } = this.app.wakatobi
2
+ const { routePath } = this.app.waibu
3
3
  let result
4
4
  for (let k in mapper) {
5
5
  const v = routePath(mapper[k])
@@ -1,11 +1,11 @@
1
1
  async function routeHook (ns) {
2
2
  const ctx = this.app[ns].instance
3
3
  const { runHook } = this.app.bajo
4
- const { hookTypes } = this.app.wakatobi
4
+ const { hookTypes } = this.app.waibu
5
5
  for (const hook of hookTypes) {
6
6
  ctx.addHook(hook, async function (...args) {
7
- const context = this // encapsulated fastify scope
8
- await runHook(`${ns}:${hook}`, context, ...args)
7
+ args.push(this)
8
+ await runHook(`${ns}:${hook}`, ...args)
9
9
  })
10
10
  }
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Web Framework for Bajo",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,6 +12,7 @@
12
12
  "url": "git+https://github.com/ardhi/waibu.git"
13
13
  },
14
14
  "keywords": [
15
+ "waibu",
15
16
  "web",
16
17
  "webserver",
17
18
  "bajo",
@@ -26,21 +27,22 @@
26
27
  },
27
28
  "homepage": "https://github.com/ardhi/waibu#readme",
28
29
  "dependencies": {
29
- "@fastify/accepts": "^4.3.0",
30
- "@fastify/compress": "^7.0.3",
31
- "@fastify/cookie": "^9.3.1",
32
- "@fastify/cors": "^9.0.1",
33
- "@fastify/flash": "^5.2.0",
34
- "@fastify/formbody": "^7.4.0",
35
- "@fastify/helmet": "^11.1.1",
36
- "@fastify/multipart": "^8.3.0",
37
- "@fastify/rate-limit": "^9.1.0",
38
- "@fastify/reply-from": "^9.8.0",
39
- "@fastify/sensible": "^5.6.0",
40
- "@fastify/session": "^10.9.0",
41
- "@fastify/static": "github:ardhi/fastify-static#v7.x",
42
- "@fastify/under-pressure": "^8.5.1",
43
- "fastify": "^4.28.1",
44
- "fastify-no-icon": "^6.0.0"
30
+ "@fastify/accepts": "^5.0.2",
31
+ "@fastify/compress": "^8.0.1",
32
+ "@fastify/cookie": "^11.0.2",
33
+ "@fastify/cors": "^10.0.2",
34
+ "@fastify/flash": "^6.0.3",
35
+ "@fastify/formbody": "^8.0.2",
36
+ "@fastify/helmet": "^13.0.1",
37
+ "@fastify/multipart": "^9.0.2",
38
+ "@fastify/rate-limit": "^10.2.2",
39
+ "@fastify/reply-from": "^12.0.1",
40
+ "@fastify/sensible": "^6.0.2",
41
+ "@fastify/session": "^11.1.0",
42
+ "@fastify/static": "^8.0.4",
43
+ "@fastify/under-pressure": "^9.0.3",
44
+ "fastify": "^5.2.1",
45
+ "fastify-no-icon": "^7.0.0",
46
+ "query-string": "^9.1.1"
45
47
  }
46
48
  }
@@ -1,6 +0,0 @@
1
- async function bajoI18nBeforeInit () {
2
- const config = this.app.bajoI18N.config
3
- if (!config.fallbackNS.includes(this.name)) config.fallbackNS.push(this.name)
4
- }
5
-
6
- export default bajoI18nBeforeInit
@@ -1,18 +0,0 @@
1
- function getParams (req, ...items) {
2
- const { map, trim, get } = this.app.bajo.lib._
3
- let fields
4
- req.query = req.query ?? {}
5
- req.params = req.params ?? {}
6
- if (req.query.fields) fields = map((req.query.fields ?? '').split(','), i => trim(i))
7
- const params = {
8
- fields,
9
- count: get(this, 'config.dbColl.count', false),
10
- body: req.body
11
- }
12
- items.forEach(i => {
13
- params[i] = req.params[i]
14
- })
15
- return params
16
- }
17
-
18
- export default getParams
@@ -1,9 +0,0 @@
1
- const methodMap = {
2
- create: 'POST',
3
- find: 'GET',
4
- get: 'GET',
5
- update: 'PUT',
6
- remove: 'DELETE'
7
- }
8
-
9
- export default methodMap
@@ -1,13 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function create ({ coll, req, reply, body, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { recordCreate, attachmentFind } = this.app.dobo
6
- const { name, input, opts } = prepCrud.call(this, { coll, req, body, options, args: ['coll'] })
7
- const ret = await recordCreate(name, input, opts)
8
- const { attachment, stats, mimeType } = req.query
9
- if (attachment) ret.data._attachment = await attachmentFind(name, ret.data.id, { stats, mimeType })
10
- return ret
11
- }
12
-
13
- export default create
@@ -1,19 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function find ({ coll, req, reply, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { recordFindOne, attachmentFind } = this.app.dobo
6
- const { name, opts } = prepCrud.call(this, { coll, req, options, args: ['coll'] })
7
- opts.bboxLatField = req.query[this.config.qsKey.bboxLatField]
8
- opts.bboxLngField = req.query[this.config.qsKey.bboxLngField]
9
- const filter = this.parseFilter(req)
10
- const ret = await recordFindOne(name, filter, opts)
11
- ret.filter = filter
12
- const { attachment, stats, mimeType } = req.query
13
- if (attachment) {
14
- ret.data._attachment = await attachmentFind(name, ret.data.id, { stats, mimeType })
15
- }
16
- return ret
17
- }
18
-
19
- export default find
@@ -1,20 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function find ({ coll, req, reply, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { recordFind, attachmentFind } = this.app.dobo
6
- const { name, opts } = prepCrud.call(this, { coll, req, options, args: ['coll'] })
7
- opts.bboxLatField = req.query[this.config.qsKey.bboxLatField]
8
- opts.bboxLngField = req.query[this.config.qsKey.bboxLngField]
9
- const filter = this.parseFilter(req)
10
- const ret = await recordFind(name, filter, opts)
11
- const { attachment, stats, mimeType } = req.query
12
- if (attachment) {
13
- for (const d of ret.data) {
14
- d._attachment = await attachmentFind(name, d.id, { stats, mimeType })
15
- }
16
- }
17
- return ret
18
- }
19
-
20
- export default find
@@ -1,14 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function get ({ coll, req, reply, id, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { recordGet, attachmentFind } = this.app.dobo
6
- const { name, recId, opts } = prepCrud.call(this, { coll, req, id, options, args: ['coll', 'id'] })
7
- opts.filter = this.parseFilter(req)
8
- const ret = await recordGet(name, recId, opts)
9
- const { attachment, stats, mimeType } = req.query
10
- if (attachment) ret.data._attachment = await attachmentFind(name, id, { stats, mimeType })
11
- return ret
12
- }
13
-
14
- export default get
@@ -1,10 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function remove ({ coll, req, reply, id, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { recordRemove } = this.app.dobo
6
- const { name, recId, opts } = prepCrud.call(this, { coll, req, id, options, args: ['coll', 'id'] })
7
- return await recordRemove(name, recId, opts)
8
- }
9
-
10
- export default remove
@@ -1,13 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function update ({ coll, req, reply, id, body, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { recordUpdate, attachmentFind } = this.app.dobo
6
- const { name, input, opts, recId } = prepCrud.call(this, { coll, req, body, id, options, args: ['coll', 'id'] })
7
- const ret = await recordUpdate(name, recId, input, opts)
8
- const { attachment, stats, mimeType } = req.query
9
- if (attachment) ret.data._attachment = await attachmentFind(name, id, { stats, mimeType })
10
- return ret
11
- }
12
-
13
- export default update
@@ -1,13 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function aggregate ({ coll, req, reply, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { statAggregate } = this.app.dobo
6
- const { name, opts } = prepCrud.call(this, { coll, req, options, args: ['coll'] })
7
- for (const item of ['group', 'aggregate']) {
8
- opts[item] = options[item] ?? req.params[item] ?? req.query[item]
9
- }
10
- return await statAggregate(name, this.parseFilter(req), opts)
11
- }
12
-
13
- export default aggregate
@@ -1,13 +0,0 @@
1
- import prepCrud from '../../../lib/prep-crud.js'
2
-
3
- async function histogram ({ coll, req, reply, options = {} }) {
4
- this.app.bajo.getPlugin('dobo') // ensure dobo is loaded
5
- const { statHistogram } = this.app.dobo
6
- const { name, opts } = prepCrud.call(this, { coll, req, options, args: ['coll'] })
7
- for (const item of ['type', 'group', 'aggregate']) {
8
- opts[item] = options[item] ?? req.params[item] ?? req.query[item]
9
- }
10
- return await statHistogram(name, this.parseFilter(req), opts)
11
- }
12
-
13
- export default histogram
package/lib/prep-crud.js DELETED
@@ -1,17 +0,0 @@
1
- function prepCrud ({ coll, body, id, req, options, args }) {
2
- const { pascalCase } = this.app.bajo
3
- const { cloneDeep, get } = this.app.bajo.lib._
4
- const opts = cloneDeep(options)
5
- const params = this.getParams(req, ...args)
6
- for (const k of ['count', 'fields']) {
7
- opts[k] = opts[k] ?? params[k]
8
- }
9
- opts.dataOnly = get(this, 'config.dbColl.dataOnly', false)
10
- opts.req = req
11
- const recId = id ?? params.id ?? req.query.id
12
- const name = pascalCase(coll ?? params.coll)
13
- const input = body ?? params.body
14
- return { name, recId, input, opts }
15
- }
16
-
17
- export default prepCrud