dobo 2.38.0 → 2.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/.bootorder +0 -0
  2. package/.github/FUNDING.yml +0 -0
  3. package/.github/workflows/repo-lockdown.yml +0 -0
  4. package/.jsdoc.conf.json +0 -0
  5. package/LICENSE +0 -0
  6. package/README.md +0 -0
  7. package/docs/Dobo.html +0 -0
  8. package/docs/DoboAction.html +0 -0
  9. package/docs/DoboAdapter.html +0 -0
  10. package/docs/DoboConnection.html +0 -0
  11. package/docs/DoboFeature.html +0 -0
  12. package/docs/DoboModel.html +0 -0
  13. package/docs/data/search.json +0 -0
  14. package/docs/extend_bajo_hook-docs.js.html +0 -0
  15. package/docs/external-Tools.html +0 -0
  16. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  17. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  18. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  19. package/docs/global.html +0 -0
  20. package/docs/index.html +0 -0
  21. package/docs/index.js.html +0 -0
  22. package/docs/lib_factory_action.js.html +0 -0
  23. package/docs/lib_factory_adapter.js.html +0 -0
  24. package/docs/lib_factory_connection.js.html +0 -0
  25. package/docs/lib_factory_feature.js.html +0 -0
  26. package/docs/lib_factory_model.js.html +0 -0
  27. package/docs/lib_factory_model_build.js.html +0 -0
  28. package/docs/lib_factory_model_clear-record.js.html +0 -0
  29. package/docs/lib_factory_model_count-record.js.html +0 -0
  30. package/docs/lib_factory_model_create-record.js.html +0 -0
  31. package/docs/lib_factory_model_drop.js.html +0 -0
  32. package/docs/lib_factory_model_exists.js.html +0 -0
  33. package/docs/lib_factory_model_find-all-record.js.html +0 -0
  34. package/docs/lib_factory_model_find-one-record.js.html +0 -0
  35. package/docs/lib_factory_model_find-record.js.html +0 -0
  36. package/docs/lib_factory_model_get-record.js.html +0 -0
  37. package/docs/lib_factory_model_helper.js.html +0 -0
  38. package/docs/lib_factory_model_remove-record.js.html +0 -0
  39. package/docs/lib_factory_model_sanitize-body.js.html +0 -0
  40. package/docs/lib_factory_model_sanitize-fixture.js.html +0 -0
  41. package/docs/lib_factory_model_sanitize-record.js.html +0 -0
  42. package/docs/lib_factory_model_update-record.js.html +0 -0
  43. package/docs/lib_factory_model_upsert-record.js.html +0 -0
  44. package/docs/lib_factory_model_validate.js.html +0 -0
  45. package/docs/lib_helper.js.html +0 -0
  46. package/docs/module-Helper.html +0 -0
  47. package/docs/module-Helper_Model.html +0 -0
  48. package/docs/module-Hook.html +0 -0
  49. package/docs/scripts/core.js +0 -0
  50. package/docs/scripts/core.min.js +0 -0
  51. package/docs/scripts/resize.js +0 -0
  52. package/docs/scripts/search.js +0 -0
  53. package/docs/scripts/search.min.js +5 -5
  54. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
  55. package/docs/scripts/third-party/fuse.js +0 -0
  56. package/docs/scripts/third-party/hljs-line-num-original.js +0 -0
  57. package/docs/scripts/third-party/hljs-line-num.js +0 -0
  58. package/docs/scripts/third-party/hljs-original.js +0 -0
  59. package/docs/scripts/third-party/hljs.js +0 -0
  60. package/docs/scripts/third-party/popper.js +0 -0
  61. package/docs/scripts/third-party/tippy.js +0 -0
  62. package/docs/scripts/third-party/tocbot.js +0 -0
  63. package/docs/scripts/third-party/tocbot.min.js +0 -0
  64. package/docs/static/bitcoin.jpeg +0 -0
  65. package/docs/static/home.md +0 -0
  66. package/docs/static/logo-ecosystem.png +0 -0
  67. package/docs/static/logo.png +0 -0
  68. package/docs/styles/clean-jsdoc-theme-base.css +0 -0
  69. package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
  70. package/docs/styles/clean-jsdoc-theme-light.css +0 -0
  71. package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  72. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  73. package/docs/styles/clean-jsdoc-theme.min.css +0 -0
  74. package/extend/bajo/hook.js +236 -236
  75. package/extend/bajo/intl/en-US.json +0 -0
  76. package/extend/bajo/intl/id.json +0 -0
  77. package/extend/bajoCli/applet/aggregate.js +0 -0
  78. package/extend/bajoCli/applet/clear-record.js +0 -0
  79. package/extend/bajoCli/applet/connection.js +0 -0
  80. package/extend/bajoCli/applet/count-record.js +0 -0
  81. package/extend/bajoCli/applet/create-record.js +0 -0
  82. package/extend/bajoCli/applet/find-record.js +0 -0
  83. package/extend/bajoCli/applet/get-record.js +0 -0
  84. package/extend/bajoCli/applet/histogram.js +0 -0
  85. package/extend/bajoCli/applet/lib/post-process.js +0 -0
  86. package/extend/bajoCli/applet/model.js +0 -0
  87. package/extend/bajoCli/applet/rebuild-model.js +0 -0
  88. package/extend/bajoCli/applet/remove-record.js +0 -0
  89. package/extend/bajoCli/applet/update-record.js +0 -0
  90. package/extend/bajoCli/applet.js +0 -0
  91. package/extend/dobo/adapter/memory.js +175 -175
  92. package/extend/dobo/feature/created-at.js +0 -0
  93. package/extend/dobo/feature/dt.js +0 -0
  94. package/extend/dobo/feature/image.js +0 -0
  95. package/extend/dobo/feature/immutable.js +0 -0
  96. package/extend/dobo/feature/removed-at.js +0 -0
  97. package/extend/dobo/feature/unique.js +0 -0
  98. package/extend/dobo/feature/updated-at.js +0 -0
  99. package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +0 -0
  100. package/extend/waibuStatic/virtual.json +0 -0
  101. package/index.js +0 -0
  102. package/lib/factory/action.js +287 -287
  103. package/lib/factory/adapter.js +1055 -1055
  104. package/lib/factory/connection.js +109 -109
  105. package/lib/factory/feature.js +52 -52
  106. package/lib/factory/model/aggregate.js +23 -23
  107. package/lib/factory/model/build.js +25 -25
  108. package/lib/factory/model/bulk-create-record.js +36 -36
  109. package/lib/factory/model/clear-record.js +30 -30
  110. package/lib/factory/model/count-record.js +42 -42
  111. package/lib/factory/model/create-attachment.js +36 -36
  112. package/lib/factory/model/create-record.js +49 -49
  113. package/lib/factory/model/drop.js +26 -26
  114. package/lib/factory/model/exists.js +26 -26
  115. package/lib/factory/model/find-all-record.js +112 -112
  116. package/lib/factory/model/find-attachment.js +28 -28
  117. package/lib/factory/model/find-one-record.js +38 -38
  118. package/lib/factory/model/find-record.js +82 -82
  119. package/lib/factory/model/get-attachment.js +15 -15
  120. package/lib/factory/model/get-record.js +52 -52
  121. package/lib/factory/model/helper.js +575 -576
  122. package/lib/factory/model/histogram.js +23 -23
  123. package/lib/factory/model/list-attachment.js +40 -40
  124. package/lib/factory/model/load-fixtures.js +63 -63
  125. package/lib/factory/model/remove-attachment.js +24 -24
  126. package/lib/factory/model/remove-record.js +44 -44
  127. package/lib/factory/model/sanitize-body.js +57 -57
  128. package/lib/factory/model/sanitize-fixture.js +56 -56
  129. package/lib/factory/model/sanitize-record.js +80 -80
  130. package/lib/factory/model/transaction.js +15 -15
  131. package/lib/factory/model/update-attachment.js +9 -9
  132. package/lib/factory/model/update-record.js +58 -58
  133. package/lib/factory/model/upsert-record.js +71 -71
  134. package/lib/factory/model/validate.js +0 -0
  135. package/lib/factory/model.js +503 -503
  136. package/lib/helper.js +463 -463
  137. package/package.json +1 -1
  138. package/test/e2e/_run.js +12 -12
  139. package/test/e2e/e2e-factory-process.test.js +25 -25
  140. package/test/e2e/e2e-model-adapter-process.test.js +52 -52
  141. package/test/integration/aspect-01-start-connections.test.js +33 -33
  142. package/test/integration/aspect-02-query-regex.test.js +34 -34
  143. package/test/integration/aspect-03-model-adapter-flow.test.js +88 -88
  144. package/test/unit/_stub.js +244 -244
  145. package/test/unit/dobo-action.test.js +58 -58
  146. package/test/unit/dobo-connection.test.js +37 -37
  147. package/test/unit/dobo-core.test.js +136 -136
  148. package/test/unit/dobo-feature.test.js +25 -25
  149. package/test/unit/dobo-model.test.js +115 -115
  150. package/test/unit/helper-sanitize-all.test.js +40 -40
  151. package/test/unit/helper-sanitize-ref.test.js +64 -64
  152. package/wiki/APPLETS.md +0 -0
  153. package/wiki/CHANGES.md +477 -469
  154. package/wiki/CONFIG.md +0 -0
  155. package/wiki/CONTRIBUTING.md +0 -0
  156. package/wiki/DEV-GUIDE.md +0 -0
  157. package/wiki/ECOSYSTEM.md +0 -0
  158. package/wiki/GETTING-STARTED.md +0 -0
  159. package/wiki/QUERY-LANGUAGE.md +0 -0
  160. package/wiki/USER-GUIDE.md +0 -0
@@ -1,175 +1,175 @@
1
- import { Query } from 'mingo'
2
-
3
- async function memoryAdapterFactory () {
4
- const { DoboAdapter } = this.app.baseClass
5
- const { findIndex, pullAt, omit, has } = this.app.lib._
6
- const { defaultsDeep } = this.app.lib.aneka
7
-
8
- class DoboMemoryAdapter extends DoboAdapter {
9
- constructor (plugin, name, options) {
10
- super(plugin, name, options)
11
- this.idGenerator = 'ulid'
12
- this.saving = true
13
- this.memory = true
14
- this.storage = {}
15
- this.support = {
16
- propType: {
17
- object: true,
18
- array: true
19
- }
20
- }
21
- }
22
-
23
- async sanitizeConnection (conn) {
24
- await super.sanitizeConnection(conn)
25
- conn.memory = true
26
- }
27
-
28
- async connect (connection, noRebuild) {
29
- const conn = this.plugin.getConnection('memory')
30
- const { fs } = this.app.lib
31
- const { setInterval } = this.app.lib
32
- const dir = `${this.app.getPluginDataDir(this.plugin.ns)}/memDb/data` // persistence dir
33
- fs.ensureDirSync(dir)
34
- conn.persistences = conn.persistences ?? []
35
-
36
- const models = this.plugin.getModelsByConnection(conn.name).map(model => {
37
- if (conn.persistences.includes(model.name)) model.options.persistence = true
38
- return model
39
- })
40
-
41
- for (const model of models) {
42
- this.storage[model.name] = this.storage[model.name] ?? [] // init empty model
43
- if (model.options.persistence) {
44
- const file = `${dir}/${model.name}.json`
45
- let data = []
46
- if (fs.existsSync(file)) {
47
- try {
48
- data = JSON.parse(fs.readFileSync(file, 'utf8'))
49
- } catch (err) {}
50
- }
51
- if (data.length === 0) await model.loadFixtures({ ignoreError: false })
52
- else this.storage[model.name] = data
53
- } else await model.loadFixtures({ ignoreError: false })
54
- }
55
- async function handler () {
56
- if (!this.saving) return
57
- this.saving = true
58
- for (const model of models) {
59
- if (!model.options.persistence) continue
60
- try {
61
- fs.writeFileSync(`${dir}/${model.name}.json`, JSON.stringify(this.storage[model.name], null, 2), 'utf8')
62
- } catch (err) {}
63
- }
64
- this.saving = false
65
- }
66
-
67
- await setInterval(handler, this.plugin.config.memDb.persistenceDur, { lockFile: 'memDbPersistence', scope: this })
68
- }
69
-
70
- async _getOldRecord (model, id, options = {}) {
71
- const idx = findIndex(this.storage[model.name], { _id: id })
72
- const oldData = this.storage[model.name][idx]
73
- return { idx, oldData }
74
- }
75
-
76
- async modelExists (model, options = {}) {
77
- return { data: has(this.storage, model.name) }
78
- }
79
-
80
- async buildModel (model, options = {}) {
81
- if (has(this.storage, model.name)) throw this.plugin.error('exist%s%s', this.plugin.t('model'), model.name)
82
- this.storage[model.name] = []
83
- if (options.noResult) return
84
- return { data: true }
85
- }
86
-
87
- async dropModel (model, options = {}) {
88
- if (!has(this.storage, model.name)) throw this.plugin.error('notFound%s%s', this.plugin.t('model'), model.name)
89
- delete this.storage[model.name]
90
- if (options.noResult) return
91
- return { data: true }
92
- }
93
-
94
- async createRecord (model, body = {}, options = {}) {
95
- this.storage[model.name].push(body)
96
- return { data: body }
97
- }
98
-
99
- async getRecord (model, id, options = {}) {
100
- const { oldData: data } = await this._getOldRecord(model, id)
101
- return { data }
102
- }
103
-
104
- async updateRecord (model, id, body = {}, options = {}) {
105
- const { idx, oldData } = await this._getOldRecord(model, id)
106
- const data = defaultsDeep(body, oldData)
107
- this.storage[model.name][idx] = data
108
- return { oldData, data }
109
- }
110
-
111
- async removeRecord (model, id, options = {}) {
112
- const { idx, oldData } = await this._getOldRecord(model, id)
113
- pullAt(this.storage[model.name], idx)
114
- return { oldData }
115
- }
116
-
117
- async clearRecord (model, options = {}) {
118
- this.storage[model.name] = []
119
- if (options.noResult) return
120
- return { data: true }
121
- }
122
-
123
- async findRecord (model, filter = {}, options = {}) {
124
- const { limit, skip, sort, page } = filter
125
- const { data: count = 0 } = await this.countRecord(model, filter, options)
126
- const cursor = this._getCursor(model, filter)
127
- if (sort) cursor.sort(sort)
128
- cursor.skip(skip).limit(limit)
129
- let result = { data: cursor.all(), page, limit, count, pages: Math.ceil(count / limit) }
130
- if (!options.count) result = omit(result, ['count', 'pages'])
131
- return result
132
- }
133
-
134
- async findAllRecord (model, filter = {}, options = {}) {
135
- const { hardCap } = this.app.dobo.getDefaultValues(options)
136
- filter.limit = hardCap
137
- delete filter.skip
138
- delete filter.page
139
- const { sort } = filter
140
- const cursor = this._getCursor(model, filter)
141
- cursor.limit(filter.limit)
142
- if (sort) cursor.sort(sort)
143
- return { data: cursor.all(), hardCapped: true }
144
- }
145
-
146
- async countRecord (model, filter = {}, options = {}) {
147
- const cursor = this._getCursor(model, filter)
148
- const data = cursor.all().length
149
- return { data }
150
- }
151
-
152
- async aggregate (model, filter = {}, params = {}, options = {}) {
153
- const item = await this.findAllRecord(model, filter, options)
154
- const result = this.app.dobo.calcAggregate({ data: item.data, ...params })
155
- return { data: result }
156
- }
157
-
158
- async histogram (model, filter = {}, params = {}, options = {}) {
159
- const item = await this.findAllRecord(model, filter, options)
160
- const result = this.app.dobo.calcHistogram({ data: item.data, ...params })
161
- return { data: result }
162
- }
163
-
164
- _getCursor (model, filter) {
165
- const criteria = filter.query ?? {}
166
- const q = new Query(criteria, { idKey: '_id' })
167
- return q.find(this.storage[model.name] ?? [])
168
- }
169
- }
170
-
171
- this.app.baseClass.DoboMemoryAdapter = DoboMemoryAdapter
172
- return DoboMemoryAdapter
173
- }
174
-
175
- export default memoryAdapterFactory
1
+ import { Query } from 'mingo'
2
+
3
+ async function memoryAdapterFactory () {
4
+ const { DoboAdapter } = this.app.baseClass
5
+ const { findIndex, pullAt, omit, has } = this.app.lib._
6
+ const { defaultsDeep } = this.app.lib.aneka
7
+
8
+ class DoboMemoryAdapter extends DoboAdapter {
9
+ constructor (plugin, name, options) {
10
+ super(plugin, name, options)
11
+ this.idGenerator = 'ulid'
12
+ this.saving = true
13
+ this.memory = true
14
+ this.storage = {}
15
+ this.support = {
16
+ propType: {
17
+ object: true,
18
+ array: true
19
+ }
20
+ }
21
+ }
22
+
23
+ async sanitizeConnection (conn) {
24
+ await super.sanitizeConnection(conn)
25
+ conn.memory = true
26
+ }
27
+
28
+ async connect (connection, noRebuild) {
29
+ const conn = this.plugin.getConnection('memory')
30
+ const { fs } = this.app.lib
31
+ const { startInterval } = this.app.lib
32
+ const dir = `${this.app.getPluginDataDir(this.plugin.ns)}/memDb/data` // persistence dir
33
+ fs.ensureDirSync(dir)
34
+ conn.persistences = conn.persistences ?? []
35
+
36
+ const models = this.plugin.getModelsByConnection(conn.name).map(model => {
37
+ if (conn.persistences.includes(model.name)) model.options.persistence = true
38
+ return model
39
+ })
40
+
41
+ for (const model of models) {
42
+ this.storage[model.name] = this.storage[model.name] ?? [] // init empty model
43
+ if (model.options.persistence) {
44
+ const file = `${dir}/${model.name}.json`
45
+ let data = []
46
+ if (fs.existsSync(file)) {
47
+ try {
48
+ data = JSON.parse(fs.readFileSync(file, 'utf8'))
49
+ } catch (err) {}
50
+ }
51
+ if (data.length === 0) await model.loadFixtures({ ignoreError: false })
52
+ else this.storage[model.name] = data
53
+ } else await model.loadFixtures({ ignoreError: false })
54
+ }
55
+ const handler = async () => {
56
+ if (!this.saving) return
57
+ this.saving = true
58
+ for (const model of models) {
59
+ if (!model.options.persistence) continue
60
+ try {
61
+ fs.writeFileSync(`${dir}/${model.name}.json`, JSON.stringify(this.storage[model.name], null, 2), 'utf8')
62
+ } catch (err) {}
63
+ }
64
+ this.saving = false
65
+ }
66
+
67
+ startInterval(handler, this.plugin.config.memDb.persistenceDur, 'memDbPersistence')
68
+ }
69
+
70
+ async _getOldRecord (model, id, options = {}) {
71
+ const idx = findIndex(this.storage[model.name], { _id: id })
72
+ const oldData = this.storage[model.name][idx]
73
+ return { idx, oldData }
74
+ }
75
+
76
+ async modelExists (model, options = {}) {
77
+ return { data: has(this.storage, model.name) }
78
+ }
79
+
80
+ async buildModel (model, options = {}) {
81
+ if (has(this.storage, model.name)) throw this.plugin.error('exist%s%s', this.plugin.t('model'), model.name)
82
+ this.storage[model.name] = []
83
+ if (options.noResult) return
84
+ return { data: true }
85
+ }
86
+
87
+ async dropModel (model, options = {}) {
88
+ if (!has(this.storage, model.name)) throw this.plugin.error('notFound%s%s', this.plugin.t('model'), model.name)
89
+ delete this.storage[model.name]
90
+ if (options.noResult) return
91
+ return { data: true }
92
+ }
93
+
94
+ async createRecord (model, body = {}, options = {}) {
95
+ this.storage[model.name].push(body)
96
+ return { data: body }
97
+ }
98
+
99
+ async getRecord (model, id, options = {}) {
100
+ const { oldData: data } = await this._getOldRecord(model, id)
101
+ return { data }
102
+ }
103
+
104
+ async updateRecord (model, id, body = {}, options = {}) {
105
+ const { idx, oldData } = await this._getOldRecord(model, id)
106
+ const data = defaultsDeep(body, oldData)
107
+ this.storage[model.name][idx] = data
108
+ return { oldData, data }
109
+ }
110
+
111
+ async removeRecord (model, id, options = {}) {
112
+ const { idx, oldData } = await this._getOldRecord(model, id)
113
+ pullAt(this.storage[model.name], idx)
114
+ return { oldData }
115
+ }
116
+
117
+ async clearRecord (model, options = {}) {
118
+ this.storage[model.name] = []
119
+ if (options.noResult) return
120
+ return { data: true }
121
+ }
122
+
123
+ async findRecord (model, filter = {}, options = {}) {
124
+ const { limit, skip, sort, page } = filter
125
+ const { data: count = 0 } = await this.countRecord(model, filter, options)
126
+ const cursor = this._getCursor(model, filter)
127
+ if (sort) cursor.sort(sort)
128
+ cursor.skip(skip).limit(limit)
129
+ let result = { data: cursor.all(), page, limit, count, pages: Math.ceil(count / limit) }
130
+ if (!options.count) result = omit(result, ['count', 'pages'])
131
+ return result
132
+ }
133
+
134
+ async findAllRecord (model, filter = {}, options = {}) {
135
+ const { hardCap } = this.app.dobo.getDefaultValues(options)
136
+ filter.limit = hardCap
137
+ delete filter.skip
138
+ delete filter.page
139
+ const { sort } = filter
140
+ const cursor = this._getCursor(model, filter)
141
+ cursor.limit(filter.limit)
142
+ if (sort) cursor.sort(sort)
143
+ return { data: cursor.all(), hardCapped: true }
144
+ }
145
+
146
+ async countRecord (model, filter = {}, options = {}) {
147
+ const cursor = this._getCursor(model, filter)
148
+ const data = cursor.all().length
149
+ return { data }
150
+ }
151
+
152
+ async aggregate (model, filter = {}, params = {}, options = {}) {
153
+ const item = await this.findAllRecord(model, filter, options)
154
+ const result = this.app.dobo.calcAggregate({ data: item.data, ...params })
155
+ return { data: result }
156
+ }
157
+
158
+ async histogram (model, filter = {}, params = {}, options = {}) {
159
+ const item = await this.findAllRecord(model, filter, options)
160
+ const result = this.app.dobo.calcHistogram({ data: item.data, ...params })
161
+ return { data: result }
162
+ }
163
+
164
+ _getCursor (model, filter) {
165
+ const criteria = filter.query ?? {}
166
+ const q = new Query(criteria, { idKey: '_id' })
167
+ return q.find(this.storage[model.name] ?? [])
168
+ }
169
+ }
170
+
171
+ this.app.baseClass.DoboMemoryAdapter = DoboMemoryAdapter
172
+ return DoboMemoryAdapter
173
+ }
174
+
175
+ export default memoryAdapterFactory
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/index.js CHANGED
File without changes