dobo 2.19.1 → 2.20.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.
- package/lib/factory/model/_util.js +9 -0
- package/lib/factory/model/find-all-record.js +33 -28
- package/lib/factory/model/find-record.js +34 -29
- package/lib/factory/model/get-record.js +21 -17
- package/lib/factory/model/remove-record.js +2 -1
- package/lib/factory/model/update-record.js +2 -1
- package/lib/factory/model/upsert-record.js +3 -2
- package/package.json +1 -1
- package/wiki/CHANGES.md +4 -3
|
@@ -430,3 +430,12 @@ export function preparePagination (filter = {}, options = {}) {
|
|
|
430
430
|
const sort = buildSort(sortInput, options.allowSortUnindexed)
|
|
431
431
|
return { limit, page, skip, sort }
|
|
432
432
|
}
|
|
433
|
+
|
|
434
|
+
export async function clearCache (id) {
|
|
435
|
+
const { clear } = this.app.bajoCache
|
|
436
|
+
if (!clear) return
|
|
437
|
+
await clear({ key: `dobo|${this.name}|getRecord|${id}` })
|
|
438
|
+
await clear({ key: `dobo|${this.name}|findRecord` })
|
|
439
|
+
await clear({ key: `dobo|${this.name}|findAllRecord` })
|
|
440
|
+
await clear({ key: `dobo|${this.name}|findOneRecord` })
|
|
441
|
+
}
|
|
@@ -4,45 +4,50 @@ const action = 'findAllRecord'
|
|
|
4
4
|
async function native (...args) {
|
|
5
5
|
const { isSet } = this.app.lib.aneka
|
|
6
6
|
const { getDefaultValues, t } = this.app.dobo
|
|
7
|
-
const { pick, omit } = this.app.lib._
|
|
7
|
+
const { pick, omit, cloneDeep } = this.app.lib._
|
|
8
8
|
const [params = {}, opts = {}] = args
|
|
9
|
+
const { get, set } = this.app.bajoCache ?? {}
|
|
9
10
|
opts.dataOnly = opts.dataOnly ?? true
|
|
10
11
|
const { dataOnly } = opts
|
|
11
12
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
12
13
|
const { hardCap, warnings } = getDefaultValues(options)
|
|
13
14
|
if (dataOnly) options.count = false
|
|
14
15
|
const { noResultSanitizer } = options
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
else if (options.count && result.count > hardCap) {
|
|
25
|
-
result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
|
|
26
|
-
result.count = hardCap
|
|
27
|
-
result.hardCapped = true
|
|
16
|
+
await execHook.call(this, 'beforeFindRecord', filter, options)
|
|
17
|
+
await execModelHook.call(this, 'beforeFindRecord', filter, options)
|
|
18
|
+
await execDynHook.call(this, 'beforeFindRecord', filter, options)
|
|
19
|
+
const cFilter = cloneDeep(filter)
|
|
20
|
+
if (get) {
|
|
21
|
+
const resp = await get({ model: this, action, filter: cFilter, options })
|
|
22
|
+
if (resp) {
|
|
23
|
+
resp.cached = true
|
|
24
|
+
return dataOnly ? resp.data : resp
|
|
28
25
|
}
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
}
|
|
27
|
+
let result = options.record ?? (await this.driver._findAllRecord(this, filter, options)) ?? {}
|
|
28
|
+
result.limit = filter.limit
|
|
29
|
+
result.filter = pick(filter, ['query', 'match', 'sort'])
|
|
30
|
+
result.warnings = result.warnings ?? []
|
|
31
|
+
if (!options.count) result = omit(result, ['count', 'pages'])
|
|
32
|
+
else if (options.count && result.count > hardCap) {
|
|
33
|
+
result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
|
|
34
|
+
result.count = hardCap
|
|
35
|
+
result.hardCapped = true
|
|
36
|
+
}
|
|
37
|
+
result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
|
|
38
|
+
if (!warnings) delete result.warnings
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
40
|
+
if (!noResultSanitizer) {
|
|
41
|
+
for (const idx in result.data) {
|
|
42
|
+
result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
|
|
36
43
|
}
|
|
37
|
-
if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
|
|
38
|
-
await execDynHook.call(this, 'afterFindRecord', filter, result, options)
|
|
39
|
-
await execModelHook.call(this, 'afterFindRecord', filter, result, options)
|
|
40
|
-
await execHook.call(this, 'afterFindRecord', filter, result, options)
|
|
41
|
-
return dataOnly ? result.data : result
|
|
42
|
-
} catch (err) {
|
|
43
|
-
if (err.code === 'cachedResult') return err.data
|
|
44
|
-
throw err
|
|
45
44
|
}
|
|
45
|
+
if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
|
|
46
|
+
await execDynHook.call(this, 'afterFindRecord', filter, result, options)
|
|
47
|
+
await execModelHook.call(this, 'afterFindRecord', filter, result, options)
|
|
48
|
+
await execHook.call(this, 'afterFindRecord', filter, result, options)
|
|
49
|
+
if (set) await set({ model: this, action, filter: cFilter, options, result })
|
|
50
|
+
return dataOnly ? result.data : result
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
async function loop (...args) {
|
|
@@ -69,45 +69,50 @@ async function findRecord (...args) {
|
|
|
69
69
|
const { getDefaultValues, t } = this.app.dobo
|
|
70
70
|
const [params = {}, opts = {}] = args
|
|
71
71
|
const { isSet } = this.app.lib.aneka
|
|
72
|
-
const { pick, omit } = this.app.lib._
|
|
72
|
+
const { pick, omit, cloneDeep } = this.app.lib._
|
|
73
|
+
const { get, set } = this.app.bajoCache ?? {}
|
|
73
74
|
opts.dataOnly = opts.dataOnly ?? true
|
|
74
75
|
const { dataOnly } = opts
|
|
75
76
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
76
77
|
const { hardCap, warnings } = getDefaultValues(options)
|
|
77
78
|
if (dataOnly) options.count = false
|
|
78
79
|
const { noResultSanitizer } = options
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (!options.count) result = omit(result, ['count', 'pages'])
|
|
89
|
-
else if (options.count && result.count > hardCap) {
|
|
90
|
-
result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
|
|
91
|
-
result.count = hardCap
|
|
92
|
-
result.hardCapped = true
|
|
80
|
+
await execHook.call(this, 'beforeFindRecord', filter, options)
|
|
81
|
+
await execModelHook.call(this, 'beforeFindRecord', filter, options)
|
|
82
|
+
await execDynHook.call(this, 'beforeFindRecord', filter, options)
|
|
83
|
+
const cFilter = cloneDeep(filter)
|
|
84
|
+
if (get) {
|
|
85
|
+
const resp = await get({ model: this, action, filter: cFilter, options })
|
|
86
|
+
if (resp) {
|
|
87
|
+
resp.cached = true
|
|
88
|
+
return dataOnly ? resp.data : resp
|
|
93
89
|
}
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
}
|
|
91
|
+
let result = options.record ?? (await this.driver._findRecord(this, filter, options)) ?? {}
|
|
92
|
+
result.page = filter.page
|
|
93
|
+
result.limit = filter.limit
|
|
94
|
+
result.filter = pick(filter, ['query', 'search', 'sort'])
|
|
95
|
+
result.warnings = result.warnings ?? []
|
|
96
|
+
if (!options.count) result = omit(result, ['count', 'pages'])
|
|
97
|
+
else if (options.count && result.count > hardCap) {
|
|
98
|
+
result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
|
|
99
|
+
result.count = hardCap
|
|
100
|
+
result.hardCapped = true
|
|
101
|
+
}
|
|
102
|
+
result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
|
|
103
|
+
if (!warnings) delete result.warnings
|
|
96
104
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
105
|
+
if (!noResultSanitizer) {
|
|
106
|
+
for (const idx in result.data) {
|
|
107
|
+
result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
|
|
101
108
|
}
|
|
102
|
-
if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
|
|
103
|
-
await execDynHook.call(this, 'afterFindRecord', filter, result, options)
|
|
104
|
-
await execModelHook.call(this, 'afterFindRecord', filter, result, options)
|
|
105
|
-
await execHook.call(this, 'afterFindRecord', filter, result, options)
|
|
106
|
-
return dataOnly ? result.data : result
|
|
107
|
-
} catch (err) {
|
|
108
|
-
if (err.code === 'cachedResult') return err.data
|
|
109
|
-
throw err
|
|
110
109
|
}
|
|
110
|
+
if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
|
|
111
|
+
await execDynHook.call(this, 'afterFindRecord', filter, result, options)
|
|
112
|
+
await execModelHook.call(this, 'afterFindRecord', filter, result, options)
|
|
113
|
+
await execHook.call(this, 'afterFindRecord', filter, result, options)
|
|
114
|
+
if (set) await set({ model: this, action, filter: cFilter, options, result })
|
|
115
|
+
return dataOnly ? result.data : result
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
export default findRecord
|
|
@@ -48,29 +48,33 @@ async function getRecord (...args) {
|
|
|
48
48
|
const { getDefaultValues } = this.app.dobo
|
|
49
49
|
const { isEmpty } = this.app.lib._
|
|
50
50
|
const { isSet } = this.app.lib.aneka
|
|
51
|
+
const { get, set } = this.app.bajoCache ?? {}
|
|
51
52
|
opts.dataOnly = opts.dataOnly ?? true
|
|
52
53
|
const { dataOnly } = opts
|
|
53
54
|
const { options } = await getFilterAndOptions.call(this, null, opts, action)
|
|
54
55
|
const { noResultSanitizer } = options
|
|
55
56
|
id = this.sanitizeId(id)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
|
|
66
|
-
await execDynHook.call(this, 'afterGetRecord', id, result, options)
|
|
67
|
-
await execModelHook.call(this, 'afterGetRecord', id, result, options)
|
|
68
|
-
await execHook.call(this, 'afterGetRecord', id, result, options)
|
|
69
|
-
return dataOnly ? result.data : result
|
|
70
|
-
} catch (err) {
|
|
71
|
-
if (err.code === 'cachedResult') return err.data
|
|
72
|
-
throw err
|
|
57
|
+
await execHook.call(this, 'beforeGetRecord', id, options)
|
|
58
|
+
await execModelHook.call(this, 'beforeGetRecord', id, options)
|
|
59
|
+
await execDynHook.call(this, 'beforeGetRecord', id, options)
|
|
60
|
+
if (get) {
|
|
61
|
+
const resp = await get({ model: this, action, id, options })
|
|
62
|
+
if (resp) {
|
|
63
|
+
resp.cached = true
|
|
64
|
+
return dataOnly ? resp.data : resp
|
|
65
|
+
}
|
|
73
66
|
}
|
|
67
|
+
const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
|
|
68
|
+
const { warnings } = getDefaultValues(options)
|
|
69
|
+
if (!warnings) delete result.warnings
|
|
70
|
+
if (isEmpty(result.data) && !options.throwNotFound) return dataOnly ? undefined : { data: undefined }
|
|
71
|
+
if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
|
|
72
|
+
if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
|
|
73
|
+
await execDynHook.call(this, 'afterGetRecord', id, result, options)
|
|
74
|
+
await execModelHook.call(this, 'afterGetRecord', id, result, options)
|
|
75
|
+
await execHook.call(this, 'afterGetRecord', id, result, options)
|
|
76
|
+
if (set) await set({ model: this, action, id, options, result })
|
|
77
|
+
return dataOnly ? result.data : result
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
export default getRecord
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getFilterAndOptions, execHook, execModelHook, execDynHook, getSingleRef, handleReq } from './_util.js'
|
|
1
|
+
import { getFilterAndOptions, execHook, execModelHook, execDynHook, getSingleRef, handleReq, clearCache } from './_util.js'
|
|
2
2
|
const action = 'removeRecord'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -45,6 +45,7 @@ async function removeRecord (...args) {
|
|
|
45
45
|
await execModelHook.call(this, 'beforeRemoveRecord', id, options)
|
|
46
46
|
await execDynHook.call(this, 'beforeRemoveRecord', id, options)
|
|
47
47
|
const result = options.record ?? (await this.driver._removeRecord(this, id, options)) ?? {}
|
|
48
|
+
await clearCache.call(this, id)
|
|
48
49
|
if (noResult) return
|
|
49
50
|
const { warnings } = getDefaultValues(options)
|
|
50
51
|
if (!warnings) delete result.warnings
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook, getSingleRef, handleReq } from './_util.js'
|
|
1
|
+
import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook, getSingleRef, handleReq, clearCache } from './_util.js'
|
|
2
2
|
import { onlyTypes } from './create-record.js'
|
|
3
3
|
const action = 'updateRecord'
|
|
4
4
|
|
|
@@ -67,6 +67,7 @@ async function updateRecord (...args) {
|
|
|
67
67
|
await execDynHook.call(this, 'beforeUpdateRecord', id, input, options)
|
|
68
68
|
if (!noValidation) await execValidation.call(this, input, options)
|
|
69
69
|
const result = options.record ?? (await this.driver._updateRecord(this, id, input, options)) ?? {}
|
|
70
|
+
await clearCache.call(this, id)
|
|
70
71
|
if (noResult) return
|
|
71
72
|
const { warnings } = getDefaultValues(options)
|
|
72
73
|
if (!warnings) delete result.warnings
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getFilterAndOptions, execHook, execModelHook, execDynHook, execValidation, getSingleRef, handleReq } from './_util.js'
|
|
1
|
+
import { getFilterAndOptions, execHook, execModelHook, execDynHook, execValidation, getSingleRef, handleReq, clearCache } from './_util.js'
|
|
2
2
|
const action = 'upsertRecord'
|
|
3
3
|
|
|
4
4
|
async function native (body = {}, opts = {}) {
|
|
@@ -16,6 +16,7 @@ async function native (body = {}, opts = {}) {
|
|
|
16
16
|
await execModelHook.call(this, 'beforeUpsertRecord', input, options)
|
|
17
17
|
await execDynHook.call(this, 'beforeUpsertRecord', input, options)
|
|
18
18
|
const result = options.record ?? (await this.driver._upsertRecord(this, input, options)) ?? {}
|
|
19
|
+
await clearCache.call(this, body.id)
|
|
19
20
|
if (noResult) return
|
|
20
21
|
const { warnings } = getDefaultValues(options)
|
|
21
22
|
if (!warnings) delete result.warnings
|
|
@@ -39,7 +40,7 @@ async function manual (body = {}, options = {}) {
|
|
|
39
40
|
} catch (err) {
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
const id = get(old, '
|
|
43
|
+
const id = get(old, 'data.id')
|
|
43
44
|
if (id) return await this.updateRecord(old.data.id, omit(body, ['id']), options)
|
|
44
45
|
return await this.createRecord(body, options)
|
|
45
46
|
}
|
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## 2026-04-21
|
|
4
4
|
|
|
5
|
-
- [2.
|
|
6
|
-
- [2.
|
|
7
|
-
- [2.
|
|
5
|
+
- [2.19.1] Bug fix in ```collect-models.js```, now values are sanitized with ```parseObject()```
|
|
6
|
+
- [2.19.1] Bug fix in ```options.dataOnly``` on all model methods
|
|
7
|
+
- [2.19.1] Add ```options.noMagic```
|
|
8
|
+
- [2.20.0] Revert back to NOT using hooks for caching
|
|
8
9
|
|
|
9
10
|
## 2026-04-19
|
|
10
11
|
|