waibu-mpa 2.5.0 → 2.6.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.
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "properties": [
3
3
  "id,,100,primary,true",
4
- "session,object",
5
- "expires,datetime"
4
+ "session,object"
6
5
  ],
7
6
  "features": ["dobo:createdAt", "dobo:updatedAt"],
8
7
  "attachment": false
package/index.js CHANGED
@@ -57,7 +57,8 @@ async function factory (pkgName) {
57
57
  secure: 'auto',
58
58
  maxAge: 86400 * 7 * 1000
59
59
  },
60
- saveUninitialized: false
60
+ saveUninitialized: false,
61
+ trashOldDur: '5m'
61
62
  },
62
63
  emoji: true,
63
64
  viewEngine: {
@@ -206,9 +206,13 @@ async function componentFactory () {
206
206
  * @param {Object} params - The parameters containing options and values.
207
207
  * @returns {string} The generated `<option>` elements.
208
208
  */
209
- buildOptions = (params) => {
210
- const { isString, has, omit, find, isPlainObject, isArray, pick } = this.app.lib._
211
- const { attrToArray, attrToObject } = this.app.waibu
209
+ buildOptions = async (params) => {
210
+ const { isString, has, omit, find, isPlainObject, isArray, pick, camelCase, get } = this.app.lib._
211
+ const { attrToArray } = this.app.waibu
212
+ const { getMethod, callHandler } = this.app.bajo
213
+ let prop = {}
214
+ const schema = get(this, 'locals.schema')
215
+ if (schema) prop = find(schema.properties, { name: params.attr.name }) ?? {}
212
216
  if (!has(params.attr, 'options')) return
213
217
  const items = []
214
218
  let input = params.attr.options
@@ -216,22 +220,29 @@ async function componentFactory () {
216
220
  if (!has(params.attr, 'multiple') && values.length > 0) values = [values[0]]
217
221
  let options = []
218
222
  if (isString(input)) {
219
- if (input.includes(':')) input = attrToObject(input)
220
- else input = attrToArray(input)
223
+ if (getMethod(input, false)) {
224
+ input = await callHandler(input)
225
+ } else {
226
+ input = attrToArray(input, ';').map(item => {
227
+ const [value, text] = item.split(':')
228
+ return { value, text }
229
+ })
230
+ }
221
231
  }
222
- if (isPlainObject(params.attr.options)) {
223
- for (const key in params.attr.options) {
224
- options.push({ value: key, text: (params.attr.options[key] + '') })
232
+ if (isPlainObject(input)) {
233
+ for (const key in input) {
234
+ options.push({ value: key, text: (input[key] + '') })
225
235
  }
226
- } else if (isArray(params.attr.options)) {
227
- options = params.attr.options.map(item => {
236
+ } else if (isArray(input)) {
237
+ options = input.map(item => {
228
238
  if (isPlainObject(item)) return pick(item, ['value', 'text'])
229
239
  return { value: item, text: (item + '') }
230
240
  })
231
241
  }
232
242
  for (const opt of options) {
233
- const sel = find(values, v => opt.val === v)
234
- items.push(`<option value="${opt.val}"${sel ? ' selected' : ''}>${this.req.t(opt.text ?? opt.val)}</option>`)
243
+ const sel = find(values, v => opt.value === v)
244
+ const ttext = camelCase(`${prop.name} ${opt.text}`)
245
+ items.push(`<option value="${opt.value}"${sel ? ' selected' : ''}>${this.req.te(ttext) ? this.req.t(ttext) : (opt.text ?? opt.value)}</option>`)
235
246
  }
236
247
  params.attr = omit(params.attr, ['options'])
237
248
  return items.join('\n')
@@ -264,6 +275,7 @@ async function componentFactory () {
264
275
  * @returns {Promise<string>} The built sentence.
265
276
  */
266
277
  buildSentence = async (sentence, params = {}, extra = {}) => {
278
+ const { get } = this.app.lib._
267
279
  if (Array.isArray(sentence)) sentence = sentence.join(' ')
268
280
  const { minify, renderString } = this.app.waibuMpa
269
281
  if (extra.wrapped) sentence = '<w>' + sentence + '</w>'
@@ -272,8 +284,8 @@ async function componentFactory () {
272
284
  ext: params.ext ?? '.html',
273
285
  req: this.req,
274
286
  reply: this.reply,
275
- theme: this.theme.name,
276
- iconset: this.iconset.name
287
+ theme: get(this, 'theme.name', 'default'),
288
+ iconset: get(this, 'iconset.name', 'default')
277
289
  }
278
290
  let html = await renderString(sentence, params, opts)
279
291
  if (extra.wrapped) html = html.slice(3, html.length - 4)
@@ -4,7 +4,10 @@ async function datalistFactory () {
4
4
  super(options)
5
5
  this.component.normalizeAttr(this.params)
6
6
  this.params.tag = 'datalist'
7
- if (this.params.attr.options) this.params.html = this.component.buildOptions(this.params)
7
+ }
8
+
9
+ build = async () => {
10
+ if (this.params.attr.options) this.params.html = await this.component.buildOptions(this.params)
8
11
  }
9
12
  }
10
13
 
@@ -1,11 +1,26 @@
1
1
  import Store from './store.js'
2
2
 
3
+ async function trashOld () {
4
+ if (!this.app.dobo) return
5
+ const { get } = this.app.lib._
6
+ const { dayjs } = this.app.lib
7
+ const model = this.app.dobo.getModel('WmpaSession')
8
+ const recs = await model.findAllRecord({ sort: { createdAt: 1 } }, { noHook: true, noModelHook: true })
9
+ for (const rec of recs) {
10
+ let expires = get(rec, 'session.cookie.expires')
11
+ if (!expires) expires = dayjs(rec.createdAt).add(this.config.session.cookie.maxAge, 'ms').toISOString()
12
+ const diff = dayjs(expires).diff(dayjs())
13
+ if (diff < 0) await model.removeRecord(rec.id, { noReturn: true })
14
+ }
15
+ }
16
+
3
17
  async function sessionSetup () {
4
18
  const { importPkg, runHook } = this.app.bajo
5
19
  const [cookie, session, flash] = await importPkg('waibu:@fastify/cookie',
6
20
  'waibu:@fastify/session', 'waibu:@fastify/flash')
7
21
  const cfg = this.getConfig('session')
8
22
  if (!cfg) return
23
+ delete cfg.trashOldDur
9
24
  await runHook(`${this.ns}:beforeSessionSetup`)
10
25
  if (this.app.dobo) {
11
26
  this.sessionStore = new Store(this)
@@ -15,6 +30,11 @@ async function sessionSetup () {
15
30
  this.webAppCtx.register(session, cfg)
16
31
  this.webAppCtx.register(flash)
17
32
  await runHook(`${this.ns}:afterSessionSetup`, this.webAppCtx)
33
+
34
+ trashOld.call(this)
35
+ setInterval(() => {
36
+ trashOld.call(this)
37
+ }, this.config.session.trashOldDur)
18
38
  }
19
39
 
20
40
  export default sessionSetup
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-mpa",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "MPA support for Waibu Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -2,8 +2,16 @@
2
2
 
3
3
  ## 2026-02-18
4
4
 
5
+ - [2.6.0] Add auto trashing old session
6
+ - [2.6.0] Remove unecessary ```expires``` field in ```WmpaSession```
7
+ - [2.6.0] Change component's ```buildOptions()``` to async method to accomodate ```prop.values``` as a handler
8
+ - [2.6.0] Bug fix on theme and iconset resolver
9
+
10
+ ## 2026-02-18
11
+
5
12
  - [2.5.0] Move ```attrTo*()``` and ```base64Json*()``` to ```waibu``` because they are sometimes needed outside the ```waibu-mpa```
6
13
  - [2.5.0] Bug fix on ```component.buildOptions()```
14
+ - [2.5.1] Bug fix on ```component.buildOptions()```
7
15
 
8
16
  ## 2026-02-17
9
17