waibu-mpa 2.16.0 → 2.17.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/extend/bajo/hook.js +41 -0
- package/extend/waibuMpa/route/component/render.js +2 -5
- package/index.js +1 -23
- package/lib/build-page/inject-elements.js +1 -1
- package/lib/build-page.js +1 -1
- package/lib/class/component.js +2 -2
- package/lib/decorate.js +3 -5
- package/package.json +1 -1
- package/wiki/CHANGES.md +9 -0
- package/extend/bajo/hook/waibu-mpa.theme@after-inject-scripts.js +0 -5
- package/extend/bajo/hook/waibu-mpa@pre-parsing.js +0 -33
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
async function checkLang (req, reply) {
|
|
2
|
+
if (!req.session) return
|
|
3
|
+
if (req.langDetector) {
|
|
4
|
+
req.session.lang = req.lang
|
|
5
|
+
return
|
|
6
|
+
}
|
|
7
|
+
if (req.session.lang) req.lang = req.session.lang
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function checkDark (req, reply) {
|
|
11
|
+
const { isSet } = this.app.lib.aneka
|
|
12
|
+
const key = this.config.darkMode.qsKey
|
|
13
|
+
const value = this.config.darkMode.set ?? req.query[key]
|
|
14
|
+
if (isSet(value)) {
|
|
15
|
+
req.darkMode = value
|
|
16
|
+
if (req.session) req.session.darkMode = req.darkMode
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
if (isSet(req.session.darkMode)) req.darkMode = req.session.darkMode
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function hook () {
|
|
23
|
+
return [{
|
|
24
|
+
level: 9,
|
|
25
|
+
name: 'waibuMpa:preParsing',
|
|
26
|
+
handler: async function (req, reply) {
|
|
27
|
+
const { importModule } = this.app.bajo
|
|
28
|
+
const attachIntl = await importModule('waibu:/lib/webapp-scope/attach-intl.js')
|
|
29
|
+
await attachIntl.call(this, this.config.intl.detectors, req, reply)
|
|
30
|
+
await checkLang.call(this, req, reply)
|
|
31
|
+
await checkDark.call(this, req, reply)
|
|
32
|
+
}
|
|
33
|
+
}, {
|
|
34
|
+
name: 'waibuMpa.theme:afterInjectScripts',
|
|
35
|
+
handler: async function ({ items }) {
|
|
36
|
+
// items.push(`${this.ns}.virtual:/json2csv/json2csv.js`)
|
|
37
|
+
}
|
|
38
|
+
}]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default hook
|
|
@@ -2,8 +2,6 @@ const component = {
|
|
|
2
2
|
method: 'POST',
|
|
3
3
|
noCacheReq: true,
|
|
4
4
|
handler: async function (req, reply) {
|
|
5
|
-
const { getPluginDataDir } = this.app.bajo
|
|
6
|
-
const { fs } = this.app.lib
|
|
7
5
|
const { merge, get } = this.app.lib._
|
|
8
6
|
req.referer = req.headers['x-referer']
|
|
9
7
|
const pageId = req.headers['x-req-id']
|
|
@@ -13,9 +11,8 @@ const component = {
|
|
|
13
11
|
reply.header('Content-Language', req.lang)
|
|
14
12
|
if (pageId) {
|
|
15
13
|
try {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
params = merge({}, locals, params)
|
|
14
|
+
const locals = await this.app.cache.load(`${this.ns}.req:/${pageId}-locals.json`, this.config.reqTtlDur)
|
|
15
|
+
params = merge({}, locals ?? {}, params)
|
|
19
16
|
} catch (err) {}
|
|
20
17
|
}
|
|
21
18
|
const theme = get(req, 'headers.x-theme', get(params, '_meta.theme.name'))
|
package/index.js
CHANGED
|
@@ -138,10 +138,7 @@ async function factory (pkgName) {
|
|
|
138
138
|
compress: false,
|
|
139
139
|
rateLimit: false,
|
|
140
140
|
disabled: [],
|
|
141
|
-
|
|
142
|
-
intvDur: '1m',
|
|
143
|
-
reqTtlDur: '1d'
|
|
144
|
-
}
|
|
141
|
+
reqTtlDur: '1d'
|
|
145
142
|
}
|
|
146
143
|
|
|
147
144
|
this.configDev = {
|
|
@@ -171,13 +168,6 @@ async function factory (pkgName) {
|
|
|
171
168
|
await widgetFactory.call(this)
|
|
172
169
|
}
|
|
173
170
|
|
|
174
|
-
start = async () => {
|
|
175
|
-
this.purgeCache()
|
|
176
|
-
setInterval(() => {
|
|
177
|
-
this.purgeCache()
|
|
178
|
-
}, this.config.purgeCache.intvDur)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
171
|
buildUrl = ({ exclude = [], prefix = '?', base, url = '', params = {}, prettyUrl }) => {
|
|
182
172
|
const { parseObject } = this.app.lib
|
|
183
173
|
const { qs } = this.app.waibu
|
|
@@ -640,18 +630,6 @@ async function factory (pkgName) {
|
|
|
640
630
|
if (!iconset) return iconset
|
|
641
631
|
return nameOnly ? iconset.name : iconset
|
|
642
632
|
}
|
|
643
|
-
|
|
644
|
-
purgeCache = async () => {
|
|
645
|
-
const { getPluginDataDir } = this.app.bajo
|
|
646
|
-
const { fastGlob, fs } = this.app.lib
|
|
647
|
-
const dirs = await fastGlob(`${getPluginDataDir(this.ns)}/cache/req/*`, { onlyDirectories: true })
|
|
648
|
-
for (const dir of dirs) {
|
|
649
|
-
try {
|
|
650
|
-
const { mtimeMs } = await fs.stat(dir)
|
|
651
|
-
if (Date.now() - mtimeMs > this.config.purgeCache.reqTtlDur) await fs.remove(dir)
|
|
652
|
-
} catch (err) {}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
633
|
}
|
|
656
634
|
|
|
657
635
|
return WaibuMpa
|
|
@@ -38,7 +38,7 @@ async function injectElements (options) {
|
|
|
38
38
|
}
|
|
39
39
|
options.inlineScript = rsc.inlineScript
|
|
40
40
|
options.inlineCss = rsc.inlineCss
|
|
41
|
-
await runHook(`${this.ns}:
|
|
41
|
+
await runHook(`${this.ns}.injectElement:beforeBuildPage`, options)
|
|
42
42
|
await injectMeta.call(this, options)
|
|
43
43
|
await injectLink.call(this, options)
|
|
44
44
|
await injectCss.call(this, options)
|
package/lib/build-page.js
CHANGED
|
@@ -33,7 +33,7 @@ async function buildPage ({ text, locals = {}, opts = {} } = {}) {
|
|
|
33
33
|
const ns = req.ns
|
|
34
34
|
let $ = cheerio.load(text, this.config.cheerio.loadOptions, false)
|
|
35
35
|
if (partial) $('c\\:page-start, c\\:page-end').remove()
|
|
36
|
-
await runHook(`${this.ns}
|
|
36
|
+
await runHook(`${this.ns}${partial ? '.partial' : ''}:beforeBuildPage`, { $, theme, iconset, req, reply, locals, ns, text })
|
|
37
37
|
await attrsMutation.call(this, { $, el: $.root(), req })
|
|
38
38
|
const cmp = await theme.createComponent({ $, iconset, req, reply, locals: cloneDeep(locals), scriptBlock: reqAsset[req.id].scriptBlock, styleBlock: reqAsset[req.id].styleBlock })
|
|
39
39
|
await replaceTag.call(this, { el: $.root(), cmp, opts })
|
package/lib/class/component.js
CHANGED
|
@@ -115,12 +115,12 @@ async function componentFactory () {
|
|
|
115
115
|
params.attr.class = without(uniq(params.attr.class), undefined, null, '')
|
|
116
116
|
if (isEmpty(params.attr.class)) delete params.attr.class
|
|
117
117
|
if (isEmpty(params.attr.style)) delete params.attr.style
|
|
118
|
-
if (isEmpty(params.html)) return await this.render(params)
|
|
118
|
+
if (isEmpty(params.html)) return await this.render(params, opts)
|
|
119
119
|
|
|
120
120
|
const merged = merge({}, params.locals, { attr: params.attr })
|
|
121
121
|
const result = await compile(params.html, merged, { ttl: this.ttlDur })
|
|
122
122
|
params.html = result
|
|
123
|
-
return await this.render(params)
|
|
123
|
+
return await this.render(params, opts)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/**
|
package/lib/decorate.js
CHANGED
|
@@ -19,12 +19,12 @@ async function isCacheable (req, cachedUrls) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async function decorate () {
|
|
22
|
-
const { importModule
|
|
22
|
+
const { importModule } = this.app.bajo
|
|
23
23
|
const buildLocals = await importModule('waibu:/lib/build-locals.js')
|
|
24
24
|
const { importPkg } = this.app.bajo
|
|
25
25
|
const { isString, cloneDeep, isEmpty, get } = this.app.lib._
|
|
26
26
|
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
27
|
-
const { outmatch
|
|
27
|
+
const { outmatch } = this.app.lib
|
|
28
28
|
const { routePath } = this.app.waibu
|
|
29
29
|
const mime = await importPkg('waibu:mime')
|
|
30
30
|
const cfg = this.config
|
|
@@ -65,9 +65,7 @@ async function decorate () {
|
|
|
65
65
|
}
|
|
66
66
|
const locals = await buildLocals.call(me, { tpl, params, opts })
|
|
67
67
|
if (!get(this.request, 'routeOptions.config.noCacheReq')) {
|
|
68
|
-
|
|
69
|
-
fs.ensureDirSync(dir)
|
|
70
|
-
fs.writeFileSync(`${dir}/locals.json`, JSON.stringify(locals, null, 2), 'utf8')
|
|
68
|
+
await me.app.cache.save(`${me.ns}.req:/${opts.req.id}-locals.json`, locals, me.config.reqTtlDur)
|
|
71
69
|
}
|
|
72
70
|
const result = await me.render(tpl, locals, opts)
|
|
73
71
|
if (ttl > 0) await setCache({ key, value: result, ttl })
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-06-01
|
|
4
|
+
|
|
5
|
+
- [2.17.1] Bug fix in ```component.buildTag()```
|
|
6
|
+
|
|
7
|
+
## 2026-05-28
|
|
8
|
+
|
|
9
|
+
- [2.17.0] Change hooks to be written in one ```hook.js``` file
|
|
10
|
+
- [2.17.0] Change model schemas to be written in one ```model.js``` file
|
|
11
|
+
|
|
3
12
|
## 2026-05-25
|
|
4
13
|
|
|
5
14
|
- [2.16.0] Add theme & iconset auto detection mechanism
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
async function checkLang (req, reply) {
|
|
2
|
-
if (!req.session) return
|
|
3
|
-
if (req.langDetector) {
|
|
4
|
-
req.session.lang = req.lang
|
|
5
|
-
return
|
|
6
|
-
}
|
|
7
|
-
if (req.session.lang) req.lang = req.session.lang
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
async function checkDark (req, reply) {
|
|
11
|
-
const { isSet } = this.app.lib.aneka
|
|
12
|
-
const key = this.config.darkMode.qsKey
|
|
13
|
-
const value = this.config.darkMode.set ?? req.query[key]
|
|
14
|
-
if (isSet(value)) {
|
|
15
|
-
req.darkMode = value
|
|
16
|
-
if (req.session) req.session.darkMode = req.darkMode
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
if (isSet(req.session.darkMode)) req.darkMode = req.session.darkMode
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const waibuMpaPreParsing = {
|
|
23
|
-
level: 9,
|
|
24
|
-
handler: async function (req, reply) {
|
|
25
|
-
const { importModule } = this.app.bajo
|
|
26
|
-
const attachIntl = await importModule('waibu:/lib/webapp-scope/attach-intl.js')
|
|
27
|
-
await attachIntl.call(this, this.config.intl.detectors, req, reply)
|
|
28
|
-
await checkLang.call(this, req, reply)
|
|
29
|
-
await checkDark.call(this, req, reply)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default waibuMpaPreParsing
|