dobo 2.2.0 → 2.2.2

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/index.js CHANGED
@@ -67,22 +67,10 @@ const propertyType = {
67
67
  validator: 'boolean',
68
68
  rules: []
69
69
  },
70
- date: {
71
- validator: 'date',
72
- rules: []
73
- },
74
70
  datetime: {
75
71
  validator: 'date',
76
72
  rules: []
77
73
  },
78
- time: {
79
- validator: 'date',
80
- rules: []
81
- },
82
- timestamp: {
83
- validator: 'timestamp',
84
- rules: []
85
- },
86
74
  object: {
87
75
  validator: null,
88
76
  rules: []
@@ -304,13 +304,15 @@ async function collectModels () {
304
304
  for (const schema of schemas) {
305
305
  const plugin = this.app[schema.ns]
306
306
  delete schema.ns
307
- await sanitizeRef.call(this, schema, schemas, true)
308
307
  const idProp = schema.properties.find(p => p.name === 'id')
309
308
  if (!this.constructor.idTypes.includes(idProp.type)) this.fatal('invalidIdType%s%s', schema.name, this.constructor.idTypes.join(', '))
310
309
  if (idProp.type === 'string' && !has(idProp, 'maxLength')) idProp.maxLength = 50
311
310
  // schema.properties = without(schema.properties, undefined)
312
311
  const model = new DoboModel(plugin, schema)
313
312
  me.models.push(model)
313
+ }
314
+ for (const model of me.models) {
315
+ await sanitizeRef.call(this, model, me.models, true)
314
316
  me.log.trace('- %s', model.name)
315
317
  }
316
318
  this.log.debug('collected%s%d', this.t('model'), this.models.length)
@@ -34,7 +34,8 @@ async function driverFactory () {
34
34
  array: false,
35
35
  datetime: true
36
36
  },
37
- uniqueIndex: false
37
+ uniqueIndex: false,
38
+ nullableField: true
38
39
  }
39
40
  this.memory = false
40
41
  this.options = options
@@ -57,6 +58,17 @@ async function driverFactory () {
57
58
  delete item.id
58
59
  }
59
60
  for (const prop of model.properties) {
61
+ if (!isSet(item[prop.name]) && !this.support.nullableField) {
62
+ switch (prop.type) {
63
+ case 'datetime': item[prop.name] = new Date(0); break
64
+ case 'float':
65
+ case 'double': item[prop.name] = 0; break
66
+ case 'string':
67
+ case 'text': item[prop.name] = ''; break
68
+ case 'object': item[prop.name] = {}; break
69
+ case 'array': item[prop.name] = []; break
70
+ }
71
+ }
60
72
  if (isSet(item[prop.name]) && !this.support.propType[prop.type]) {
61
73
  if (prop.type === 'datetime') item[prop.name] = item[prop.name].toISOString()
62
74
  else if (['object', 'array'].includes(prop.type)) item[prop.name] = JSON.stringify(item[prop.name])
@@ -200,7 +212,9 @@ async function driverFactory () {
200
212
  const resp = await this.getRecord(model, id, { noHook: true })
201
213
  if (!resp.data) throw this.plugin.error('recordNotFound%s%s', id, model.name)
202
214
  options._data = resp.data
203
- const result = await this.updateRecord(model, id, this.sanitizeBody(model, body), options)
215
+ const input = this.sanitizeBody(model, body)
216
+ delete input.id
217
+ const result = await this.updateRecord(model, id, input, options)
204
218
  if (options.noResult) return
205
219
  result.oldData = this.sanitizeRecord(model, result.oldData)
206
220
  result.data = this.sanitizeRecord(model, result.data)
@@ -151,7 +151,7 @@ export async function getSingleRef (record = {}, options = {}) {
151
151
  if (!((typeof options.refs === 'string' && ['*', 'all'].includes(options.refs)) || options.refs.includes(key))) continue
152
152
  const ref = prop.ref[key]
153
153
  if (ref.fields.length === 0) continue
154
- const rModel = this.plugin.getModel(key)
154
+ const rModel = this.app.dobo.getModel(ref.model)
155
155
  const query = {}
156
156
  query[ref.propName] = record[prop.name]
157
157
  if (ref.propName === 'id') query[ref.propName] = this.sanitizeId(query[ref.propName])
@@ -182,7 +182,7 @@ export async function getMultiRefs (records = [], options = {}) {
182
182
  const ref = prop.ref[key]
183
183
  if (ref.fields.length === 0) continue
184
184
  if (ref.type !== '1:1') continue
185
- const rModel = this.plugin.getModel(key)
185
+ const rModel = this.app.dobo.getModel(ref.model)
186
186
  const matches = uniq(map(records, r => {
187
187
  let v = r[prop.name]
188
188
  if (ref.propName === 'id') v = this.sanitizeId(v)
@@ -24,7 +24,7 @@ async function createRecord (...args) {
24
24
  }
25
25
  result = result ?? {}
26
26
  if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
27
- if (isSet(options.refs)) await getSingleRef.call(this, { record: result.data, options })
27
+ if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
28
28
  await handleReq.call(this, result.data.id, 'created', options)
29
29
  await execModelHook.call(this, 'afterCreateRecord', input, result, options)
30
30
  await execHook.call(this, 'afterCreateRecord', input, result, options)
@@ -23,7 +23,7 @@ async function native (filter, options, dataOnly) {
23
23
  result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
24
24
  }
25
25
  }
26
- if (isSet(options.refs)) await getMultiRefs.call(this, { records: result.data, options })
26
+ if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
27
27
  await execModelHook.call(this, 'afterFindAllRecord', filter, result, options)
28
28
  await execHook.call(this, 'afterFindAllRecord', filter, result, options)
29
29
  if (set && !noCache) await set({ model: this.name, filter, options, result })
@@ -93,7 +93,7 @@ async function findRecord (...args) {
93
93
  result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
94
94
  }
95
95
  }
96
- if (isSet(options.refs)) await getMultiRefs.call(this, { records: result.data, options })
96
+ if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
97
97
  await execModelHook.call(this, 'afterFindRecord', filter, result, options)
98
98
  await execHook.call(this, 'afterFindRecord', filter, result, options)
99
99
  if (!noCache) await runHook('cache:setByFilter', this, filter, result)
@@ -69,7 +69,7 @@ async function getRecord (...args) {
69
69
  const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
70
70
  if (isEmpty(result.data) && !options.throwNotFound) return dataOnly ? undefined : { data: undefined }
71
71
  if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
72
- if (isSet(options.refs)) await getSingleRef.call(this, { record: result.data, options })
72
+ if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
73
73
  await execModelHook.call(this, 'afterGetRecord', id, result.data, options)
74
74
  await execHook.call(this, 'afterGetRecord', id, result, options)
75
75
  if (!noCache) await runHook('cache:setById', this, id, result)
@@ -48,7 +48,7 @@ async function removeRecord (...args) {
48
48
  return
49
49
  }
50
50
  if (!noResultSanitizer) result.oldData = await this.sanitizeRecord(result.oldData, options)
51
- if (isSet(options.refs)) await getSingleRef.call(this, { record: result.data, options })
51
+ if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
52
52
  await handleReq.call(this, result.oldData.id, 'removed', options)
53
53
  await execModelHook.call(this, 'afterRemoveRecord', id, result, options)
54
54
  await execHook.call(this, 'afterRemoveRecord', id, result, options)
@@ -16,7 +16,7 @@ async function sanitizeBody ({ body = {}, partial, strict, extFields = [], noDef
16
16
  const { isSet } = this.app.lib.aneka
17
17
  const { callHandler } = this.app.bajo
18
18
  const { omit, has, isString, isNaN } = this.app.lib._
19
- const { sanitizeBoolean, sanitizeDate, sanitizeFloat, sanitizeTimestamp, sanitizeInt, sanitizeObject, sanitizeString } = this.app.dobo
19
+ const { sanitizeBoolean, sanitizeDate, sanitizeFloat, sanitizeInt, sanitizeObject, sanitizeString } = this.app.dobo
20
20
  const result = {}
21
21
 
22
22
  const sanitize = (name, type) => {
@@ -25,14 +25,8 @@ async function sanitizeBody ({ body = {}, partial, strict, extFields = [], noDef
25
25
  else if (type === 'boolean') result[name] = sanitizeBoolean(result[name])
26
26
  else if (['float', 'double'].includes(type)) result[name] = sanitizeFloat(result[name], strict)
27
27
  else if (['integer', 'smallint'].includes(type)) result[name] = sanitizeInt(result[name], strict)
28
- else if (type === 'timestamp') result[name] = sanitizeTimestamp(result[name])
29
28
  else if (['string', 'text'].includes(type)) result[name] = sanitizeString(result[name], strict)
30
- else {
31
- for (const t of ['datetime|native', 'date|YYYY-MM-DD', 'time|HH:mm:ss']) {
32
- const [ptype, input] = t.split('|')
33
- if (ptype === type) result[name] = sanitizeDate(result[name], { input })
34
- }
35
- }
29
+ else if (['datetime'].includes(type)) result[name] = sanitizeDate(result[name], { input: 'native' })
36
30
  if (!strict && isNaN(result[name])) result[name] = null
37
31
  if (['updateRecord', 'upsertRecord'].includes(action) && type === 'string' && result[name] === '') result[name] = null
38
32
  }
@@ -70,7 +70,7 @@ async function updateRecord (...args) {
70
70
  result.data = await this.sanitizeRecord(result.data, options)
71
71
  result.oldData = await this.sanitizeRecord(result.oldData, options)
72
72
  }
73
- if (isSet(options.refs)) await getSingleRef.call(this, { record: result.data, options })
73
+ if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
74
74
  await handleReq.call(this, result.data.id, 'updated', options)
75
75
  await execModelHook.call(this, 'afterUpdateRecord', id, input, result, options)
76
76
  await execHook.call(this, 'afterUpdateRecord', id, input, result, options)
@@ -19,7 +19,7 @@ async function native (body = {}, opts = {}) {
19
19
  return
20
20
  }
21
21
  if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
22
- if (isSet(options.refs)) await getSingleRef.call(this, { record: result.data, options })
22
+ if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
23
23
  await handleReq.call(this, result.data.id, 'upserted', options)
24
24
  await execModelHook.call(this, 'afterUpsertRecord', input, result, options)
25
25
  await execHook.call(this, 'afterUpsertRecord', input, result, options)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dobo",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "DBMS for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "@tryghost/nql": "^0.12.7",
36
36
  "joi": "^18.0.2",
37
- "mingo": "^7.1.0",
37
+ "mingo": "^6.5.1",
38
38
  "ulid": "^3.0.2",
39
39
  "uuid": "^13.0.0"
40
40
  },
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-01-18
4
+
5
+ - [2.2.2] Revert back to ```mingo@6.5.1``` because of bugs in ```skip``` operation
6
+
7
+ ## 2026-01-16
8
+
9
+ - [2.2.1] Bug fix on model references
10
+
3
11
  ## 2026-01-11
4
12
 
5
13
  - [2.2.0] Any driver that support memory DB can now declare itself as in-memory DB and be handled as such