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.
- package/.jsdoc.conf.json +1 -1
- package/docs/WaibuDb.html +1 -1
- package/docs/data/search.json +1 -1
- package/docs/external-DoboModel.html +3 -0
- package/docs/external-TFilter.html +3 -0
- package/docs/external-TOptions.html +3 -0
- package/docs/global.html +1 -1
- package/docs/index.html +1 -1
- package/docs/index.js.html +109 -85
- package/docs/lib_config.js.html +48 -0
- package/docs/lib_crud_add-handler.js.html +82 -0
- package/docs/lib_crud_all-handler.js.html +81 -0
- package/docs/lib_crud_delete-handler.js.html +67 -0
- package/docs/lib_crud_details-handler.js.html +55 -0
- package/docs/lib_crud_edit-handler.js.html +90 -0
- package/docs/lib_crud_export-handler.js.html +72 -0
- package/docs/lib_crud_helper.js.html +118 -0
- package/docs/lib_crud_list-handler.js.html +61 -0
- package/docs/lib_util.js.html +161 -0
- package/docs/module-CRUDHandler.html +24 -0
- package/docs/module-CRUDHandler_Helper.html +3 -0
- package/docs/module-Helper.html +3 -0
- package/docs/module-Helper_CRUDHandler.html +6 -0
- package/extend/waibuBootstrap/theme/component/widget/btn-export.js +2 -1
- package/index.js +80 -30
- package/lib/config.js +45 -0
- package/lib/crud/add-handler.js +31 -4
- package/lib/crud/all-handler.js +47 -1
- package/lib/crud/delete-handler.js +28 -6
- package/lib/crud/details-handler.js +29 -4
- package/lib/crud/edit-handler.js +34 -6
- package/lib/crud/export-handler.js +45 -4
- package/lib/crud/helper.js +59 -10
- package/lib/crud/list-handler.js +30 -3
- package/lib/util.js +98 -20
- package/package.json +1 -1
- package/wiki/CHANGES.md +9 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: lib/crud/helper.js</title><!--[if lt IE 9]>
|
|
2
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
3
|
+
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="light"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">WaibuDb API</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="WaibuDb.html">WaibuDb</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-CRUDHandler.html">CRUDHandler</a></div><div class="sidebar-section-children"><a href="module-CRUDHandler_Helper.html">CRUDHandler/Helper</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-externals"><div>Externals</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="external-DoboModel.html">DoboModel</a></div><div class="sidebar-section-children"><a href="external-TFilter.html">TFilter</a></div><div class="sidebar-section-children"><a href="external-TOptions.html">TOptions</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#factory">factory</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/waibu-db" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/waibu-db" target="">Github</a></div><div class="navbar-item"><a id="" href="https://waibu.bajo.app/" target="">Waibu</a></div><div class="navbar-item"><a id="" href="https://bajo.app/" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">lib_crud_helper.js</h1></header><article><pre class="prettyprint source lang-js"><code>/**
|
|
4
|
+
* @module CRUDHandler/Helper
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Add-ons handler for generating chart options based on the schema's aggregate settings.
|
|
9
|
+
*
|
|
10
|
+
* This function retrieves the aggregate settings from the schema and generates chart options for each setting.
|
|
11
|
+
* The generated chart options are encoded in base64 and returned as an array of add-ons.
|
|
12
|
+
*
|
|
13
|
+
* @async
|
|
14
|
+
* @memberof module:CRUDHandler/Helper
|
|
15
|
+
* @method
|
|
16
|
+
* @name addOnsHandler
|
|
17
|
+
* @param {object} opts - Options object
|
|
18
|
+
* @param {object} opts.req - Request object
|
|
19
|
+
* @param {object} opts.reply - Reply object
|
|
20
|
+
* @param {object} opts.schema - Schema object
|
|
21
|
+
* @returns {Promise<Array>} Array of add-ons with chart options
|
|
22
|
+
*/
|
|
23
|
+
export async function addOnsHandler (opts = {}) {
|
|
24
|
+
const { req, reply, schema } = opts
|
|
25
|
+
const { escape } = this.app.waibu
|
|
26
|
+
const { base64JsonEncode } = this.app.waibu
|
|
27
|
+
const { createAggregate } = this.app.waibuDb
|
|
28
|
+
const { get, map, pick, pullAt } = this.app.lib._
|
|
29
|
+
const _opts = map(get(schema, 'view.stat.aggregate', []), item => {
|
|
30
|
+
const dbOpts = pick(item, ['fields', 'group', 'aggregate'])
|
|
31
|
+
const name = item.name ?? `field.${item.fields[0]}`
|
|
32
|
+
return { name, dbOpts }
|
|
33
|
+
})
|
|
34
|
+
if (_opts.length === 0) return []
|
|
35
|
+
const dropped = []
|
|
36
|
+
for (const idx in _opts) {
|
|
37
|
+
const o = _opts[idx]
|
|
38
|
+
try {
|
|
39
|
+
const resp = await createAggregate({ model: schema.name, req, reply, options: o.dbOpts })
|
|
40
|
+
const data = []
|
|
41
|
+
for (const d of resp.data) {
|
|
42
|
+
const key = o.dbOpts.fields[0]
|
|
43
|
+
data.push({
|
|
44
|
+
name: escape(d[key]),
|
|
45
|
+
value: d[key + 'Count']
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
_opts[idx].chartOpts = base64JsonEncode({
|
|
49
|
+
tooltip: {
|
|
50
|
+
trigger: 'item'
|
|
51
|
+
},
|
|
52
|
+
series: [{
|
|
53
|
+
type: 'pie',
|
|
54
|
+
data
|
|
55
|
+
}]
|
|
56
|
+
})
|
|
57
|
+
} catch (err) {
|
|
58
|
+
dropped.push(idx)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (dropped.length > 0) pullAt(_opts, dropped)
|
|
62
|
+
return map(_opts, o => {
|
|
63
|
+
return {
|
|
64
|
+
data: { setting: o.chartOpts, name: o.name },
|
|
65
|
+
resource: 'waibuDb.partial:/crud/~echarts-window.html'
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Handles attachments for a given schema and ID.
|
|
72
|
+
* @async
|
|
73
|
+
* @memberof module:CRUDHandler/Helper
|
|
74
|
+
* @method
|
|
75
|
+
* @name attachmentHandler
|
|
76
|
+
* @param {object} opts - Options object
|
|
77
|
+
* @param {object} opts.schema - Schema object
|
|
78
|
+
* @param {string|number} opts.id - ID of the record
|
|
79
|
+
* @returns {Promise<Array>} Array of attachments
|
|
80
|
+
*/
|
|
81
|
+
export async function attachmentHandler (opts = {}) {
|
|
82
|
+
const { schema, id } = opts
|
|
83
|
+
if (!schema.view.attachment) return []
|
|
84
|
+
const model = this.app.dobo.getModel(schema.name)
|
|
85
|
+
return await model.listAttachment({ id })
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Builds parameters for a given model and request.
|
|
90
|
+
*
|
|
91
|
+
* @param {object} opts - Options object
|
|
92
|
+
* @param {string} opts.model - Model name
|
|
93
|
+
* @param {object} opts.req - Request object
|
|
94
|
+
* @returns {object} Parameters including page information
|
|
95
|
+
*/
|
|
96
|
+
export function buildParams (opts = {}) {
|
|
97
|
+
const { model, req } = opts
|
|
98
|
+
const { camelCase, kebabCase, map, upperFirst, get } = this.app.lib._
|
|
99
|
+
const [, ...names] = map(kebabCase(model).split('-'), n => upperFirst(n))
|
|
100
|
+
const mdl = this.app.dobo.getModel(model)
|
|
101
|
+
const prefix = this.app.waibuMpa ? this.app.waibuMpa.getPluginTitle(mdl.plugin.ns, req) : mdl.plugin.ns
|
|
102
|
+
const modelTitle = req.t(prefix) + ': ' + req.t(camelCase(names.join(' ')))
|
|
103
|
+
const page = {
|
|
104
|
+
title: req.t(get(req, 'routeOptions.config.title', this.app[mdl.plugin.ns].title)),
|
|
105
|
+
modelTitle
|
|
106
|
+
}
|
|
107
|
+
return { page }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Template path for the "not found" page.
|
|
112
|
+
* @name notFoundTpl
|
|
113
|
+
* @constant {string}
|
|
114
|
+
* @default 'waibuDb.template:/crud/not-found.html'
|
|
115
|
+
* @memberof module:CRUDHandler/Helper
|
|
116
|
+
*/
|
|
117
|
+
export const notFoundTpl = 'waibuDb.template:/crud/not-found.html'
|
|
118
|
+
</code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">WaibuDb API</a><div class="mobile-nav-links"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/waibu-db" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/waibu-db" target="">Github</a></div><div class="navbar-item"><a id="" href="https://waibu.bajo.app/" target="">Waibu</a></div><div class="navbar-item"><a id="" href="https://bajo.app/" target="">Bajo</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="WaibuDb.html">WaibuDb</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-CRUDHandler.html">CRUDHandler</a></div><div class="sidebar-section-children"><a href="module-CRUDHandler_Helper.html">CRUDHandler/Helper</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-externals"><div>Externals</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="external-DoboModel.html">DoboModel</a></div><div class="sidebar-section-children"><a href="external-TFilter.html">TFilter</a></div><div class="sidebar-section-children"><a href="external-TOptions.html">TOptions</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#factory">factory</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: lib/crud/list-handler.js</title><!--[if lt IE 9]>
|
|
2
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
3
|
+
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="light"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">WaibuDb API</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="WaibuDb.html">WaibuDb</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-CRUDHandler.html">CRUDHandler</a></div><div class="sidebar-section-children"><a href="module-CRUDHandler_Helper.html">CRUDHandler/Helper</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-externals"><div>Externals</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="external-DoboModel.html">DoboModel</a></div><div class="sidebar-section-children"><a href="external-TFilter.html">TFilter</a></div><div class="sidebar-section-children"><a href="external-TOptions.html">TOptions</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#factory">factory</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/waibu-db" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/waibu-db" target="">Github</a></div><div class="navbar-item"><a id="" href="https://waibu.bajo.app/" target="">Waibu</a></div><div class="navbar-item"><a id="" href="https://bajo.app/" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">lib_crud_list-handler.js</h1></header><article><pre class="prettyprint source lang-js"><code>/**
|
|
4
|
+
* Handle the list view for a given model, rendering the appropriate template with the retrieved data.
|
|
5
|
+
*
|
|
6
|
+
* To use this handler, you must import it first and call it with the necessary parameters. For example:
|
|
7
|
+
* ```javascript
|
|
8
|
+
* const { importModule } = this.app.bajo
|
|
9
|
+
* const listHandler = await importModule('waibuDb:/lib/crud/list-handler.js')
|
|
10
|
+
* const result = await listHandler.call(this, { model: 'YourModelName', req, reply })
|
|
11
|
+
* ```
|
|
12
|
+
* @async
|
|
13
|
+
* @memberof module:CRUDHandler
|
|
14
|
+
* @method
|
|
15
|
+
* @param {object} opts - Options object
|
|
16
|
+
* @param {object} opts.req - Request object
|
|
17
|
+
* @param {object} opts.reply - Reply object
|
|
18
|
+
* @param {string} opts.model - Model name
|
|
19
|
+
* @param {string} opts.template - Template path
|
|
20
|
+
* @param {object} [opts.params={}] - Parameters for the template
|
|
21
|
+
* @param {Function} [opts.addOnsHandler] - Add-ons handler function
|
|
22
|
+
* @param {string} [opts.templateDisabled='waibuDb.template:/disabled.html'] - Disabled template path
|
|
23
|
+
* @param {object} [opts.options={}] - Additional options
|
|
24
|
+
* @returns {Promise<string>} Renders the list view
|
|
25
|
+
*/
|
|
26
|
+
async function listHandler (opts) {
|
|
27
|
+
let {
|
|
28
|
+
req, reply, model, template, params = {}, addOnsHandler,
|
|
29
|
+
templateDisabled = 'waibuDb.template:/disabled.html', options = {}
|
|
30
|
+
} = opts
|
|
31
|
+
const { pascalCase } = this.app.lib.aneka
|
|
32
|
+
const { findRecord, getSchemaExt } = this.app.waibuDb
|
|
33
|
+
const { get, merge, isArray, upperFirst } = this.app.lib._
|
|
34
|
+
const qsKey = this.app.waibu.config.qsKey
|
|
35
|
+
|
|
36
|
+
const _opts = merge({}, { count: true, refs: '*' }, options.modelOpts)
|
|
37
|
+
model = pascalCase(model ?? req.params.model)
|
|
38
|
+
const mdl = this.app.dobo.getModel(model)
|
|
39
|
+
const { schema } = await getSchemaExt(model, 'list', merge({ args: [{ req, model: mdl }] }, { params }, options))
|
|
40
|
+
if (schema.disabled.includes('find')) return await reply.view(templateDisabled, { action: 'list' })
|
|
41
|
+
for (const key of ['sort', 'limit', 'fields']) {
|
|
42
|
+
const sessKey = `wdb${model}${upperFirst(key)}`
|
|
43
|
+
if (!req.query[qsKey[key]]) req.query[qsKey[key]] = req.session[sessKey] ?? get(schema, `view.qs.${key}`)
|
|
44
|
+
else req.session[sessKey] = req.query[qsKey[key]]
|
|
45
|
+
}
|
|
46
|
+
if (!req.query[qsKey.page]) req.query[qsKey.page] = 1
|
|
47
|
+
// req.query.attachment = true
|
|
48
|
+
const list = await findRecord({ model, req, options: _opts })
|
|
49
|
+
let addOns = []
|
|
50
|
+
if (addOnsHandler) {
|
|
51
|
+
addOns = await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: list, schema, options })
|
|
52
|
+
if (!isArray(addOns)) addOns = [addOns]
|
|
53
|
+
}
|
|
54
|
+
merge(params, { list, schema, addOns })
|
|
55
|
+
if (schema.template) template = schema.template
|
|
56
|
+
if (schema.layout) params.page.layout = schema.layout
|
|
57
|
+
return await reply.view(template, params)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default listHandler
|
|
61
|
+
</code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">WaibuDb API</a><div class="mobile-nav-links"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/waibu-db" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/waibu-db" target="">Github</a></div><div class="navbar-item"><a id="" href="https://waibu.bajo.app/" target="">Waibu</a></div><div class="navbar-item"><a id="" href="https://bajo.app/" target="">Bajo</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="WaibuDb.html">WaibuDb</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-CRUDHandler.html">CRUDHandler</a></div><div class="sidebar-section-children"><a href="module-CRUDHandler_Helper.html">CRUDHandler/Helper</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-externals"><div>Externals</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="external-DoboModel.html">DoboModel</a></div><div class="sidebar-section-children"><a href="external-TFilter.html">TFilter</a></div><div class="sidebar-section-children"><a href="external-TOptions.html">TOptions</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#factory">factory</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: lib/util.js</title><!--[if lt IE 9]>
|
|
2
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
3
|
+
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="light"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">WaibuDb API</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="WaibuDb.html">WaibuDb</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-CRUDHandler.html">CRUDHandler</a></div><div class="sidebar-section-children"><a href="module-CRUDHandler_Helper.html">CRUDHandler/Helper</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-externals"><div>Externals</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="external-DoboModel.html">DoboModel</a></div><div class="sidebar-section-children"><a href="external-TFilter.html">TFilter</a></div><div class="sidebar-section-children"><a href="external-TOptions.html">TOptions</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#factory">factory</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/waibu-db" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/waibu-db" target="">Github</a></div><div class="navbar-item"><a id="" href="https://waibu.bajo.app/" target="">Waibu</a></div><div class="navbar-item"><a id="" href="https://bajo.app/" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">lib_util.js</h1></header><article><pre class="prettyprint source lang-js"><code>/**
|
|
4
|
+
* @module Helper
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @external DoboModel
|
|
9
|
+
* @see {@link https://ardhi.github.io/dobo/DoboModel.html|DoboModel}
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @external TFilter
|
|
14
|
+
* @see {@link https://ardhi.github.io/dobo/DoboModel.html#.TFilter|TFilter}
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @external TOptions
|
|
19
|
+
* @see {@link https://ardhi.github.io/dobo/DoboModel.html#.TOptions|TOptions}
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Type of actions that can be performed on records in the database.
|
|
24
|
+
* @typedef TActions
|
|
25
|
+
* @type {Object}
|
|
26
|
+
* @property {number} 0='countRecord' - Count the number of records
|
|
27
|
+
* @property {number} 1='createAggregate' - Create an aggregate record
|
|
28
|
+
* @property {number} 2='createHistogram' - Create a histogram record
|
|
29
|
+
* @property {number} 3='createRecord' - Create a new record
|
|
30
|
+
* @property {number} 4='findAllRecord' - Find all records
|
|
31
|
+
* @property {number} 5='findOneRecord' - Find one record
|
|
32
|
+
* @property {number} 6='findRecord' - Find records
|
|
33
|
+
* @property {number} 7='getRecord' - Get a record
|
|
34
|
+
* @property {number} 8='removeRecord' - Remove a record
|
|
35
|
+
* @property {number} 9='updateRecord' - Update a record
|
|
36
|
+
*/
|
|
37
|
+
export const actions = ['countRecord', 'createAggregate', 'createHistogram', 'createRecord', 'findAllRecord', 'findOneRecord', 'findRecord', 'getRecord', 'removeRecord', 'updateRecord']
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Prepare CRUD operation parameters.
|
|
41
|
+
* @async
|
|
42
|
+
* @param {Object} [options={}] - Options for preparing CRUD operation
|
|
43
|
+
* @param {string|external:DoboModel} options.model - The model to operate on
|
|
44
|
+
* @param {string|number} [options.id] - The record ID
|
|
45
|
+
* @param {Object} [options.req] - The request object
|
|
46
|
+
* @param {Object} [options.reply] - The reply object
|
|
47
|
+
* @param {Object} [options.transaction] - The transaction object
|
|
48
|
+
* @param {Object} [options.options] - Additional options
|
|
49
|
+
* @param {Array} [options.args] - Additional arguments
|
|
50
|
+
* @returns {Object} Prepared CRUD parameters
|
|
51
|
+
*/
|
|
52
|
+
export async function prepCrud (options = {}) {
|
|
53
|
+
let { model, id, req, reply, transaction, options: _options = {}, args } = options
|
|
54
|
+
const { isSet } = this.app.lib.aneka
|
|
55
|
+
const { importModule } = this.app.bajo
|
|
56
|
+
const { parseFilter } = this.app.waibu
|
|
57
|
+
const { pascalCase } = this.app.lib.aneka
|
|
58
|
+
const { cloneDeep, has, isString, omit } = this.app.lib._
|
|
59
|
+
const { parseObject } = this.app.lib
|
|
60
|
+
const { buildFilterQuery, buildFilterSearch } = await importModule('dobo:/lib/factory/model/helper.js', { asDefaultImport: false })
|
|
61
|
+
|
|
62
|
+
const cfgWeb = this.app.waibu.getConfig()
|
|
63
|
+
const opts = cloneDeep(omit(_options, ['trx']))
|
|
64
|
+
opts.throwNotFound = true
|
|
65
|
+
if (opts.suppressError === true) opts.suppressError = actions
|
|
66
|
+
else if (isString(opts.suppressError)) opts.suppressError = [opts.suppressError]
|
|
67
|
+
else opts.suppressError = opts.suppressError ?? []
|
|
68
|
+
const params = this.getParams(req, ...args)
|
|
69
|
+
for (const k of ['count', 'fields']) {
|
|
70
|
+
opts[k] = opts[k] ?? params[k]
|
|
71
|
+
}
|
|
72
|
+
if (has(_options, 'count')) opts.count = _options.count
|
|
73
|
+
opts.dataOnly = opts.dataOnly ?? false
|
|
74
|
+
opts.req = req
|
|
75
|
+
opts.reply = reply
|
|
76
|
+
opts.trx = opts.trx ?? _options.trx ?? transaction ?? true
|
|
77
|
+
|
|
78
|
+
let { attachment, stats, mimeType } = opts
|
|
79
|
+
attachment = attachment ?? req.query.attachment
|
|
80
|
+
stats = stats ?? req.query.stats
|
|
81
|
+
mimeType = mimeType ?? req.query.mimeType
|
|
82
|
+
|
|
83
|
+
let refs = []
|
|
84
|
+
const headers = parseObject(req.headers, { parseValue: true })
|
|
85
|
+
if (isSet(headers['x-count'])) _options.count = headers['x-count']
|
|
86
|
+
if (isSet(headers['x-refs'])) refs = headers['x-refs']
|
|
87
|
+
if (typeof refs === 'string' && !['*', 'all'].includes(refs)) refs = [refs]
|
|
88
|
+
if (refs.length > 0) _options.refs = refs
|
|
89
|
+
|
|
90
|
+
const recId = id ?? params.id ?? req.query.id
|
|
91
|
+
let mdl = model
|
|
92
|
+
if (!model || isString(model)) {
|
|
93
|
+
model = model ?? pascalCase(params.model)
|
|
94
|
+
mdl = this.app.dobo.getModel(model)
|
|
95
|
+
}
|
|
96
|
+
opts.bboxLatField = req.query[cfgWeb.qsKey.bboxLatField]
|
|
97
|
+
opts.bboxLngField = req.query[cfgWeb.qsKey.bboxLngField]
|
|
98
|
+
const filter = parseFilter(req)
|
|
99
|
+
filter.query = buildFilterQuery.call(mdl, filter)
|
|
100
|
+
filter.search = buildFilterSearch.call(mdl, filter)
|
|
101
|
+
if (_options.query) filter.query = cloneDeep(_options.query)
|
|
102
|
+
if (_options.search) filter.search = cloneDeep(_options.search)
|
|
103
|
+
if (_options.limit) filter.limit = _options.limit
|
|
104
|
+
if (_options.sort) filter.sort = _options.sort
|
|
105
|
+
if (_options.page) filter.page = _options.page
|
|
106
|
+
if (opts.fields && opts.fields.length > 0 && mdl.hasProperty('_immutable')) opts.fields.push('_immutable')
|
|
107
|
+
const input = cloneDeep(req.body) ?? {}
|
|
108
|
+
return { model: mdl, input, recId, opts, filter, attachment, stats, mimeType }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get a single record from the database based on the provided model, ID, filter, and options.
|
|
113
|
+
* @async
|
|
114
|
+
* @param {external:DoboModel} model - The model to query
|
|
115
|
+
* @param {string|number} id - The ID of the record to retrieve
|
|
116
|
+
* @param {external:TFilter} [filter={}] - The filter criteria for the query
|
|
117
|
+
* @param {external:TOptions} [options={}] - Additional options for the query
|
|
118
|
+
* @returns {Promise<Object>} The retrieved record
|
|
119
|
+
*/
|
|
120
|
+
export async function getOneRecord (model, id, filter = {}, options = {}) {
|
|
121
|
+
const { cloneDeep, pick, isEmpty } = this.app.lib._
|
|
122
|
+
let query = cloneDeep(filter.query || {})
|
|
123
|
+
query = { $and: [query, { id }] }
|
|
124
|
+
const opts = pick(options, ['forceNoHidden', 'trx', 'req', 'refs', 'fmt'])
|
|
125
|
+
opts.dataOnly = false
|
|
126
|
+
const data = await model.findOneRecord({ query }, opts)
|
|
127
|
+
if (isEmpty(data.data) && options.throwNotFound) throw this.error('_notFound')
|
|
128
|
+
return data
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Process a database operation with error suppression and transaction handling.
|
|
133
|
+
* @async
|
|
134
|
+
* @param {Object} [opts={}] - Options for processing the handler
|
|
135
|
+
* @param {string} opts.action - The action to perform (e.g., 'createRecord', 'updateRecord')
|
|
136
|
+
* @param {external:DoboModel} opts.model - The model to operate on
|
|
137
|
+
* @param {Function} opts.handler - The handler function to execute
|
|
138
|
+
* @param {external:TOptions} [opts.options] - Additional options for the handler
|
|
139
|
+
*/
|
|
140
|
+
export async function processHandler (opts = {}) {
|
|
141
|
+
const { action, model, handler, options } = opts
|
|
142
|
+
function suppressedReturn (err) {
|
|
143
|
+
this.log.error(err)
|
|
144
|
+
if (action === 'countRecord') return options.dataOnly ? 0 : { data: 0, warnings: [options.req.t('supppressedError')] }
|
|
145
|
+
if (['createRecord', 'getRecord'].includes(action)) return options.dataOnly ? {} : { data: {}, warnings: [options.req.t('supppressedError')] }
|
|
146
|
+
if (action === 'removeRecord') return options.dataOnly ? {} : { oldData: {}, warnings: [options.req.t('supppressedError')] }
|
|
147
|
+
if (action === 'updateRecord') return options.dataOnly ? {} : { data: {}, oldData: {}, warnings: [options.req.t('supppressedError')] }
|
|
148
|
+
return options.dataOnly ? [] : { data: [], count: 0, page: 1, warnings: [options.req.t('supppressedError')] }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
if (options.trx === true && ['createRecord', 'updateRecord', 'upsertRecord', 'removeRecord'].includes(action)) {
|
|
153
|
+
return await model.transaction(handler, action, options)
|
|
154
|
+
}
|
|
155
|
+
return await handler()
|
|
156
|
+
} catch (err) {
|
|
157
|
+
if (options.suppressError.includes(action)) return suppressedReturn.call(this, err)
|
|
158
|
+
throw err
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
</code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">WaibuDb API</a><div class="mobile-nav-links"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/waibu-db" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/waibu-db" target="">Github</a></div><div class="navbar-item"><a id="" href="https://waibu.bajo.app/" target="">Waibu</a></div><div class="navbar-item"><a id="" href="https://bajo.app/" target="">Bajo</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="WaibuDb.html">WaibuDb</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-CRUDHandler.html">CRUDHandler</a></div><div class="sidebar-section-children"><a href="module-CRUDHandler_Helper.html">CRUDHandler/Helper</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-externals"><div>Externals</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="external-DoboModel.html">DoboModel</a></div><div class="sidebar-section-children"><a href="external-TFilter.html">TFilter</a></div><div class="sidebar-section-children"><a href="external-TOptions.html">TOptions</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#factory">factory</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|