dobo 2.29.2 → 2.30.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.
@@ -27,9 +27,8 @@ async function memoryDriverFactory () {
27
27
 
28
28
  async connect (connection, noRebuild) {
29
29
  const conn = this.plugin.getConnection('memory')
30
- const { getPluginDataDir } = this.app.bajo
31
30
  const { fs } = this.app.lib
32
- const dir = `${getPluginDataDir(this.plugin.ns)}/memDb/data` // persistence dir
31
+ const dir = `${this.app.getPluginDataDir(this.plugin.ns)}/memDb/data` // persistence dir
33
32
  fs.ensureDirSync(dir)
34
33
  conn.persistences = conn.persistences ?? []
35
34
 
package/index.js CHANGED
@@ -233,13 +233,12 @@ async function factory (pkgName) {
233
233
  * @async
234
234
  */
235
235
  init = async () => {
236
- const { getPluginDataDir } = this.app.bajo
237
236
  const { fs } = this.app.lib
238
237
  await collectDrivers.call(this)
239
238
  await collectConnections.call(this)
240
239
  await collectFeatures.call(this)
241
240
  await collectModels.call(this)
242
- const attDir = `${getPluginDataDir('dobo')}/attachment`
241
+ const attDir = `${this.app.getPluginDataDir('dobo')}/attachment`
243
242
  fs.ensureDirSync(attDir)
244
243
  }
245
244
 
@@ -369,7 +368,6 @@ async function factory (pkgName) {
369
368
  sanitizeDate = (value, { inputFormat, outputFormat, silent = true } = {}) => {
370
369
  const { dayjs } = this.app.lib
371
370
  if (value === 0) return null
372
- if (!outputFormat) outputFormat = inputFormat
373
371
  const dt = dayjs(value, inputFormat)
374
372
  if (!dt.isValid()) {
375
373
  if (silent) return null
@@ -428,6 +426,19 @@ async function factory (pkgName) {
428
426
  return value + ''
429
427
  }
430
428
 
429
+ sanitizeByType = (value, type, opts = {}) => {
430
+ const { isNaN } = this.app.lib._
431
+ let result = value
432
+ if (['object', 'array'].includes(type)) result = this.sanitizeObject(value, opts)
433
+ else if (type === 'boolean') result = this.sanitizeBoolean(value)
434
+ else if (['float', 'double'].includes(type)) result = this.sanitizeFloat(value, opts)
435
+ else if (['integer', 'smallint'].includes(type)) result = this.sanitizeInt(value, opts)
436
+ else if (['string', 'text'].includes(type)) result = this.sanitizeString(result, opts)
437
+ else if (['datetime'].includes(type)) result = this.sanitizeDate(result, opts)
438
+ if (!opts.strict && isNaN(result)) result = null
439
+ return result
440
+ }
441
+
431
442
  _calcStats = (items, field, aggregates) => {
432
443
  const { generateId, isSet } = this.app.lib.aneka
433
444
  const result = { id: generateId, count: 0, avg: null, min: null, max: null }
@@ -378,7 +378,7 @@ async function driverFactory () {
378
378
  result = await this.findRecord(model, filter, options)
379
379
  await this._attachHook('afterFindRecord', model, filter, result, options)
380
380
  } catch (err) {
381
- if (err.message !== '_emptyColumnQuery') throw err
381
+ if (!['_emptyColumnQuery', '_abortAction'].includes(err.message)) throw err
382
382
  result = {
383
383
  data: [],
384
384
  count: 0
@@ -125,9 +125,8 @@ export async function mergeAttachmentInfo (rec, source, options = {}) {
125
125
  }
126
126
 
127
127
  export async function getAttachmentPath (id, field, file, options = {}) {
128
- const { getPluginDataDir } = this.app.bajo
129
128
  const { fs } = this.app.lib
130
- const dir = `${getPluginDataDir(this.app.dobo.ns)}/attachment/${this.name}/${id}`
129
+ const dir = `${this.app.getPluginDataDir(this.app.dobo.ns)}/attachment/${this.name}/${id}`
131
130
  if (options.dirOnly) return dir
132
131
  const path = field ? `${dir}/${field}/${file}` : `${dir}/${file}`
133
132
  if (!fs.existsSync(path)) throw this.app.dobo.error('notFound')
@@ -160,11 +159,10 @@ export async function copyAttachment (id, options = {}) {
160
159
 
161
160
  export async function handleAttachmentUpload (id, trigger, options = {}) {
162
161
  if (!this.options.attachment) return
163
- const { getPluginDataDir } = this.app.bajo
164
162
  const { fs } = this.app.lib
165
163
  const { req, mimeType, stats, setFile, setField } = options
166
164
  if (trigger === 'removed') {
167
- const dir = `${getPluginDataDir(this.app.dobo.ns)}/attachment/${this.name}/${id}`
165
+ const dir = `${this.app.getPluginDataDir(this.app.dobo.ns)}/attachment/${this.name}/${id}`
168
166
  await fs.remove(dir)
169
167
  return
170
168
  }
@@ -6,8 +6,7 @@ async function findAttachment (...args) {
6
6
  if (args.length === 0) return this.action(action, ...args)
7
7
  const [id, opts = {}] = args
8
8
  const { fastGlob, fs } = this.app.lib
9
- const { getPluginDataDir } = this.app.bajo
10
- const dir = `${getPluginDataDir(this.plugin.ns)}/attachment/${this.name}/${id}`
9
+ const dir = `${this.app.getPluginDataDir(this.plugin.ns)}/attachment/${this.name}/${id}`
11
10
  if (!fs.existsSync(dir)) return []
12
11
  const files = await fastGlob(`${dir}/**/*`)
13
12
  const { fullPath, stats, mimeType } = opts
@@ -6,13 +6,13 @@ async function listAttachment (...args) {
6
6
  if (args.length === 0) return this.action(action, ...args)
7
7
  const [params = {}, opts = {}] = args
8
8
  const { map, kebabCase } = this.app.lib._
9
- const { importPkg, getPluginDataDir } = this.app.bajo
9
+ const { importPkg } = this.app.bajo
10
10
  const mime = await importPkg('waibu:mime')
11
11
  const { fastGlob } = this.app.lib
12
12
 
13
13
  const { id = '*', field = '*', file = '*', type } = params
14
14
  const { uriEncoded = true } = opts
15
- const root = `${getPluginDataDir('dobo')}/attachment`
15
+ const root = `${this.app.getPluginDataDir('dobo')}/attachment`
16
16
  let pattern = `${root}/${this.name}/${id}/${field}/${file}`
17
17
  if (type === 'image') pattern += '.{jpg,jpeg,gif,png,webp,avif,svg}'
18
18
  else if (type === 'video') pattern += '.{mp4,m4v,webm,mov,qt,mkv,ogg,ogv}'
@@ -2,7 +2,6 @@ import path from 'path'
2
2
 
3
3
  async function exec ({ body, spinner, options, result, bodies } = {}) {
4
4
  const { isArray, isString } = this.app.lib._
5
- const { getPluginDataDir } = this.app.bajo
6
5
  const { fs } = this.app.lib
7
6
 
8
7
  await this.transaction(async (trx) => {
@@ -12,7 +11,7 @@ async function exec ({ body, spinner, options, result, bodies } = {}) {
12
11
  if (isString(att)) att = { field: 'file', file: att }
13
12
  const fname = path.basename(att.file)
14
13
  if (fs.existsSync(att.file)) {
15
- const dest = `${getPluginDataDir(this.plugin.ns)}/${resp.id}/${att.field}/${fname}`
14
+ const dest = `${this.app.getPluginDataDir(this.plugin.ns)}/${resp.id}/${att.field}/${fname}`
16
15
  try {
17
16
  fs.copySync(att.file, dest)
18
17
  } catch (err) {}
@@ -15,19 +15,13 @@
15
15
  async function sanitizeBody ({ body = {}, partial, strict, extFields = [], noDefault, truncateString, onlyTypes = [], action } = {}) {
16
16
  const { isSet } = this.app.lib.aneka
17
17
  const { callHandler } = this.app.bajo
18
- const { omit, has, isString, isNaN } = this.app.lib._
19
- const { sanitizeBoolean, sanitizeDate, sanitizeFloat, sanitizeInt, sanitizeObject, sanitizeString } = this.app.dobo
18
+ const { sanitizeByType } = this.app.dobo
19
+ const { omit, has, isString } = this.app.lib._
20
20
  const result = {}
21
21
 
22
22
  const sanitize = (name, type) => {
23
- // if (onlyTypes.length > 0 && !onlyTypes.includes(type)) return
24
- if (['object', 'array'].includes(type)) result[name] = sanitizeObject(result[name], { strict, action, model: this.name })
25
- else if (type === 'boolean') result[name] = sanitizeBoolean(result[name])
26
- else if (['float', 'double'].includes(type)) result[name] = sanitizeFloat(result[name], { strict })
27
- else if (['integer', 'smallint'].includes(type)) result[name] = sanitizeInt(result[name], { strict })
28
- else if (['string', 'text'].includes(type)) result[name] = sanitizeString(result[name], { strict })
29
- else if (['datetime'].includes(type)) result[name] = sanitizeDate(result[name], { input: 'native' })
30
- if (!strict && isNaN(result[name])) result[name] = null
23
+ const opts = { strict, action, model: this.name, outputFormat: 'native' }
24
+ result[name] = sanitizeByType(result[name], type, opts)
31
25
  if (['updateRecord', 'upsertRecord'].includes(action) && type === 'string' && result[name] === '') result[name] = null
32
26
  }
33
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dobo",
3
- "version": "2.29.2",
3
+ "version": "2.30.1",
4
4
  "description": "DBMS for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-06-12
4
+
5
+ - [2.30.0] Necessary updates to ```bajo@2.18.0``` specs
6
+ - [2.30.0] Add ```sanitizeByType()```
7
+ - [2.30.0] Add ```error._abortAction``` to abort an action in driver level
8
+ - [2.30.0] Refactor ```model.sanitizeBody()``` to use shared sanitizing function
9
+ - [2.30.1] Bug fix in ```model.sanitizeBody()```
10
+
3
11
  ## 2026-06-11
4
12
 
5
13
  - [2.29.1] Bug fix in ```model.sanitizeBody()```