waibu-db 2.27.0 → 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.
Files changed (37) hide show
  1. package/.jsdoc.conf.json +1 -1
  2. package/docs/WaibuDb.html +1 -1
  3. package/docs/data/search.json +1 -1
  4. package/docs/external-DoboModel.html +3 -0
  5. package/docs/external-TFilter.html +3 -0
  6. package/docs/external-TOptions.html +3 -0
  7. package/docs/global.html +1 -1
  8. package/docs/index.html +1 -1
  9. package/docs/index.js.html +109 -85
  10. package/docs/lib_config.js.html +48 -0
  11. package/docs/lib_crud_add-handler.js.html +82 -0
  12. package/docs/lib_crud_all-handler.js.html +81 -0
  13. package/docs/lib_crud_delete-handler.js.html +67 -0
  14. package/docs/lib_crud_details-handler.js.html +55 -0
  15. package/docs/lib_crud_edit-handler.js.html +90 -0
  16. package/docs/lib_crud_export-handler.js.html +72 -0
  17. package/docs/lib_crud_helper.js.html +118 -0
  18. package/docs/lib_crud_list-handler.js.html +61 -0
  19. package/docs/lib_util.js.html +161 -0
  20. package/docs/module-CRUDHandler.html +24 -0
  21. package/docs/module-CRUDHandler_Helper.html +3 -0
  22. package/docs/module-Helper.html +3 -0
  23. package/docs/module-Helper_CRUDHandler.html +6 -0
  24. package/extend/waibuBootstrap/theme/component/widget/btn-export.js +2 -1
  25. package/index.js +80 -30
  26. package/lib/config.js +45 -0
  27. package/lib/crud/add-handler.js +31 -4
  28. package/lib/crud/all-handler.js +47 -1
  29. package/lib/crud/delete-handler.js +28 -6
  30. package/lib/crud/details-handler.js +29 -4
  31. package/lib/crud/edit-handler.js +34 -6
  32. package/lib/crud/export-handler.js +45 -4
  33. package/lib/crud/helper.js +59 -10
  34. package/lib/crud/list-handler.js +30 -3
  35. package/lib/util.js +98 -20
  36. package/package.json +1 -1
  37. package/wiki/CHANGES.md +9 -0
package/lib/util.js CHANGED
@@ -1,16 +1,64 @@
1
+ /**
2
+ * @module Helper
3
+ */
4
+
5
+ /**
6
+ * @external DoboModel
7
+ * @see {@link https://ardhi.github.io/dobo/DoboModel.html|DoboModel}
8
+ */
9
+
10
+ /**
11
+ * @external TFilter
12
+ * @see {@link https://ardhi.github.io/dobo/DoboModel.html#.TFilter|TFilter}
13
+ */
14
+
15
+ /**
16
+ * @external TOptions
17
+ * @see {@link https://ardhi.github.io/dobo/DoboModel.html#.TOptions|TOptions}
18
+ */
19
+
20
+ /**
21
+ * Type of actions that can be performed on records in the database.
22
+ * @typedef TActions
23
+ * @type {Object}
24
+ * @property {number} 0='countRecord' - Count the number of records
25
+ * @property {number} 1='createAggregate' - Create an aggregate record
26
+ * @property {number} 2='createHistogram' - Create a histogram record
27
+ * @property {number} 3='createRecord' - Create a new record
28
+ * @property {number} 4='findAllRecord' - Find all records
29
+ * @property {number} 5='findOneRecord' - Find one record
30
+ * @property {number} 6='findRecord' - Find records
31
+ * @property {number} 7='getRecord' - Get a record
32
+ * @property {number} 8='removeRecord' - Remove a record
33
+ * @property {number} 9='updateRecord' - Update a record
34
+ */
1
35
  export const actions = ['countRecord', 'createAggregate', 'createHistogram', 'createRecord', 'findAllRecord', 'findOneRecord', 'findRecord', 'getRecord', 'removeRecord', 'updateRecord']
2
36
 
3
- export async function prepCrud ({ model, id, req, reply, transaction, options = {}, args } = {}) {
37
+ /**
38
+ * Prepare CRUD operation parameters.
39
+ * @async
40
+ * @param {Object} [options={}] - Options for preparing CRUD operation
41
+ * @param {string|external:DoboModel} options.model - The model to operate on
42
+ * @param {string|number} [options.id] - The record ID
43
+ * @param {Object} [options.req] - The request object
44
+ * @param {Object} [options.reply] - The reply object
45
+ * @param {Object} [options.transaction] - The transaction object
46
+ * @param {Object} [options.options] - Additional options
47
+ * @param {Array} [options.args] - Additional arguments
48
+ * @returns {Object} Prepared CRUD parameters
49
+ */
50
+ export async function prepCrud (options = {}) {
51
+ let { model, id, req, reply, transaction, options: _options = {}, args } = options
4
52
  const { isSet } = this.app.lib.aneka
5
53
  const { importModule } = this.app.bajo
6
54
  const { parseFilter } = this.app.waibu
7
55
  const { pascalCase } = this.app.lib.aneka
8
56
  const { cloneDeep, has, isString, omit } = this.app.lib._
9
57
  const { parseObject } = this.app.lib
10
- const { buildFilterQuery, buildFilterSearch } = await importModule('dobo:/lib/factory/model/_util.js', { asDefaultImport: false })
58
+ const { buildFilterQuery, buildFilterSearch } = await importModule('dobo:/lib/factory/model/helper.js', { asDefaultImport: false })
11
59
 
12
60
  const cfgWeb = this.app.waibu.getConfig()
13
- const opts = cloneDeep(omit(options, ['trx']))
61
+ const opts = cloneDeep(omit(_options, ['trx']))
14
62
  opts.throwNotFound = true
15
63
  if (opts.suppressError === true) opts.suppressError = actions
16
64
  else if (isString(opts.suppressError)) opts.suppressError = [opts.suppressError]
@@ -19,11 +67,11 @@ export async function prepCrud ({ model, id, req, reply, transaction, options =
19
67
  for (const k of ['count', 'fields']) {
20
68
  opts[k] = opts[k] ?? params[k]
21
69
  }
22
- if (has(options, 'count')) opts.count = options.count
70
+ if (has(_options, 'count')) opts.count = _options.count
23
71
  opts.dataOnly = opts.dataOnly ?? false
24
72
  opts.req = req
25
73
  opts.reply = reply
26
- opts.trx = opts.trx ?? options.trx ?? transaction ?? true
74
+ opts.trx = opts.trx ?? _options.trx ?? transaction ?? true
27
75
 
28
76
  let { attachment, stats, mimeType } = opts
29
77
  attachment = attachment ?? req.query.attachment
@@ -32,10 +80,10 @@ export async function prepCrud ({ model, id, req, reply, transaction, options =
32
80
 
33
81
  let refs = []
34
82
  const headers = parseObject(req.headers, { parseValue: true })
35
- if (isSet(headers['x-count'])) options.count = headers['x-count']
83
+ if (isSet(headers['x-count'])) _options.count = headers['x-count']
36
84
  if (isSet(headers['x-refs'])) refs = headers['x-refs']
37
85
  if (typeof refs === 'string' && !['*', 'all'].includes(refs)) refs = [refs]
38
- if (refs.length > 0) options.refs = refs
86
+ if (refs.length > 0) _options.refs = refs
39
87
 
40
88
  const recId = id ?? params.id ?? req.query.id
41
89
  let mdl = model
@@ -48,16 +96,26 @@ export async function prepCrud ({ model, id, req, reply, transaction, options =
48
96
  const filter = parseFilter(req)
49
97
  filter.query = buildFilterQuery.call(mdl, filter)
50
98
  filter.search = buildFilterSearch.call(mdl, filter)
51
- if (options.query) filter.query = cloneDeep(options.query)
52
- if (options.search) filter.search = cloneDeep(options.search)
53
- if (options.limit) filter.limit = options.limit
54
- if (options.sort) filter.sort = options.sort
55
- if (options.page) filter.page = options.page
99
+ if (_options.query) filter.query = cloneDeep(_options.query)
100
+ if (_options.search) filter.search = cloneDeep(_options.search)
101
+ if (_options.limit) filter.limit = _options.limit
102
+ if (_options.sort) filter.sort = _options.sort
103
+ if (_options.page) filter.page = _options.page
56
104
  if (opts.fields && opts.fields.length > 0 && mdl.hasProperty('_immutable')) opts.fields.push('_immutable')
57
- return { model: mdl, recId, opts, filter, attachment, stats, mimeType }
105
+ const input = cloneDeep(req.body) ?? {}
106
+ return { model: mdl, input, recId, opts, filter, attachment, stats, mimeType }
58
107
  }
59
108
 
60
- export async function getOneRecord (model, id, filter, options) {
109
+ /**
110
+ * Get a single record from the database based on the provided model, ID, filter, and options.
111
+ * @async
112
+ * @param {external:DoboModel} model - The model to query
113
+ * @param {string|number} id - The ID of the record to retrieve
114
+ * @param {external:TFilter} [filter={}] - The filter criteria for the query
115
+ * @param {external:TOptions} [options={}] - Additional options for the query
116
+ * @returns {Promise<Object>} The retrieved record
117
+ */
118
+ export async function getOneRecord (model, id, filter = {}, options = {}) {
61
119
  const { cloneDeep, pick, isEmpty } = this.app.lib._
62
120
  let query = cloneDeep(filter.query || {})
63
121
  query = { $and: [query, { id }] }
@@ -68,17 +126,37 @@ export async function getOneRecord (model, id, filter, options) {
68
126
  return data
69
127
  }
70
128
 
71
- export async function processHandler ({ action, model, handler, options } = {}) {
129
+ /**
130
+ * Process a database operation with error suppression and transaction handling.
131
+ * @async
132
+ * @param {Object} [opts={}] - Options for processing the handler
133
+ * @param {string} opts.action - The action to perform (e.g., 'createRecord', 'updateRecord')
134
+ * @param {external:DoboModel} opts.model - The model to operate on
135
+ * @param {Function} opts.handler - The handler function to execute
136
+ * @param {external:TOptions} [opts.options] - Additional options for the handler
137
+ */
138
+ export async function processHandler (opts = {}) {
139
+ const { action, model, handler, options } = opts
140
+ const { req, reply } = options
141
+
142
+ const handleExport = async () => {
143
+ if (!(req.method === 'POST' && req.body._action === 'export' && options.allowExport)) return
144
+ const { importModule } = this.app.bajo
145
+ const exportHandler = await importModule('waibuDb:/lib/crud/export-handler.js')
146
+ await exportHandler.call(this, { model: model.name, req, reply })
147
+ }
148
+
72
149
  function suppressedReturn (err) {
73
150
  this.log.error(err)
74
- if (action === 'countRecord') return options.dataOnly ? 0 : { data: 0, warnings: [options.req.t('supppressedError')] }
75
- if (['createRecord', 'getRecord'].includes(action)) return options.dataOnly ? {} : { data: {}, warnings: [options.req.t('supppressedError')] }
76
- if (action === 'removeRecord') return options.dataOnly ? {} : { oldData: {}, warnings: [options.req.t('supppressedError')] }
77
- if (action === 'updateRecord') return options.dataOnly ? {} : { data: {}, oldData: {}, warnings: [options.req.t('supppressedError')] }
78
- return options.dataOnly ? [] : { data: [], count: 0, page: 1, warnings: [options.req.t('supppressedError')] }
151
+ if (action === 'countRecord') return options.dataOnly ? 0 : { data: 0, warnings: [req.t('supppressedError')] }
152
+ if (['createRecord', 'getRecord'].includes(action)) return options.dataOnly ? {} : { data: {}, warnings: [req.t('supppressedError')] }
153
+ if (action === 'removeRecord') return options.dataOnly ? {} : { oldData: {}, warnings: [req.t('supppressedError')] }
154
+ if (action === 'updateRecord') return options.dataOnly ? {} : { data: {}, oldData: {}, warnings: [req.t('supppressedError')] }
155
+ return options.dataOnly ? [] : { data: [], count: 0, page: 1, warnings: [req.t('supppressedError')] }
79
156
  }
80
157
 
81
158
  try {
159
+ await handleExport()
82
160
  if (options.trx === true && ['createRecord', 'updateRecord', 'upsertRecord', 'removeRecord'].includes(action)) {
83
161
  return await model.transaction(handler, action, options)
84
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-db",
3
- "version": "2.27.0",
3
+ "version": "2.28.0",
4
4
  "description": "DB Helper",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-07-13
4
+
5
+ - [2.28.0] Update documentations
6
+ - [2.28.0] Add feature to allow export only if `options.allowExport` is set to true
7
+
8
+ ## 2026-07-12
9
+
10
+ - [2.27.1] Bug fix in `util.js`
11
+
3
12
  ## 2026-06-29
4
13
 
5
14
  - [2.27.0] Add ```isActionAllowed()``` in ```wdb-base```