waibu-db 2.0.0 → 2.1.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 (124) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/.github/workflows/repo-lockdown.yml +24 -0
  3. package/.jsdoc.conf.json +45 -0
  4. package/LICENSE +0 -0
  5. package/README.md +31 -9
  6. package/docs/WaibuDb.html +3 -0
  7. package/docs/data/search.json +1 -0
  8. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  9. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  10. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  11. package/docs/global.html +3 -0
  12. package/docs/index.html +3 -0
  13. package/docs/index.js.html +225 -0
  14. package/docs/scripts/core.js +726 -0
  15. package/docs/scripts/core.min.js +23 -0
  16. package/docs/scripts/resize.js +90 -0
  17. package/docs/scripts/search.js +265 -0
  18. package/docs/scripts/search.min.js +6 -0
  19. package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
  20. package/docs/scripts/third-party/fuse.js +9 -0
  21. package/docs/scripts/third-party/hljs-line-num-original.js +369 -0
  22. package/docs/scripts/third-party/hljs-line-num.js +1 -0
  23. package/docs/scripts/third-party/hljs-original.js +5171 -0
  24. package/docs/scripts/third-party/hljs.js +1 -0
  25. package/docs/scripts/third-party/popper.js +5 -0
  26. package/docs/scripts/third-party/tippy.js +1 -0
  27. package/docs/scripts/third-party/tocbot.js +672 -0
  28. package/docs/scripts/third-party/tocbot.min.js +1 -0
  29. package/docs/static/bitcoin.jpeg +0 -0
  30. package/docs/static/home.md +23 -0
  31. package/docs/static/logo-ecosystem.png +0 -0
  32. package/docs/static/logo.png +0 -0
  33. package/docs/styles/clean-jsdoc-theme-base.css +1159 -0
  34. package/docs/styles/clean-jsdoc-theme-dark.css +412 -0
  35. package/docs/styles/clean-jsdoc-theme-light.css +482 -0
  36. package/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
  37. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
  38. package/docs/styles/clean-jsdoc-theme.min.css +1 -0
  39. package/extend/bajo/hook/waibu-rest-api@after-init.js +3 -2
  40. package/extend/bajo/intl/en-US.json +0 -0
  41. package/extend/bajo/intl/id.json +0 -0
  42. package/extend/bajoTemplate/partial/crud/_add-attachment.html +0 -0
  43. package/extend/bajoTemplate/partial/crud/_add-btns.html +2 -2
  44. package/extend/bajoTemplate/partial/crud/_addons.html +0 -0
  45. package/extend/bajoTemplate/partial/crud/_details-attachment.html +0 -0
  46. package/extend/bajoTemplate/partial/crud/_details-btns.html +0 -0
  47. package/extend/bajoTemplate/partial/crud/_edit-attachment.html +0 -0
  48. package/extend/bajoTemplate/partial/crud/_edit-btns.html +2 -0
  49. package/extend/bajoTemplate/partial/crud/_list-attachment.html +0 -0
  50. package/extend/bajoTemplate/partial/crud/_list-btns.html +0 -0
  51. package/extend/bajoTemplate/partial/crud/_list-footer.html +0 -0
  52. package/extend/bajoTemplate/partial/crud/add-handler.html +0 -0
  53. package/extend/bajoTemplate/partial/crud/details-handler.html +0 -0
  54. package/extend/bajoTemplate/partial/crud/edit-handler.html +0 -0
  55. package/extend/bajoTemplate/partial/crud/list-handler.html +1 -1
  56. package/extend/bajoTemplate/partial/crud/~echarts-window.html +0 -0
  57. package/extend/bajoTemplate/template/crud/add.html +0 -0
  58. package/extend/bajoTemplate/template/crud/details.html +0 -0
  59. package/extend/bajoTemplate/template/crud/edit.html +0 -0
  60. package/extend/bajoTemplate/template/crud/list.html +0 -0
  61. package/extend/bajoTemplate/template/disabled.html +0 -0
  62. package/extend/waibuBootstrap/theme/component/factory/btn-add.js +1 -1
  63. package/extend/waibuBootstrap/theme/component/factory/btn-back.js +2 -2
  64. package/extend/waibuBootstrap/theme/component/factory/btn-clone.js +1 -1
  65. package/extend/waibuBootstrap/theme/component/factory/btn-columns.js +3 -3
  66. package/extend/waibuBootstrap/theme/component/factory/btn-delete.js +2 -2
  67. package/extend/waibuBootstrap/theme/component/factory/btn-details.js +2 -2
  68. package/extend/waibuBootstrap/theme/component/factory/btn-edit.js +2 -2
  69. package/extend/waibuBootstrap/theme/component/factory/btn-export.js +1 -1
  70. package/extend/waibuBootstrap/theme/component/factory/echarts-bar.js +2 -2
  71. package/extend/waibuBootstrap/theme/component/factory/echarts-pie.js +2 -2
  72. package/extend/waibuBootstrap/theme/component/factory/echarts.js +3 -3
  73. package/extend/waibuBootstrap/theme/component/factory/form.js +2 -2
  74. package/extend/waibuBootstrap/theme/component/factory/pagination.js +3 -3
  75. package/extend/waibuBootstrap/theme/component/factory/query.js +4 -4
  76. package/extend/waibuBootstrap/theme/component/factory/recs-info.js +2 -2
  77. package/extend/waibuBootstrap/theme/component/factory/table.js +11 -11
  78. package/extend/waibuBootstrap/theme/component/wdb-base.js +0 -0
  79. package/extend/waibuMpa/extend/waibuAdmin/route/@model/@action.js +0 -0
  80. package/extend/waibuRestApi/route/@model/@id/get.js +1 -1
  81. package/extend/waibuRestApi/route/@model/@id/remove.js +1 -1
  82. package/extend/waibuRestApi/route/@model/@id/update.js +1 -1
  83. package/extend/waibuRestApi/route/@model/create.js +1 -1
  84. package/extend/waibuRestApi/route/@model/find.js +3 -3
  85. package/extend/waibuRestApi/route/@model/stat/@stat/find.js +8 -0
  86. package/index.js +144 -24
  87. package/lib/crud/add-handler.js +10 -9
  88. package/lib/crud/all-handler.js +1 -1
  89. package/lib/crud/delete-handler.js +6 -5
  90. package/lib/crud/details-handler.js +6 -6
  91. package/lib/crud/edit-handler.js +11 -12
  92. package/lib/crud/export-handler.js +5 -5
  93. package/lib/crud/helper/add-ons-handler.js +3 -3
  94. package/lib/crud/helper/attachment-handler.js +2 -2
  95. package/lib/crud/helper/build-params.js +4 -5
  96. package/lib/crud/list-handler.js +5 -5
  97. package/lib/method/count-record.js +9 -0
  98. package/lib/method/create-aggregate.js +13 -0
  99. package/lib/method/create-histogram.js +13 -0
  100. package/lib/method/create-record.js +10 -0
  101. package/lib/method/find-one-record.js +14 -0
  102. package/lib/method/find-record.js +14 -0
  103. package/lib/method/get-record.js +10 -0
  104. package/{method → lib/method}/get-schema-ext.js +16 -17
  105. package/lib/method/remove-record.js +9 -0
  106. package/lib/method/update-record.js +10 -0
  107. package/lib/prep-crud.js +9 -10
  108. package/package.json +15 -4
  109. package/wiki/CHANGES.md +5 -0
  110. package/wiki/CONFIG.md +3 -0
  111. package/wiki/CONTRIBUTING.md +5 -0
  112. package/method/format-record.js +0 -41
  113. package/method/get-lookup-data.js +0 -13
  114. package/method/get-params.js +0 -18
  115. package/method/method-map.js +0 -9
  116. package/method/record/count.js +0 -10
  117. package/method/record/create.js +0 -11
  118. package/method/record/find-one.js +0 -15
  119. package/method/record/find.js +0 -15
  120. package/method/record/get.js +0 -11
  121. package/method/record/remove.js +0 -10
  122. package/method/record/update.js +0 -11
  123. package/method/stat/aggregate.js +0 -14
  124. package/method/stat/histogram.js +0 -14
@@ -5,8 +5,8 @@ async function btnBack () {
5
5
 
6
6
  return class WdbBtnBack extends WdbBase {
7
7
  build = async () => {
8
- const { isEmpty } = this.plugin.app.bajo.lib._
9
- const { attrToArray } = this.plugin.app.waibuMpa
8
+ const { isEmpty } = this.app.lib._
9
+ const { attrToArray } = this.app.waibuMpa
10
10
  const { req } = this.component
11
11
  this.params.noTag = true
12
12
  if (isEmpty(this.params.attr.content)) this.params.attr.content = req.t('back')
@@ -6,7 +6,7 @@ async function btnClone () {
6
6
  return class WdbBtnClone extends WdbBase {
7
7
  build = async () => {
8
8
  const { req } = this.component
9
- const { isEmpty, get } = this.plugin.app.bajo.lib._
9
+ const { isEmpty, get } = this.app.lib._
10
10
  this.params.noTag = true
11
11
  const schema = get(this, 'component.locals.schema', {})
12
12
  if (schema.view.disabled.includes('create')) {
@@ -5,10 +5,10 @@ async function btnColumns () {
5
5
 
6
6
  return class WdbBtnColumns extends WdbBase {
7
7
  build = async () => {
8
- const { get, isEmpty, without } = this.plugin.app.bajo.lib._
9
- const { jsonStringify } = this.plugin.app.waibuMpa
8
+ const { get, isEmpty, without } = this.app.lib._
9
+ const { jsonStringify } = this.app.waibuMpa
10
10
  const { req } = this.component
11
- const qsKey = this.plugin.app.waibu.config.qsKey
11
+ const qsKey = this.app.waibu.config.qsKey
12
12
  const schema = get(this, 'component.locals.schema', {})
13
13
  const count = get(this, 'component.locals.list.count', 0)
14
14
  if (count === 0) this.params.attr.triggerDisabled = true
@@ -6,8 +6,8 @@ async function btnDelete () {
6
6
  return class WdbBtnDelete extends WdbBase {
7
7
  build = async () => {
8
8
  const { req } = this.component
9
- const { generateId } = this.plugin.app.bajo
10
- const { isEmpty, get } = this.plugin.app.bajo.lib._
9
+ const { generateId } = this.app.lib.aneka
10
+ const { isEmpty, get } = this.app.lib._
11
11
  this.params.noTag = true
12
12
  const schema = get(this, 'component.locals.schema', {})
13
13
  if (schema.view.disabled.includes('remove')) {
@@ -6,8 +6,8 @@ async function btnDetails () {
6
6
  return class WdbBtnDetails extends WdbBase {
7
7
  build = async () => {
8
8
  const { req } = this.component
9
- const { generateId } = this.plugin.app.bajo
10
- const { isEmpty, get } = this.plugin.app.bajo.lib._
9
+ const { generateId } = this.app.lib.aneka
10
+ const { isEmpty, get } = this.app.lib._
11
11
  this.params.noTag = true
12
12
  const schema = get(this, 'component.locals.schema', {})
13
13
  if (schema.view.disabled.includes('update')) {
@@ -6,8 +6,8 @@ async function btnEdit () {
6
6
  return class WdbBtnEdit extends WdbBase {
7
7
  build = async () => {
8
8
  const { req } = this.component
9
- const { generateId } = this.plugin.app.bajo
10
- const { isEmpty, get } = this.plugin.app.bajo.lib._
9
+ const { generateId } = this.app.lib.aneka
10
+ const { isEmpty, get } = this.app.lib._
11
11
  this.params.noTag = true
12
12
  const schema = get(this, 'component.locals.schema', {})
13
13
  if (schema.view.disabled.includes('update')) {
@@ -9,7 +9,7 @@ async function btnExport () {
9
9
  ]
10
10
 
11
11
  build = async () => {
12
- const { isEmpty, get } = this.plugin.app.bajo.lib._
12
+ const { isEmpty, get } = this.app.lib._
13
13
  const { req } = this.component
14
14
  this.params.noTag = true
15
15
  const schema = get(this, 'component.locals.schema', {})
@@ -5,8 +5,8 @@ async function echartsBar () {
5
5
 
6
6
  return class WdbEchartsBar extends WdbEcharts {
7
7
  build = async () => {
8
- const { jsonStringify } = this.plugin.app.waibuMpa
9
- const { merge } = this.plugin.lib._
8
+ const { jsonStringify } = this.app.waibuMpa
9
+ const { merge } = this.app.lib._
10
10
  merge(this.setting, {
11
11
  tooltip: {
12
12
  trigger: 'axis',
@@ -5,8 +5,8 @@ async function echartsPie () {
5
5
 
6
6
  return class WdbEchartsPie extends WdbEcharts {
7
7
  build = async () => {
8
- const { jsonStringify } = this.plugin.app.waibuMpa
9
- const { merge } = this.plugin.lib._
8
+ const { jsonStringify } = this.app.waibuMpa
9
+ const { merge } = this.app.lib._
10
10
  merge(this.setting, {
11
11
  tooltip: {
12
12
  trigger: 'item'
@@ -10,7 +10,7 @@ async function echarts () {
10
10
 
11
11
  constructor (options) {
12
12
  super(options)
13
- const { generateId } = this.plugin.app.bajo
13
+ const { generateId } = this.app.lib.aneka
14
14
  this.defSetting = {
15
15
  grid: {
16
16
  top: 8,
@@ -27,8 +27,8 @@ async function echarts () {
27
27
  }
28
28
 
29
29
  _build = ({ setting = {}, onLoad = [] } = {}) => {
30
- const { jsonStringify } = this.plugin.app.waibuMpa
31
- const { merge, isArray } = this.plugin.app.bajo.lib._
30
+ const { jsonStringify } = this.app.waibuMpa
31
+ const { merge, isArray } = this.app.lib._
32
32
  if (!isArray(onLoad)) onLoad = [onLoad]
33
33
  const option = merge({}, this.defSetting, this.setting, setting)
34
34
  this.component.addScriptBlock('alpineInit', `
@@ -5,8 +5,8 @@ async function form () {
5
5
 
6
6
  return class WdbForm extends WdbBase {
7
7
  build = async () => {
8
- const { get, find, filter, forOwn, isEmpty } = this.plugin.lib._
9
- const { base64JsonEncode } = this.plugin.app.waibuMpa
8
+ const { get, find, filter, forOwn, isEmpty } = this.app.lib._
9
+ const { base64JsonEncode } = this.app.waibuMpa
10
10
  const schema = get(this, 'component.locals.schema', {})
11
11
  const body = []
12
12
  const xModels = get(schema, 'view.x.model', [])
@@ -1,7 +1,7 @@
1
1
  import wdbBase from '../wdb-base.js'
2
2
 
3
3
  export function getUrlOpts (params = {}) {
4
- const { get } = this.plugin.app.bajo.lib._
4
+ const { get } = this.app.lib._
5
5
  return {
6
6
  params,
7
7
  excludes: [
@@ -17,8 +17,8 @@ async function pagination () {
17
17
  return class WdbPagination extends WdbBase {
18
18
  build = async () => {
19
19
  const { req } = this.component
20
- const { attrToObject, paginationLayout, groupAttrs } = this.plugin.app.waibuMpa
21
- const { get, isNumber } = this.plugin.app.bajo.lib._
20
+ const { attrToObject, paginationLayout, groupAttrs } = this.app.waibuMpa
21
+ const { get, isNumber } = this.app.lib._
22
22
  const schema = get(this, 'component.locals.schema', {})
23
23
  if (schema.view.disabled.includes('find')) {
24
24
  this.params.html = ''
@@ -5,10 +5,10 @@ async function query () {
5
5
 
6
6
  return class WdbQuery extends WdbBase {
7
7
  build = async () => {
8
- const { generateId } = this.plugin.app.bajo
9
- const { jsonStringify } = this.plugin.app.waibuMpa
10
- const { find, get, without, isEmpty, filter, upperFirst } = this.plugin.app.bajo.lib._
11
- const qsKey = this.plugin.app.waibu.config.qsKey
8
+ const { generateId } = this.app.lib.aneka
9
+ const { jsonStringify } = this.app.waibuMpa
10
+ const { find, get, without, isEmpty, filter, upperFirst } = this.app.lib._
11
+ const qsKey = this.app.waibu.config.qsKey
12
12
  const schema = get(this, 'component.locals.schema', {})
13
13
  if (schema.view.disabled.includes('find')) {
14
14
  this.params.html = ''
@@ -7,8 +7,8 @@ async function recsInfo () {
7
7
  return class WdbRecsInfo extends WdbBase {
8
8
  build = async () => {
9
9
  const { req } = this.component
10
- const { attrToObject, groupAttrs, attrToArray } = this.plugin.app.waibuMpa
11
- const { get, isEmpty, omit, merge } = this.plugin.app.bajo.lib._
10
+ const { attrToObject, groupAttrs, attrToArray } = this.app.waibuMpa
11
+ const { get, isEmpty, omit, merge } = this.app.lib._
12
12
  const schema = get(this, 'component.locals.schema', {})
13
13
  if (schema.view.disabled.includes('find')) {
14
14
  this.params.html = ''
@@ -5,7 +5,7 @@ async function table () {
5
5
 
6
6
  return class WdbTable extends WdbBase {
7
7
  isRightAligned = (field, schema) => {
8
- const { get, find } = this.plugin.app.bajo.lib._
8
+ const { get, find } = this.app.lib._
9
9
  const prop = find(schema.properties, { name: field })
10
10
  if (!prop) return false
11
11
  let value = get(schema, 'view.alignEnd', []).includes(field)
@@ -15,17 +15,17 @@ async function table () {
15
15
 
16
16
  isNoWrap = (field, schema, bodyNowrap) => {
17
17
  if (bodyNowrap) return true
18
- const { get } = this.plugin.app.bajo.lib._
18
+ const { get } = this.app.lib._
19
19
  return get(schema, 'view.noWrap', []).includes(field)
20
20
  }
21
21
 
22
22
  _defFormatter = async ({ req, key, value, data, schema }) => {
23
- const { get, find } = this.plugin.lib._
24
- const { escape } = this.plugin.app.waibu
23
+ const { get, find } = this.app.lib._
24
+ const { escape } = this.app.waibu
25
25
  const prop = find(schema.properties, { name: key })
26
26
  if (!prop) return value
27
27
  if (prop.type === 'boolean') {
28
- value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${data[key] ? 'Check' : ''}` } })) +
28
+ value = (await this.component.buildTag({ tag: 'icon', attr: { name: `circle${data[key] ? 'Check' : 'Cross'}` } })) +
29
29
  ' ' + (req.t(data[key] ? 'Yes' : 'No'))
30
30
  } else if (['string', 'text'].includes(prop.type)) {
31
31
  if (!get(schema, 'view.noEscape', []).includes(key)) value = escape(value)
@@ -35,10 +35,10 @@ async function table () {
35
35
 
36
36
  build = async () => {
37
37
  const { req } = this.component
38
- const { escape } = this.plugin.app.waibu
39
- const { formatRecord } = this.plugin.app.waibuDb
40
- const { attrToArray, groupAttrs } = this.plugin.app.waibuMpa
41
- const { get, omit, set, find, isEmpty, without, merge } = this.plugin.lib._
38
+ const { escape } = this.app.waibu
39
+ const { formatRecord } = this.app.waibuDb
40
+ const { attrToArray, groupAttrs } = this.app.waibuMpa
41
+ const { get, omit, set, find, isEmpty, without, merge } = this.app.lib._
42
42
  const group = groupAttrs(this.params.attr, ['body', 'head', 'foot'])
43
43
  this.params.attr = group._
44
44
  const prettyUrl = this.params.attr.prettyUrl
@@ -59,7 +59,7 @@ async function table () {
59
59
  this.params.html = ''
60
60
  return
61
61
  }
62
- const qsKey = this.plugin.app.waibu.config.qsKey
62
+ const qsKey = this.app.waibu.config.qsKey
63
63
  let fields = without(get(this, `component.locals._meta.query.${qsKey.fields}`, '').split(','), '')
64
64
  if (isEmpty(fields)) fields = schema.view.fields
65
65
  if (!isEmpty(schema.view.hidden)) fields = without(fields, ...schema.view.hidden)
@@ -101,7 +101,7 @@ async function table () {
101
101
  const attr = this.isRightAligned(f, schema) ? { text: 'align:end' } : {}
102
102
  const content = [
103
103
  await this.component.buildTag({ tag: 'div', attr, html: head }),
104
- await this.component.buildTag({ tag: 'a', attr: { icon, href }, prepend: '<div class="ms-1">', append: '</div>' })
104
+ await this.component.buildTag({ tag: 'a', attr: { icon, href, noIconLink: true }, prepend: '<div class="ms-1">', append: '</div>' })
105
105
  ]
106
106
  head = await this.component.buildTag({ tag: 'div', attr: { flex: 'justify-content:between align-items:end' }, html: content.join('\n') })
107
107
  }
File without changes
@@ -1,5 +1,5 @@
1
1
  async function get (req, reply) {
2
- return await this.recordGet({ req, reply })
2
+ return await this.getRecord({ req, reply })
3
3
  }
4
4
 
5
5
  export default get
@@ -1,5 +1,5 @@
1
1
  async function remove (req, reply) {
2
- return await this.recordRemove({ req, reply })
2
+ return await this.removeRecord({ req, reply })
3
3
  }
4
4
 
5
5
  export default remove
@@ -1,5 +1,5 @@
1
1
  async function update (req, reply) {
2
- return await this.recordUpdate({ req, reply })
2
+ return await this.updateRecord({ req, reply })
3
3
  }
4
4
 
5
5
  export default update
@@ -1,5 +1,5 @@
1
1
  async function create (req, reply) {
2
- return await this.recordCreate({ req, reply })
2
+ return await this.createRecord({ req, reply })
3
3
  }
4
4
 
5
5
  export default create
@@ -1,6 +1,6 @@
1
1
  async function find (req, reply) {
2
- const { isSet } = this.lib.aneka
3
- const { parseObject } = this.app.bajo
2
+ const { isSet } = this.app.lib.aneka
3
+ const { parseObject } = this.app.lib
4
4
  let { fields, count } = this.getParams(req)
5
5
  let rels = []
6
6
  const headers = parseObject(req.headers, { parseValue: true })
@@ -8,7 +8,7 @@ async function find (req, reply) {
8
8
  if (isSet(headers['x-rels'])) rels = headers['x-rels']
9
9
  if (typeof rels === 'string' && !['*', 'all'].includes(rels)) rels = [rels]
10
10
  const options = { fields, count, rels }
11
- return await this.recordFind({ req, reply, options })
11
+ return await this.findRecord({ req, reply, options })
12
12
  }
13
13
 
14
14
  export default find
@@ -0,0 +1,8 @@
1
+ async function stat (req, reply) {
2
+ const { camelCase } = this.app.lib._
3
+ const method = camelCase(`create ${req.params.stat}`)
4
+ if (!this[method]) throw this.error('_notFound')
5
+ return await this[method]({ req, reply })
6
+ }
7
+
8
+ export default stat
package/index.js CHANGED
@@ -1,11 +1,31 @@
1
+ import countRecord from './lib/method/count-record.js'
2
+ import createAggregate from './lib/method/create-aggregate.js'
3
+ import createHistogram from './lib/method/create-histogram.js'
4
+ import createRecord from './lib/method/create-record.js'
5
+ import findOneRecord from './lib/method/find-one-record.js'
6
+ import findRecord from './lib/method/find-record.js'
7
+ import getSchemaExt from './lib/method/get-schema-ext.js'
8
+ import getRecord from './lib/method/get-record.js'
9
+ import removeRecord from './lib/method/remove-record.js'
10
+ import updateRecord from './lib/method/update-record.js'
11
+
12
+ /**
13
+ * Plugin factory
14
+ *
15
+ * @param {string} pkgName - NPM package name
16
+ * @returns {class}
17
+ */
1
18
  async function factory (pkgName) {
2
19
  const me = this
3
20
 
4
- return class WaibuDb extends this.lib.Plugin {
21
+ /**
22
+ * WaibuDb class
23
+ *
24
+ * @class
25
+ */
26
+ class WaibuDb extends this.app.baseClass.Base {
5
27
  constructor () {
6
28
  super(pkgName, me.app)
7
- this.alias = 'wdb'
8
- this.dependencies = ['dobo', 'waibu', 'bajo-queue', 'dobo-extra']
9
29
  this.config = {
10
30
  waibu: {
11
31
  prefix: 'db',
@@ -22,15 +42,34 @@ async function factory (pkgName) {
22
42
  count: false,
23
43
  patchEnabled: false
24
44
  },
25
- modelRestApi: false
45
+ enableRestApiForModel: false
46
+ }
47
+ this.methodMap = {
48
+ create: 'POST',
49
+ find: 'GET',
50
+ get: 'GET',
51
+ update: 'PUT',
52
+ remove: 'DELETE'
26
53
  }
54
+
55
+ this.selfBind([
56
+ 'countRecord',
57
+ 'createAggregate',
58
+ 'createHistogram',
59
+ 'createRecord',
60
+ 'findOneRecord',
61
+ 'findRecord',
62
+ 'getSchemaExt',
63
+ 'getRecord',
64
+ 'removeRecord',
65
+ 'updateRecord'
66
+ ])
27
67
  }
28
68
 
29
69
  exportData = async (params) => {
30
70
  const { getPlugin } = this.app.bajo
31
- const { get } = this.lib._
32
- const { fs } = this.lib
33
- const { recordUpdate } = this.app.dobo
71
+ const { get } = this.app.lib._
72
+ const { fs } = this.app.lib
34
73
  const { exportTo } = this.app.doboExtra
35
74
  const { downloadDir } = getPlugin('sumba')
36
75
  const model = get(params, 'payload.data.name')
@@ -43,38 +82,37 @@ async function factory (pkgName) {
43
82
  fields
44
83
  }
45
84
  options.filter.sort = 'id:1'
46
- const dmodel = 'SumbaDownload'
85
+ const dmodel = this.app.dobo.getModel('SumbaDownload')
47
86
  try {
48
- await recordUpdate(dmodel, id, { status: 'PROCESSING' })
87
+ await dmodel.updateRecord(id, { status: 'PROCESSING' })
49
88
  await exportTo(model, dest, options)
50
89
  const { size } = fs.statSync(dest)
51
- await recordUpdate(dmodel, id, { size, status: 'COMPLETE' })
90
+ await dmodel.updateRecord(id, { size, status: 'COMPLETE' })
52
91
  } catch (err) {
53
- await recordUpdate(dmodel, id, { status: 'FAIL' })
92
+ await dmodel.updateRecord(id, { status: 'FAIL' })
54
93
  }
55
94
  }
56
95
 
57
96
  adminMenu = async (locals, req) => {
58
97
  const { getPluginPrefix } = this.app.waibu
59
- const { pascalCase } = this.lib.aneka
98
+ const { pascalCase } = this.app.lib.aneka
60
99
  const { getAppTitle } = this.app.waibuMpa
61
- const { camelCase, map, pick, groupBy, keys, kebabCase, filter, get } = this.lib._
100
+ const { camelCase, map, groupBy, keys, kebabCase, filter, get, isArray } = this.app.lib._
62
101
 
63
- const prefix = getPluginPrefix(this.name)
64
- const schemas = filter(this.app.dobo.schemas, s => {
102
+ const prefix = getPluginPrefix(this.ns)
103
+ const allModels = this.app.dobo.models
104
+ const models = filter(allModels, s => {
65
105
  const byModelFind = !s.disabled.includes('find')
66
- let modelDisabled = get(this, `app.${s.ns}.config.waibuAdmin.modelDisabled`)
67
- if (modelDisabled) {
68
- const allModels = map(filter(this.app.dobo.schemas, { ns: s.ns }), 'name')
69
- if (modelDisabled === 'all') modelDisabled = allModels
70
- else modelDisabled = map(modelDisabled, m => pascalCase(`${this.app[s.ns].alias} ${m}`))
71
- } else modelDisabled = []
106
+ const disabled = get(this, `app.${s.plugin.ns}.config.waibuAdmin.modelDisabled`, [])
107
+ let modelDisabled = []
108
+ if (['*', 'all'].includes(disabled)) modelDisabled = map(filter(allModels, m => m.plugin.ns === s.plugin.ns), 'name')
109
+ else if (isArray(disabled)) modelDisabled = map(disabled, m => pascalCase(`${this.app[s.plugin.ns].alias} ${m}`))
72
110
  const byDbDisabled = !modelDisabled.includes(s.name)
73
111
  return byModelFind && byDbDisabled
74
112
  })
75
- const omenu = groupBy(map(schemas, s => {
76
- const item = pick(s, ['name', 'ns'])
77
- item.nsTitle = getAppTitle(s.ns)
113
+ const omenu = groupBy(map(models, s => {
114
+ const item = { name: s.name, ns: s.plugin.ns }
115
+ item.nsTitle = getAppTitle(s.plugin.ns)
78
116
  return item
79
117
  }), 'nsTitle')
80
118
  const menu = []
@@ -93,7 +131,89 @@ async function factory (pkgName) {
93
131
  }
94
132
  return menu
95
133
  }
134
+
135
+ getParams = (req, ...items) => {
136
+ const { map, trim, get } = this.app.lib._
137
+ let fields
138
+ req.query = req.query ?? {}
139
+ req.params = req.params ?? {}
140
+ if (req.query.fields) fields = map((req.query.fields ?? '').split(','), i => trim(i))
141
+ const params = {
142
+ fields,
143
+ count: get(this, 'config.dbModel.count', false),
144
+ body: req.body
145
+ }
146
+ items.forEach(i => {
147
+ params[i] = req.params[i]
148
+ })
149
+ return params
150
+ }
151
+
152
+ getLookupData = async ({ model, req, data, id = 'id', field, query }) => {
153
+ const { set, map } = this.app.lib._
154
+ const $in = map(data, id)
155
+ const q = query ?? set({}, field, { $in })
156
+ const options = {
157
+ dataOnly: true,
158
+ limit: -1,
159
+ query: q
160
+ }
161
+ return await this.findRecord({ model, req, options })
162
+ }
163
+
164
+ formatRecord = async ({ data, req, schema, options = {} }) => {
165
+ const { isArray } = this.app.lib._
166
+ if (!isArray(data)) return await this.formatRow({ data, req, schema, options })
167
+ const items = []
168
+ for (const d of data) {
169
+ const item = await this.formatRow({ data: d, req, schema, options })
170
+ items.push(item)
171
+ }
172
+ return items
173
+ }
174
+
175
+ formatRow = async ({ data, req, schema, options = {} }) => {
176
+ const { get, find, isFunction, cloneDeep } = this.app.lib._
177
+ const { format, callHandler } = this.app.bajo
178
+ const { escape } = this.app.waibu
179
+ const fields = get(schema, 'view.fields', Object.keys(schema.properties))
180
+ const rec = cloneDeep(data)
181
+ for (const f of fields) {
182
+ if (f === '_rel') continue
183
+ let prop = find(schema.properties, { name: f })
184
+ if (!prop) prop = find(schema.view.calcFields, { name: f })
185
+ if (!prop) continue
186
+ const opts = {
187
+ lang: options.lang ?? (req ? req.lang : undefined),
188
+ longitude: ['lng', 'longitude'].includes(f),
189
+ latitude: ['lat', 'latitude'].includes(f),
190
+ speed: ['speed'].includes(f),
191
+ degree: ['course', 'heading'].includes(f),
192
+ distance: ['distance'].includes(f)
193
+ }
194
+ rec[f] = format(data[f], prop.type, opts)
195
+ const vf = get(schema, `view.valueFormatter.${f}`)
196
+ if (vf) {
197
+ if (isFunction(vf)) rec[f] = await vf.call(this, data[f], data)
198
+ else rec[f] = await callHandler(vf, { req, value: data[f], data })
199
+ } else if (['string', 'text'].includes(prop.type)) rec[f] = escape(rec[f])
200
+ }
201
+ return rec
202
+ }
203
+
204
+ countRecord = countRecord
205
+ createAggregate = createAggregate
206
+ createHistogram = createHistogram
207
+ createRecord = createRecord
208
+ findOneRecord = findOneRecord
209
+ findRecord = findRecord
210
+ getSchemaExt = getSchemaExt
211
+ getRecord = getRecord
212
+ removeRecord = removeRecord
213
+ updateRecord = updateRecord
96
214
  }
215
+
216
+ return WaibuDb
97
217
  }
98
218
 
99
219
  export default factory
@@ -1,18 +1,18 @@
1
1
  async function addHandler ({ req, reply, model, params = {}, template, addOnsHandler, templateDisabled = 'waibuDb.template:/disabled.html', options = {} } = {}) {
2
- const { pascalCase } = this.lib.aneka
3
- const { recordCreate, recordGet, getSchemaExt } = this.app.waibuDb
2
+ const { pascalCase } = this.app.lib.aneka
3
+ const { createRecord, getRecord, getSchemaExt } = this.app.waibuDb
4
4
  const { buildUrl } = this.app.waibuMpa
5
- const { defaultsDeep } = this.lib.aneka
6
- const { pick, map, merge, omit, isEmpty } = this.lib._
5
+ const { defaultsDeep } = this.app.lib.aneka
6
+ const { pick, map, merge, omit } = this.app.lib._
7
7
  const opts = {}
8
- model = model ?? pascalCase(req.params.model)
8
+ model = pascalCase(model ?? req.params.model)
9
9
  const { schema } = await getSchemaExt(model, 'add', merge({}, { params }, options))
10
10
  if (schema.disabled.includes('create')) return await reply.view(templateDisabled, { action: 'add' })
11
11
  // req.query.attachment = true
12
12
  opts.fields = schema.view.fields
13
13
  let def = {}
14
14
  if (req.method === 'GET' && req.query.mode === 'clone' && req.query.id) {
15
- const resp = await recordGet({ model, req, id: req.query.id, options: { fields: map(schema.properties, 'name') } })
15
+ const resp = await getRecord({ model, req, id: req.query.id, options: { fields: map(schema.properties, 'name') } })
16
16
  def = omit(resp.data, ['id', 'createdAt', 'updatedAt'])
17
17
  }
18
18
  let form = defaultsDeep(req.body, def)
@@ -22,9 +22,9 @@ async function addHandler ({ req, reply, model, params = {}, template, addOnsHan
22
22
  req.session[`wdb${model}AddMore`] = form._addmore
23
23
  req.session[`wdb${model}ClonePrev`] = form._cloneprev
24
24
  try {
25
- resp = await recordCreate({ model, req, reply, options: opts })
26
- if (isEmpty(form._addmore)) return reply.redirectTo(buildUrl({ url: req.url, base: 'list', params: { page: 1 }, exclude: ['id', 'mode'] }))
27
- if (isEmpty(form._cloneprev)) form = pick(form, ['_addmore', '_cloneprev'])
25
+ resp = await createRecord({ model, req, reply, options: opts })
26
+ if (!form._addmore) return reply.redirectTo(buildUrl({ url: req.url, base: 'list', params: { page: 1 }, exclude: ['id', 'mode'] }))
27
+ if (!form._cloneprev) form = pick(form, ['_addmore', '_cloneprev'])
28
28
  } catch (err) {
29
29
  error = err
30
30
  }
@@ -32,6 +32,7 @@ async function addHandler ({ req, reply, model, params = {}, template, addOnsHan
32
32
  form._addmore = req.session[`wdb${model}AddMore`]
33
33
  form._cloneprev = req.session[`wdb${model}ClonePrev`]
34
34
  }
35
+ console.log(form)
35
36
  const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema, error, options }) : undefined
36
37
  merge(params, { form, schema, error, addOns })
37
38
  if (schema.template) template = schema.template
@@ -18,7 +18,7 @@ const handler = {
18
18
  }
19
19
 
20
20
  async function allHandler ({ model, action, req, reply, template, params = {}, options = {} }) {
21
- const { upperFirst, merge, keys } = this.lib._
21
+ const { upperFirst, merge, keys } = this.app.lib._
22
22
  if (!keys(handler).includes(action)) throw this.error('_notFound')
23
23
  if (['delete', 'export'].includes(action)) {
24
24
  if (req.method === 'GET') throw this.error('_notFound')
@@ -1,10 +1,10 @@
1
1
  async function deleteHandler ({ req, reply, model, params = {}, templateDisabled = 'waibuDb.template:/disabled.html', options = {} } = {}) {
2
- const { pascalCase } = this.lib.aneka
3
- const { recordRemove, getSchemaExt } = this.app.waibuDb
2
+ const { pascalCase } = this.app.lib.aneka
3
+ const { removeRecord, getSchemaExt } = this.app.waibuDb
4
4
  const { buildUrl } = this.app.waibuMpa
5
- const { reduce, merge } = this.lib._
5
+ const { reduce, merge } = this.app.lib._
6
6
  const opts = {}
7
- model = model ?? pascalCase(req.params.model)
7
+ model = pascalCase(model ?? req.params.model)
8
8
  const { schema } = await getSchemaExt(model, 'add', merge({}, { params }, options))
9
9
  if (schema.disabled.includes('remove')) return await reply.view(templateDisabled, { action: 'delete' })
10
10
  opts.fields = schema.view.fields
@@ -15,9 +15,10 @@ async function deleteHandler ({ req, reply, model, params = {}, templateDisabled
15
15
  opts.noFlash = true
16
16
  for (const id of ids) {
17
17
  try {
18
- await recordRemove({ model, id, req, reply, options: opts })
18
+ await removeRecord({ model, id, req, reply, options: opts })
19
19
  result.push(true)
20
20
  } catch (err) {
21
+ console.log(err)
21
22
  result.push(err.message)
22
23
  }
23
24
  }
@@ -1,17 +1,17 @@
1
1
  import attachmentHandler from './helper/attachment-handler.js'
2
2
 
3
3
  async function detailsHandler ({ req, reply, model, params = {}, id, template, addOnsHandler, templateDisabled = 'waibuDb.template:/disabled.html', options } = {}) {
4
- const { pascalCase } = this.lib.aneka
5
- const { recordGet, getSchemaExt } = this.app.waibuDb
6
- const { merge } = this.lib._
7
- const opts = { rels: '*' }
8
- model = model ?? pascalCase(req.params.model)
4
+ const { pascalCase } = this.app.lib.aneka
5
+ const { getRecord, getSchemaExt } = this.app.waibuDb
6
+ const { merge } = this.app.lib._
7
+ const opts = { refs: '*' }
8
+ model = pascalCase(model ?? req.params.model)
9
9
  const { schema } = await getSchemaExt(model, 'details', merge({}, { params }, options))
10
10
  if (schema.disabled.includes('get')) return await reply.view(templateDisabled, { action: 'details' })
11
11
  // req.query.attachment = true
12
12
  opts.fields = schema.view.fields
13
13
  id = id ?? req.params.id ?? req.query.id
14
- const resp = await recordGet({ model, req, id, options: opts })
14
+ const resp = await getRecord({ model, req, id, options: opts })
15
15
  const form = resp.data
16
16
  const addOns = addOnsHandler ? await addOnsHandler.call(this.app[req.ns], { req, reply, params, data: resp, schema, options }) : undefined
17
17
  const attachments = await attachmentHandler.call(this, { schema, id, options })