waibu-mpa 2.1.10 → 2.2.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.
@@ -5,13 +5,12 @@ import collectThemes from '../../lib/collect-themes.js'
5
5
  import collectIconsets from '../../lib/collect-iconsets.js'
6
6
  import handleSession from '../../lib/session/setup.js'
7
7
  import subApp from '../../lib/sub-app.js'
8
- import notFound from '../../lib/not-found.js'
9
- import error from '../../lib/error.js'
8
+ import errorHandler from '../../lib/error-handler.js'
10
9
 
11
10
  const boot = {
12
11
  level: 10,
13
- handler: async function (ctx, prefix) {
14
- this.ctx = ctx
12
+ errorHandler,
13
+ handler: async function (prefix) {
15
14
  const { importPkg, importModule } = this.app.bajo
16
15
  const bodyParser = await importPkg('waibu:@fastify/formbody')
17
16
  const routeHook = await importModule('waibu:/lib/webapp-scope/route-hook.js')
@@ -21,22 +20,20 @@ const boot = {
21
20
  const handleCompress = await importModule('waibu:/lib/webapp-scope/handle-compress.js')
22
21
  const handleRateLimit = await importModule('waibu:/lib/webapp-scope/handle-rate-limit.js')
23
22
 
24
- await ctx.register(bodyParser)
25
- await handleRateLimit.call(this, ctx, this.config.rateLimit)
26
- await handleCors.call(this, ctx, this.config.cors)
27
- await handleHelmet.call(this, ctx, this.config.helmet)
28
- await handleCompress.call(this, ctx, this.config.compress)
29
- await handleMultipart.call(this, ctx, this.config.multipart)
30
- await decorate.call(this, ctx)
31
- await handleSession.call(this, ctx)
23
+ await this.webAppCtx.register(bodyParser)
24
+ await handleRateLimit.call(this, this.config.rateLimit)
25
+ await handleCors.call(this, this.config.cors)
26
+ await handleHelmet.call(this, this.config.helmet)
27
+ await handleCompress.call(this, this.config.compress)
28
+ await handleMultipart.call(this, this.config.multipart)
29
+ await decorate.call(this)
30
+ await handleSession.call(this)
32
31
  await routeHook.call(this, this.ns)
33
- await error.call(this, ctx)
34
- await collectViewEngines.call(this, ctx)
35
- await collectThemes.call(this, ctx)
36
- await collectIconsets.call(this, ctx)
37
- await buildRoutes.call(this, ctx, prefix)
38
- await subApp.call(this, ctx)
39
- await notFound.call(this, ctx)
32
+ await collectViewEngines.call(this)
33
+ await collectThemes.call(this)
34
+ await collectIconsets.call(this)
35
+ await buildRoutes.call(this, prefix)
36
+ await subApp.call(this)
40
37
  }
41
38
  }
42
39
 
@@ -1,4 +1,4 @@
1
- async function theme (ctx) {
1
+ async function theme () {
2
2
  const css = [
3
3
  'waibuMpa.virtual:/purecss/pure-min.css'
4
4
  ]
@@ -7,7 +7,7 @@ const names = ['description', 'keywords', 'robots', 'viewport', 'author', 'publi
7
7
 
8
8
  async function meta (options) {
9
9
  const { runHook, importPkg } = this.app.bajo
10
- const { map, uniq, isArray, merge, kebabCase, keys, omit, get, isFunction } = this.app.lib._
10
+ const { map, uniq, isArray, kebabCase, keys, omit, get, isFunction } = this.app.lib._
11
11
  const { sprintf } = this.app.lib
12
12
  const { $, theme, req, locals } = options ?? {}
13
13
  const { page = {} } = locals
@@ -22,10 +22,22 @@ async function meta (options) {
22
22
  content: isArray(page[attr]) ? page[attr].join(', ') : page[attr]
23
23
  })
24
24
  }
25
- // link
25
+ // links
26
26
  for (const attr of links) {
27
27
  if (!page[attr]) continue
28
- items.push(merge({}, page[attr], { rel: kebabCase(attr), tag: 'link' }))
28
+ const all = isArray(page[attr]) ? page[attr] : page[attr] = [page[attr]]
29
+ for (const a of all) {
30
+ const [href, ...params] = a.split('|')
31
+ const item = {
32
+ tag: 'link',
33
+ rel: kebabCase(attr),
34
+ href
35
+ }
36
+ for (const p of params ?? []) {
37
+ item[p] = true
38
+ }
39
+ items.push(item)
40
+ }
29
41
  }
30
42
  if (this.config.theme && this.config.theme.autoInsert.meta) {
31
43
  await runHook(`${this.ns}.${theme.name}:beforeInjectMeta`, { meta: theme.meta, items, req })
@@ -57,7 +57,7 @@ export async function build ({ files, pathPrefix, dir, ns, cfg, parent, urlPrefi
57
57
  return mods
58
58
  }
59
59
 
60
- async function addRoutes ({ appPrefix, prefix, mods, ctx, appCtx, cfg }) {
60
+ async function addRoutes ({ appPrefix, prefix, mods, appCtx, cfg }) {
61
61
  const { importModule } = this.app.bajo
62
62
  const isRouteDisabled = await importModule('waibu:/lib/webapp-scope/is-route-disabled.js')
63
63
  const reroutedPath = await importModule('waibu:/lib/webapp-scope/rerouted-path.js')
@@ -72,12 +72,12 @@ async function addRoutes ({ appPrefix, prefix, mods, ctx, appCtx, cfg }) {
72
72
  this.log.warn('rerouted%s%s', `${prefix}${fullPath}`, `${prefix}${rpath}`)
73
73
  mod.url = rpath
74
74
  mod.pathReroutedTo = rpath
75
- await ctx.route(mod)
75
+ await this.webAppCtx.route(mod)
76
76
  } else await appCtx.route(mod)
77
77
  }
78
78
  }
79
79
 
80
- async function buildRoutes (ctx, prefix) {
80
+ async function buildRoutes (prefix) {
81
81
  const { eachPlugins, runHook } = this.app.bajo
82
82
  const { getPluginPrefix } = this.app.waibu
83
83
  const { fastGlob } = this.app.lib
@@ -88,7 +88,7 @@ async function buildRoutes (ctx, prefix) {
88
88
  const appCtxs = {}
89
89
  let subRoutes = []
90
90
  const names = this.app.getAllNs()
91
- await runHook(`${this.ns}:beforeBuildRoutes`, ctx)
91
+ await runHook(`${this.ns}:beforeBuildRoutes`, this.webAppCtx)
92
92
  await eachPlugins(async function ({ dir }) {
93
93
  const { ns } = this
94
94
  let appPrefix = getPluginPrefix(ns)
@@ -103,11 +103,11 @@ async function buildRoutes (ctx, prefix) {
103
103
  subRoutes.push({ file, ns: sns, sns: ns, dir })
104
104
  }
105
105
  if (files.length === 0) return undefined
106
- await ctx.register(async (appCtx) => {
106
+ await me.webAppCtx.register(async (appCtx) => {
107
107
  appCtxs[ns] = appCtx
108
108
  await runHook(`${me.ns}.${this.ns}:beforeBuildRoutes`, appCtx, appPrefix)
109
109
  const mods = await build.call(this, { appCtx, files, appPrefix, pathPrefix, dir, ns, cfg, parent: me.ns })
110
- await addRoutes.call(me, { appPrefix, prefix, mods, ctx, appCtx, cfg })
110
+ await addRoutes.call(me, { appPrefix, prefix, mods, appCtx, cfg })
111
111
  await runHook(`${me.ns}.${this.ns}:afterBuildRoutes`, appCtx, appPrefix)
112
112
  }, { prefix: appPrefix })
113
113
  })
@@ -128,13 +128,13 @@ async function buildRoutes (ctx, prefix) {
128
128
  const pathPrefix = `waibuMpa/extend/${ns}/route/`
129
129
  const urlPrefix = getPluginPrefix(sns)
130
130
  const mods = await build.call(scope, { appCtx, files: [file], pathPrefix, dir, ns, cfg, parent: me.ns, urlPrefix, subRoute: sns })
131
- await addRoutes.call(me, { appPrefix, prefix, mods, ctx, appCtx, cfg })
131
+ await addRoutes.call(me, { appPrefix, prefix, mods, appCtx, cfg })
132
132
  }
133
133
  await runHook(`${me.ns}.${k}:afterBuildSubRoutes`, appCtx, appPrefix)
134
134
  }
135
135
  }
136
136
 
137
- await runHook(`${this.ns}:afterBuildRoutes`, ctx)
137
+ await runHook(`${this.ns}:afterBuildRoutes`, this.webAppCtx)
138
138
  }
139
139
 
140
140
  export default buildRoutes
@@ -1,7 +1,7 @@
1
1
  import iconsetFactory from './class/iconset.js'
2
2
  import loadResource from './load-resource.js'
3
3
 
4
- async function collectIconsets (ctx) {
4
+ async function collectIconsets () {
5
5
  const { eachPlugins, importModule, runHook } = this.app.bajo
6
6
  const { omit, isFunction, isArray, pullAt, findIndex, cloneDeep } = this.app.lib._
7
7
 
@@ -16,7 +16,7 @@ async function collectIconsets (ctx) {
16
16
  await eachPlugins(async function ({ file }) {
17
17
  const { ns } = this
18
18
  let mod = await importModule(file)
19
- if (isFunction(mod)) mod = await mod.call(this, ctx)
19
+ if (isFunction(mod)) mod = await mod.call(this, me.webAppCtx)
20
20
  if (!isArray(mod)) mod = [mod]
21
21
  for (const m of mod) {
22
22
  for (const key of ['css', 'links', 'scripts']) {
@@ -55,7 +55,7 @@ async function build (mod, fw) {
55
55
  await runHook(`${this.ns}.${mod.name}:afterCollectTheme`, theme)
56
56
  }
57
57
 
58
- async function collectThemes (ctx) {
58
+ async function collectThemes () {
59
59
  const { eachPlugins, importModule } = this.app.bajo
60
60
  const { isFunction, isArray, find, without } = this.app.lib._
61
61
 
@@ -67,10 +67,11 @@ async function collectThemes (ctx) {
67
67
  this.log.debug('collect%s', this.t('themes'))
68
68
  const modso = []
69
69
  const modsf = []
70
+ const me = this
70
71
  await eachPlugins(async function ({ file }) {
71
72
  const plugin = this
72
73
  let mod = await importModule(file)
73
- if (isFunction(mod)) mod = await mod.call(this, ctx)
74
+ if (isFunction(mod)) mod = await mod.call(this, me.webAppCtx)
74
75
  if (!isArray(mod)) mod = [mod]
75
76
  mod = mod.map(m => Object.assign(m, { plugin }))
76
77
  for (const m of mod) {
@@ -1,6 +1,6 @@
1
1
  import viewEngineFactory from './class/view-engine.js'
2
2
 
3
- async function collectViewEngines (ctx) {
3
+ async function collectViewEngines () {
4
4
  const { eachPlugins, importModule, join, runHook } = this.app.bajo
5
5
  const { isFunction, omit, isArray } = this.app.lib._
6
6
  this.viewEngines = []
@@ -9,7 +9,7 @@ async function collectViewEngines (ctx) {
9
9
  await eachPlugins(async function ({ file }) {
10
10
  const { ns } = this
11
11
  let mod = await importModule(file)
12
- if (isFunction(mod)) mod = await mod.call(this, ctx)
12
+ if (isFunction(mod)) mod = await mod.call(this, me.webAppCtx)
13
13
  if (!isArray(mod)) mod = [mod]
14
14
  for (const m of mod) {
15
15
  await runHook(`${me.ns}.${mod.name}:beforeCollectViewEngine`, m)
package/lib/decorate.js CHANGED
@@ -1,17 +1,17 @@
1
1
  import path from 'path'
2
2
 
3
- async function decorate (ctx) {
3
+ async function decorate () {
4
4
  const { importPkg } = this.app.bajo
5
5
  const { isEmpty } = this.app.lib._
6
6
  const mime = await importPkg('waibu:mime')
7
7
  const cfg = this.config
8
8
  const me = this
9
- ctx.decorateRequest('theme', cfg.theme.set)
10
- ctx.decorateRequest('iconset', cfg.iconset.set)
11
- ctx.decorateRequest('darkMode', cfg.darkMode.set)
12
- ctx.decorateRequest('referer', '')
13
- ctx.decorateReply('ctags', null)
14
- ctx.decorateReply('view', async function (tpl, params = {}, opts = {}) {
9
+ this.webAppCtx.decorateRequest('theme', cfg.theme.set)
10
+ this.webAppCtx.decorateRequest('iconset', cfg.iconset.set)
11
+ this.webAppCtx.decorateRequest('darkMode', cfg.darkMode.set)
12
+ this.webAppCtx.decorateRequest('referer', '')
13
+ this.webAppCtx.decorateReply('ctags', null)
14
+ this.webAppCtx.decorateReply('view', async function (tpl, params = {}, opts = {}) {
15
15
  let ext = path.extname(tpl)
16
16
  if (ext === '.md') ext = '.html'
17
17
  let mimeType = isEmpty(ext) ? 'text/html' : mime.getType(ext)
@@ -1,6 +1,6 @@
1
1
  import { handler } from './not-found.js'
2
2
 
3
- const extHandler = async function (err, req, reply) {
3
+ async function errorHandler (err, req, reply) {
4
4
  const { getPluginFile } = this.app.bajo
5
5
  const { fs } = this.app.lib
6
6
  const { resolveTemplate } = this.app.bajoTemplate
@@ -33,10 +33,4 @@ const extHandler = async function (err, req, reply) {
33
33
  return result
34
34
  }
35
35
 
36
- async function error (ctx) {
37
- const { importModule } = this.app.bajo
38
- const errorHandler = await importModule('waibu:/lib/webapp-scope/error-handler.js')
39
- await errorHandler.call(this, ctx, extHandler)
40
- }
41
-
42
- export default error
36
+ export default errorHandler
@@ -1,6 +1,6 @@
1
1
  import Store from './store.js'
2
2
 
3
- async function sessionSetup (ctx) {
3
+ async function sessionSetup () {
4
4
  const { importPkg, runHook } = this.app.bajo
5
5
  const [cookie, session, flash] = await importPkg('waibu:@fastify/cookie',
6
6
  'waibu:@fastify/session', 'waibu:@fastify/flash')
@@ -11,10 +11,10 @@ async function sessionSetup (ctx) {
11
11
  this.sessionStore = new Store(this)
12
12
  cfg.store = this.sessionStore
13
13
  }
14
- ctx.register(cookie)
15
- ctx.register(session, cfg)
16
- ctx.register(flash)
17
- await runHook(`${this.ns}:afterSessionSetup`, ctx)
14
+ this.webAppCtx.register(cookie)
15
+ this.webAppCtx.register(session, cfg)
16
+ this.webAppCtx.register(flash)
17
+ await runHook(`${this.ns}:afterSessionSetup`, this.webAppCtx)
18
18
  }
19
19
 
20
20
  export default sessionSetup
package/lib/sub-app.js CHANGED
@@ -1,17 +1,17 @@
1
- async function subApp (ctx) {
1
+ async function subApp () {
2
2
  const { importModule, runHook } = this.app.bajo
3
- const { collect } = await importModule('waibu:/lib/app.js', { asDefaultImport: false })
4
- await runHook(`${this.ns}:beforeSubApp`, ctx)
3
+ const { collect } = await importModule('waibu:/lib/web-app.js', { asDefaultImport: false })
4
+ await runHook(`${this.ns}:beforeSubApp`, this.webAppCtx)
5
5
  const mods = await collect.call(this.app[this.ns], 'boot.js', 'waibuMpa')
6
6
  for (const m of mods) {
7
7
  this.log.debug('bootSubApp%s', m.ns)
8
- await ctx.register(async (subCtx) => {
8
+ await this.webAppCtx.register(async (subCtx) => {
9
9
  this.app[m.ns].instance = subCtx
10
10
  await runHook(`${this.ns}.${m.alias}:afterCreateContext`, subCtx, m.prefix)
11
11
  await m.handler.call(this.app[m.ns], subCtx, m.prefix)
12
12
  }, { prefix: m.prefix })
13
13
  }
14
- await runHook(`${this.ns}:afterSubApp`, ctx)
14
+ await runHook(`${this.ns}:afterSubApp`, this.webAppCtx)
15
15
  }
16
16
 
17
17
  export default subApp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-mpa",
3
- "version": "2.1.10",
3
+ "version": "2.2.0",
4
4
  "description": "MPA support for Waibu Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-02-05
4
+
5
+ - [2.1.11] Bug fix on rendering ```preconnect```
6
+
3
7
  ## 2026-01-21
4
8
 
5
9
  - [2.1.8] Add ```getPluginTitle()```