dobo 2.27.2 → 2.28.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.
@@ -10,7 +10,7 @@ import actionFactory from './factory/action.js'
10
10
  * @param {Array} [indexes] - Container array to fill up found index
11
11
  */
12
12
  async function sanitizeProp (model, prop, indexes) {
13
- const { isEmpty, isString, keys, pick, isArray, isPlainObject, omit } = this.app.lib._
13
+ const { isEmpty, isString, keys, pick, isArray, isPlainObject, omit, isFunction } = this.app.lib._
14
14
  const allPropKeys = this.getAllPropertyKeys(model.connection.driver)
15
15
  const propType = this.constructor.propertyType
16
16
  if (isString(prop)) {
@@ -27,7 +27,7 @@ async function sanitizeProp (model, prop, indexes) {
27
27
  if (isPlainObject(item)) return pick(item, ['value', 'text'])
28
28
  return { value: item, text: item }
29
29
  })
30
- } else if (!isString(prop.values)) delete prop.values
30
+ } else if (!(isString(prop.values) || isFunction(prop.values))) delete prop.values
31
31
  if (prop.hidden) model.hidden.push(prop.name)
32
32
  if (prop.scanable) model.scanables.push(prop.scanable)
33
33
  if (prop.virtual) {
@@ -149,7 +149,6 @@ async function findAllIndexes (model, inputs = [], indexes = []) {
149
149
  */
150
150
  export async function sanitizeRef (model, models) {
151
151
  const { find, isString, pullAt } = this.app.lib._
152
- if (!models) models = this.models
153
152
  const _refKeys = []
154
153
  for (const prop of model.properties) {
155
154
  const ignored = []
@@ -339,30 +338,24 @@ async function collectModels () {
339
338
  }, { glob: ['model/*.*', 'model.*'], prefix: this.ns })
340
339
  schemas = orderBy(schemas, ['buildLevel', 'name'])
341
340
  for (const schema of schemas) {
342
- const plugin = this.app[schema.ns]
343
- delete schema.ns
344
341
  const idProp = schema.properties.find(p => p.name === 'id')
345
342
  if (!this.constructor.idTypes.includes(idProp.type)) this.fatal('invalidIdType%s%s', schema.name, this.constructor.idTypes.join(', '))
346
343
  if (idProp.type === 'string' && !has(idProp, 'maxLength')) idProp.maxLength = 50
347
- const model = new this.app.baseClass.DoboModel(plugin, omit(schema, ['beforeCreate', 'afterCreate']))
348
- schema.model = model
349
- me.models.push(model)
350
- }
351
- // last sanitizing & checking
352
- for (const schema of schemas) {
353
- const model = schema.model
354
- await sanitizeRef.call(this, model, me.models)
355
- for (const item of model.indexes) {
344
+ const plugin = this.app[schema.ns]
345
+ await sanitizeRef.call(this, schema, schemas)
346
+ for (const item of schema.indexes) {
356
347
  for (const field of item.fields) {
357
- const prop = model.properties.find(p => p.name === field)
358
- if (!prop || (prop && prop.virtual)) throw this.error('virtualFieldIn%s%s%s', field, 'index', model.name)
348
+ const prop = schema.properties.find(p => p.name === field)
349
+ if (!prop || (prop && prop.virtual)) throw this.error('virtualFieldIn%s%s%s', field, 'index', schema.name)
359
350
  }
360
351
  }
361
- for (const field of model.scanables) {
362
- const prop = model.properties.find(p => p.name === field)
363
- if (!prop || (prop && prop.virtual)) throw this.error('virtualFieldIn%s%s%s', field, 'scanable', model.name)
352
+ for (const field of schema.scanables) {
353
+ const prop = schema.properties.find(p => p.name === field)
354
+ if (!prop || (prop && prop.virtual)) throw this.error('virtualFieldIn%s%s%s', field, 'scanable', schema.name)
364
355
  }
365
- if (schema.buildEnd) await callHandler(model.plugin, schema.buildEnd, model)
356
+ if (schema.buildEnd) await callHandler(plugin, schema.buildEnd, schema)
357
+ const model = new this.app.baseClass.DoboModel(plugin, omit(schema, ['beforeCreate', 'afterCreate']))
358
+ me.models.push(model)
366
359
  }
367
360
  schemas = []
368
361
  this.log.debug('collected%s%d', this.t('model'), this.models.length)
@@ -417,17 +417,3 @@ export async function clearCache (id) {
417
417
  await clear({ key: `dobo|${this.name}|findAllRecord` })
418
418
  await clear({ key: `dobo|${this.name}|findOneRecord` })
419
419
  }
420
-
421
- export async function buildPropValues (prop, opts) {
422
- const { isString, camelCase } = this.app.lib._
423
- const { callHandler } = this.app.bajo
424
- const values = (isString(prop.values) ? await callHandler(prop.values) : [...prop.values]).map(v => {
425
- if (isString(v)) v = { value: v, text: v }
426
- if (opts.req) {
427
- const key = camelCase(`${prop.name} ${v.text}`)
428
- if (opts.req.te(key)) v.text = opts.req.t(key)
429
- }
430
- return v
431
- })
432
- return values
433
- }
@@ -1,5 +1,3 @@
1
- import { buildPropValues } from './_util.js'
2
-
3
1
  /**
4
2
  * Sanitize record to conform with the model's definition
5
3
  *
@@ -41,7 +39,7 @@ async function sanitizeRecord (record = {}, opts = {}) {
41
39
  if (!prop) continue
42
40
  let value = ['object', 'array'].includes(prop.type) ? cloneDeep(newRecord[key]) : newRecord[key]
43
41
  if (prop.values) {
44
- const values = await buildPropValues.call(this, prop, opts)
42
+ const values = await this.buildPropValues(prop, opts)
45
43
  value = (values.find(v => v.value === value) ?? {}).text ?? value
46
44
  }
47
45
  if (prop.format === false) newRecord._fmt[key] = value + ''
@@ -91,11 +91,11 @@ const validator = {
91
91
 
92
92
  async function buildFromDbModel (opts = {}) {
93
93
  const { isPlainObject, get, isEmpty, isString, keys, find, has, without } = this.app.lib._
94
- const { callHandler } = this.app.bajo
95
94
  const { fields = [], rule = {}, extFields = [] } = opts
96
95
  const obj = {}
97
96
  const { propertyType: propType } = this.app.baseClass.Dobo
98
97
  const refs = []
98
+ const me = this
99
99
 
100
100
  function getRuleKv (kvRule) {
101
101
  let key
@@ -136,12 +136,8 @@ async function buildFromDbModel (opts = {}) {
136
136
  }
137
137
  if (!['id'].includes(prop.name) && prop.required) obj = obj.required()
138
138
  if (prop.values) {
139
- let items = []
140
- if (Array.isArray(prop.values)) items = prop.values.map(item => item.value)
141
- else if (typeof prop.values === 'string') {
142
- const resp = await callHandler(prop.values)
143
- items = resp.map(item => item.value)
144
- }
139
+ const values = await me.buildPropValues(prop, opts)
140
+ const items = values.map(item => item.value)
145
141
  if (prop.type === 'array') {
146
142
  obj = obj.items(joi.string().valid(...items))
147
143
  } else obj = obj.valid(...items)
@@ -147,6 +147,20 @@ async function modelFactory () {
147
147
  return get(rec, field, null)
148
148
  }
149
149
 
150
+ buildPropValues = async (prop, opts) => {
151
+ const { isString, camelCase, isFunction } = this.app.lib._
152
+ const { callHandler } = this.app.bajo
153
+ const values = isString(prop.values) || isFunction(prop.values) ? await callHandler(this, prop.values, opts) : [...prop.values]
154
+ return values.map(v => {
155
+ if (isString(v)) v = { value: v, text: v }
156
+ if (opts.req) {
157
+ const key = camelCase(`${prop.name} ${v.text}`)
158
+ if (opts.req.te(key)) v.text = opts.req.t(key)
159
+ }
160
+ return v
161
+ })
162
+ }
163
+
150
164
  build = build
151
165
  exists = exists
152
166
  drop = drop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dobo",
3
- "version": "2.27.2",
3
+ "version": "2.28.0",
4
4
  "description": "DBMS for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-06-03
4
+
5
+ - [2.28.0] Property ```values``` can now accept a function that will be called dynamically upon used
6
+ - [2.28.0] ```_util.buildPropValues()``` now become a new model method
7
+ - [2.28.0] Bug fix in ```model.sanitizeRecord()```
8
+ - [2.28.0] Bug fix in ```model.validate()```
9
+
3
10
  ## 2026-05-30
4
11
 
5
12
  - [2.27.0] Bug fix in ```model.transaction()```