dobo 2.14.0 → 2.14.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.
- package/index.js +9 -7
- package/lib/factory/model/count-record.js +3 -0
- package/lib/factory/model/create-aggregate.js +3 -0
- package/lib/factory/model/create-histogram.js +3 -0
- package/lib/factory/model/create-record.js +3 -0
- package/lib/factory/model/find-all-record.js +20 -4
- package/lib/factory/model/find-one-record.js +7 -3
- package/lib/factory/model/find-record.js +3 -1
- package/lib/factory/model/get-record.js +3 -0
- package/lib/factory/model/remove-record.js +3 -0
- package/lib/factory/model/sanitize-record.js +4 -2
- package/lib/factory/model/update-record.js +3 -0
- package/lib/factory/model/upsert-record.js +3 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -150,13 +150,14 @@ async function factory (pkgName) {
|
|
|
150
150
|
filter: {
|
|
151
151
|
limit: 25, // num of records per page
|
|
152
152
|
maxLimit: 200, // max num of records per page
|
|
153
|
-
hardCap: 10000, // max returned records
|
|
154
153
|
maxPage: 50, // max allowed page number
|
|
155
154
|
sort: ['dt:-1', 'updatedAt:-1', 'updated_at:-1', 'createdAt:-1', 'createdAt:-1', 'ts:-1', 'username', 'name']
|
|
156
155
|
},
|
|
157
156
|
cache: {
|
|
158
157
|
ttlDur: '10s'
|
|
159
|
-
}
|
|
158
|
+
},
|
|
159
|
+
hardCap: 10000, // max returned records
|
|
160
|
+
warnings: true
|
|
160
161
|
},
|
|
161
162
|
memDb: {
|
|
162
163
|
autoSaveDur: '1s'
|
|
@@ -497,12 +498,13 @@ async function factory (pkgName) {
|
|
|
497
498
|
getDefaultValues = (options = {}) => {
|
|
498
499
|
const { get } = this.app.lib._
|
|
499
500
|
const config = this.app.dobo.config
|
|
500
|
-
const limit = get(options, 'req.site.setting.dobo.default.limit', config.default.filter.limit)
|
|
501
|
-
const maxLimit = get(options, 'req.site.setting.dobo.default.maxLimit', config.default.filter.maxLimit)
|
|
502
|
-
const
|
|
503
|
-
const
|
|
501
|
+
const limit = get(options, 'req.site.setting.dobo.default.filter.limit', config.default.filter.limit)
|
|
502
|
+
const maxLimit = get(options, 'req.site.setting.dobo.default.filter.maxLimit', config.default.filter.maxLimit)
|
|
503
|
+
const maxPage = get(options, 'req.site.setting.dobo.default.filter.maxPage', config.default.filter.maxPage)
|
|
504
|
+
const hardCap = get(options, 'req.site.setting.dobo.default.hardCap', config.default.hardCap)
|
|
505
|
+
const warnings = get(options, 'req.site.setting.dobo.default.warnings', config.default.warnings)
|
|
504
506
|
const t = options.req ? options.req.t : this.t
|
|
505
|
-
return { limit, maxLimit, hardCap, maxPage, t }
|
|
507
|
+
return { limit, maxLimit, hardCap, maxPage, warnings, t }
|
|
506
508
|
}
|
|
507
509
|
|
|
508
510
|
handleLastPage = (params = {}, options = {}) => {
|
|
@@ -16,8 +16,11 @@ async function countRecord (...args) {
|
|
|
16
16
|
result.warnings = result.warnings ?? []
|
|
17
17
|
result.warnings.push(t('hardCapWarning%s%s', result.data, hardCap))
|
|
18
18
|
result.orgCount = result.data
|
|
19
|
+
result.hardCapped = true
|
|
19
20
|
result.data = hardCap
|
|
20
21
|
}
|
|
22
|
+
const { warnings } = getDefaultValues(options)
|
|
23
|
+
if (!warnings) delete result.warnings
|
|
21
24
|
await execDynHook.call(this, 'afterCountRecord', filter, result, options)
|
|
22
25
|
await execModelHook.call(this, 'afterCountRecord', filter, result, options)
|
|
23
26
|
await execHook.call(this, 'afterCountRecord', filter, result, options)
|
|
@@ -6,10 +6,13 @@ async function createAggregate (...args) {
|
|
|
6
6
|
const [_filter = {}, params = {}, opts = {}] = args
|
|
7
7
|
const { dataOnly = true } = opts
|
|
8
8
|
const { filter, options } = await getFilterAndOptions.call(this, _filter, opts, action)
|
|
9
|
+
const { getDefaultValues } = this.app.dobo
|
|
9
10
|
await execHook.call(this, 'beforeCreateAggregate', filter, params, options)
|
|
10
11
|
await execModelHook.call(this, 'beforeCreateAggregate', filter, params, options)
|
|
11
12
|
await execDynHook.call(this, 'beforeCreateAggregate', filter, params, options)
|
|
12
13
|
const result = (await this.driver._createAggregate(this, filter, params, options)) ?? {}
|
|
14
|
+
const { warnings } = getDefaultValues(options)
|
|
15
|
+
if (!warnings) delete result.warnings
|
|
13
16
|
await execDynHook.call(this, 'afterCreateAggregate', filter, params, result, options)
|
|
14
17
|
await execModelHook.call(this, 'afterCreateAggregate', filter, params, result, options)
|
|
15
18
|
await execHook.call(this, 'afterCreateAggregate', filter, params, result, options)
|
|
@@ -6,10 +6,13 @@ async function createHistogram (...args) {
|
|
|
6
6
|
const [_filter = {}, params = {}, opts = {}] = args
|
|
7
7
|
const { dataOnly = true } = opts
|
|
8
8
|
const { filter, options } = await getFilterAndOptions.call(this, _filter, opts, action)
|
|
9
|
+
const { getDefaultValues } = this.app.dobo
|
|
9
10
|
await execHook.call(this, 'beforeCreateHistogram', filter, params, options)
|
|
10
11
|
await execModelHook.call(this, 'beforeCreateHistogram', filter, params, options)
|
|
11
12
|
await execDynHook.call(this, 'beforeCreateHistogram', filter, params, options)
|
|
12
13
|
const result = (await this.driver._createHistogram(this, filter, params, options)) ?? {}
|
|
14
|
+
const { warnings } = getDefaultValues(options)
|
|
15
|
+
if (!warnings) delete result.warnings
|
|
13
16
|
await execDynHook.call(this, 'afterCreateHistogram', filter, params, result, options)
|
|
14
17
|
await execModelHook.call(this, 'afterCreateHistogram', filter, params, result, options)
|
|
15
18
|
await execHook.call(this, 'afterCreateHistogram', filter, params, result, options)
|
|
@@ -6,6 +6,7 @@ const action = 'createRecord'
|
|
|
6
6
|
async function createRecord (...args) {
|
|
7
7
|
if (args.length === 0) return this.action(action, ...args)
|
|
8
8
|
const [body = {}, opts = {}] = args
|
|
9
|
+
const { getDefaultValues } = this.app.dobo
|
|
9
10
|
const { isSet } = this.app.lib.aneka
|
|
10
11
|
const { runHook } = this.app.bajo
|
|
11
12
|
const { cloneDeep, get } = this.app.lib._
|
|
@@ -24,6 +25,8 @@ async function createRecord (...args) {
|
|
|
24
25
|
return
|
|
25
26
|
}
|
|
26
27
|
result = result ?? {}
|
|
28
|
+
const { warnings } = getDefaultValues(options)
|
|
29
|
+
if (!warnings) delete result.warnings
|
|
27
30
|
if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
|
|
28
31
|
if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
|
|
29
32
|
await handleReq.call(this, result.data.id, 'created', options)
|
|
@@ -3,11 +3,13 @@ const action = 'findAllRecord'
|
|
|
3
3
|
|
|
4
4
|
async function native (...args) {
|
|
5
5
|
const { isSet } = this.app.lib.aneka
|
|
6
|
-
const {
|
|
6
|
+
const { getDefaultValues, t } = this.app.dobo
|
|
7
|
+
const { cloneDeep, pick, omit } = this.app.lib._
|
|
7
8
|
const [params = {}, opts = {}] = args
|
|
8
9
|
const { dataOnly = true } = opts
|
|
9
10
|
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
10
11
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
12
|
+
const { hardCap, warnings } = getDefaultValues(options)
|
|
11
13
|
if (dataOnly) options.count = false
|
|
12
14
|
let { noResultSanitizer, noCache } = options
|
|
13
15
|
await execHook.call(this, 'beforeFindRecord', filter, options)
|
|
@@ -25,7 +27,19 @@ async function native (...args) {
|
|
|
25
27
|
return dataOnly ? result.data : result
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
|
-
|
|
30
|
+
let result = options.record ?? (await this.driver._findAllRecord(this, filter, options)) ?? {}
|
|
31
|
+
result.limit = filter.limit
|
|
32
|
+
result.filter = pick(filter, ['query', 'match', 'sort'])
|
|
33
|
+
result.warnings = result.warnings ?? []
|
|
34
|
+
if (!options.count) result = omit(result, ['count', 'pages'])
|
|
35
|
+
else if (options.count && result.count > hardCap) {
|
|
36
|
+
result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
|
|
37
|
+
result.count = hardCap
|
|
38
|
+
result.hardCapped = true
|
|
39
|
+
}
|
|
40
|
+
result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
|
|
41
|
+
if (!warnings) delete result.warnings
|
|
42
|
+
|
|
29
43
|
if (!noResultSanitizer) {
|
|
30
44
|
for (const idx in result.data) {
|
|
31
45
|
result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
|
|
@@ -48,7 +62,7 @@ async function loop (...args) {
|
|
|
48
62
|
const [params = {}, opts = {}] = args
|
|
49
63
|
const { dataOnly = true } = opts
|
|
50
64
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
51
|
-
const { maxLimit, hardCap } = getDefaultValues(options)
|
|
65
|
+
const { maxLimit, hardCap, warnings: showWarnings } = getDefaultValues(options)
|
|
52
66
|
const nFilter = cloneDeep(filter || {})
|
|
53
67
|
const nOptions = cloneOptions.call(this, options)
|
|
54
68
|
nOptions.count = false
|
|
@@ -71,7 +85,9 @@ async function loop (...args) {
|
|
|
71
85
|
count = count + result.data.length
|
|
72
86
|
nFilter.page++
|
|
73
87
|
}
|
|
74
|
-
|
|
88
|
+
const result = { data, count, warnings }
|
|
89
|
+
if (!showWarnings) delete result.warnings
|
|
90
|
+
return dataOnly ? data : result
|
|
75
91
|
}
|
|
76
92
|
|
|
77
93
|
async function findAllRecord (...args) {
|
|
@@ -4,6 +4,7 @@ const action = 'findOneRecord'
|
|
|
4
4
|
|
|
5
5
|
async function findOneRecord (...args) {
|
|
6
6
|
if (args.length === 0) return this.action(action, ...args)
|
|
7
|
+
const { getDefaultValues } = this.app.dobo
|
|
7
8
|
const [params = {}, opts = {}] = args
|
|
8
9
|
const { cloneDeep } = this.app.lib._
|
|
9
10
|
const { dataOnly = true } = opts
|
|
@@ -13,9 +14,12 @@ async function findOneRecord (...args) {
|
|
|
13
14
|
nOptions.count = false
|
|
14
15
|
nOptions.dataOnly = false
|
|
15
16
|
nFilter.limit = 1
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
17
|
+
const { warnings } = getDefaultValues(nOptions)
|
|
18
|
+
const resp = await this.findRecord(nFilter, nOptions)
|
|
19
|
+
const data = resp.data[0]
|
|
20
|
+
const result = { data, cached: resp.cached, warnings: resp.warnings }
|
|
21
|
+
if (!warnings) delete result.warnings
|
|
22
|
+
return dataOnly ? data : result
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export default findOneRecord
|
|
@@ -73,7 +73,7 @@ async function findRecord (...args) {
|
|
|
73
73
|
const { dataOnly = true } = opts
|
|
74
74
|
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
75
75
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
76
|
-
const { hardCap } = getDefaultValues(options)
|
|
76
|
+
const { hardCap, warnings } = getDefaultValues(options)
|
|
77
77
|
if (dataOnly) options.count = false
|
|
78
78
|
let { noResultSanitizer, noCache } = options
|
|
79
79
|
await execHook.call(this, 'beforeFindRecord', filter, options)
|
|
@@ -100,8 +100,10 @@ async function findRecord (...args) {
|
|
|
100
100
|
else if (options.count && result.count > hardCap) {
|
|
101
101
|
result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
|
|
102
102
|
result.count = hardCap
|
|
103
|
+
result.hardCapped = true
|
|
103
104
|
}
|
|
104
105
|
result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
|
|
106
|
+
if (!warnings) delete result.warnings
|
|
105
107
|
|
|
106
108
|
if (!noResultSanitizer) {
|
|
107
109
|
for (const idx in result.data) {
|
|
@@ -45,6 +45,7 @@ const action = 'getRecord'
|
|
|
45
45
|
async function getRecord (...args) {
|
|
46
46
|
if (args.length === 0) return this.action(action, ...args)
|
|
47
47
|
let [id, opts = {}] = args
|
|
48
|
+
const { getDefaultValues } = this.app.dobo
|
|
48
49
|
const { isEmpty } = this.app.lib._
|
|
49
50
|
const { isSet } = this.app.lib.aneka
|
|
50
51
|
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
@@ -66,6 +67,8 @@ async function getRecord (...args) {
|
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
|
|
70
|
+
const { warnings } = getDefaultValues(options)
|
|
71
|
+
if (!warnings) delete result.warnings
|
|
69
72
|
if (isEmpty(result.data) && !options.throwNotFound) return dataOnly ? undefined : { data: undefined }
|
|
70
73
|
if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
|
|
71
74
|
if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
|
|
@@ -34,6 +34,7 @@ const action = 'removeRecord'
|
|
|
34
34
|
async function removeRecord (...args) {
|
|
35
35
|
if (args.length === 0) return this.action(action, ...args)
|
|
36
36
|
let [id, opts = {}] = args
|
|
37
|
+
const { getDefaultValues } = this.app.dobo
|
|
37
38
|
const { isSet } = this.app.lib.aneka
|
|
38
39
|
const { runHook } = this.app.bajo
|
|
39
40
|
const { dataOnly = true } = opts
|
|
@@ -48,6 +49,8 @@ async function removeRecord (...args) {
|
|
|
48
49
|
await runHook('cache:clear', this, 'remove', id)
|
|
49
50
|
return
|
|
50
51
|
}
|
|
52
|
+
const { warnings } = getDefaultValues(options)
|
|
53
|
+
if (!warnings) delete result.warnings
|
|
51
54
|
if (!noResultSanitizer) result.oldData = await this.sanitizeRecord(result.oldData, options)
|
|
52
55
|
if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
|
|
53
56
|
await handleReq.call(this, result.oldData.id, 'removed', options)
|
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
*/
|
|
12
12
|
async function sanitizeRecord (record = {}, opts = {}) {
|
|
13
13
|
const { fields = [], hidden = [], forceNoHidden } = opts
|
|
14
|
-
const { isEmpty, map, without } = this.app.lib._
|
|
14
|
+
const { isEmpty, map, without, isArray } = this.app.lib._
|
|
15
15
|
const { fillObject } = this.app.lib.aneka
|
|
16
|
-
|
|
16
|
+
let allHidden = without([...this.hidden, ...hidden], 'id')
|
|
17
|
+
if (forceNoHidden === true) allHidden = []
|
|
18
|
+
else if (isArray(forceNoHidden)) allHidden = without(allHidden, ...forceNoHidden)
|
|
17
19
|
let newFields = [...fields]
|
|
18
20
|
if (isEmpty(newFields)) newFields = map(this.properties, prop => prop.name)
|
|
19
21
|
if (!newFields.includes('id')) newFields.unshift('id')
|
|
@@ -47,6 +47,7 @@ const action = 'updateRecord'
|
|
|
47
47
|
async function updateRecord (...args) {
|
|
48
48
|
if (args.length === 0) return this.action(action, ...args)
|
|
49
49
|
let [id, body = {}, opts = {}] = args
|
|
50
|
+
const { getDefaultValues } = this.app.dobo
|
|
50
51
|
const { isSet } = this.app.lib.aneka
|
|
51
52
|
const { runHook } = this.app.bajo
|
|
52
53
|
const { cloneDeep, get, omit } = this.app.lib._
|
|
@@ -69,6 +70,8 @@ async function updateRecord (...args) {
|
|
|
69
70
|
await runHook('cache:clear', this, 'update', id, body)
|
|
70
71
|
return
|
|
71
72
|
}
|
|
73
|
+
const { warnings } = getDefaultValues(options)
|
|
74
|
+
if (!warnings) delete result.warnings
|
|
72
75
|
if (!noResultSanitizer) {
|
|
73
76
|
result.data = await this.sanitizeRecord(result.data, options)
|
|
74
77
|
result.oldData = await this.sanitizeRecord(result.oldData, options)
|
|
@@ -3,6 +3,7 @@ const action = 'upsertRecord'
|
|
|
3
3
|
|
|
4
4
|
async function native (body = {}, opts = {}) {
|
|
5
5
|
const { isSet } = this.app.lib.aneka
|
|
6
|
+
const { getDefaultValues } = this.app.dobo
|
|
6
7
|
const { runHook } = this.app.bajo
|
|
7
8
|
const { cloneDeep, get } = this.app.lib._
|
|
8
9
|
const { dataOnly = true } = opts
|
|
@@ -19,6 +20,8 @@ async function native (body = {}, opts = {}) {
|
|
|
19
20
|
await runHook('cache:clear', this, 'upsert', body)
|
|
20
21
|
return
|
|
21
22
|
}
|
|
23
|
+
const { warnings } = getDefaultValues(options)
|
|
24
|
+
if (!warnings) delete result.warnings
|
|
22
25
|
if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
|
|
23
26
|
if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
|
|
24
27
|
await handleReq.call(this, result.data.id, 'upserted', options)
|