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.
- package/.bootorder +0 -0
- package/.github/FUNDING.yml +0 -0
- package/.github/workflows/repo-lockdown.yml +0 -0
- package/.jsdoc.conf.json +0 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/docs/Dobo.html +0 -0
- package/docs/DoboAction.html +0 -0
- package/docs/DoboAdapter.html +0 -0
- package/docs/DoboConnection.html +0 -0
- package/docs/DoboFeature.html +0 -0
- package/docs/DoboModel.html +0 -0
- package/docs/data/search.json +0 -0
- package/docs/extend_bajo_hook-docs.js.html +0 -0
- package/docs/external-Tools.html +0 -0
- package/docs/fonts/Inconsolata-Regular.ttf +0 -0
- package/docs/fonts/OpenSans-Regular.ttf +0 -0
- package/docs/fonts/WorkSans-Bold.ttf +0 -0
- package/docs/global.html +0 -0
- package/docs/index.html +0 -0
- package/docs/index.js.html +0 -0
- package/docs/lib_factory_action.js.html +0 -0
- package/docs/lib_factory_adapter.js.html +0 -0
- package/docs/lib_factory_connection.js.html +0 -0
- package/docs/lib_factory_feature.js.html +0 -0
- package/docs/lib_factory_model.js.html +0 -0
- package/docs/lib_factory_model_build.js.html +0 -0
- package/docs/lib_factory_model_clear-record.js.html +0 -0
- package/docs/lib_factory_model_count-record.js.html +0 -0
- package/docs/lib_factory_model_create-record.js.html +0 -0
- package/docs/lib_factory_model_drop.js.html +0 -0
- package/docs/lib_factory_model_exists.js.html +0 -0
- package/docs/lib_factory_model_find-all-record.js.html +0 -0
- package/docs/lib_factory_model_find-one-record.js.html +0 -0
- package/docs/lib_factory_model_find-record.js.html +0 -0
- package/docs/lib_factory_model_get-record.js.html +0 -0
- package/docs/lib_factory_model_helper.js.html +0 -0
- package/docs/lib_factory_model_remove-record.js.html +0 -0
- package/docs/lib_factory_model_sanitize-body.js.html +0 -0
- package/docs/lib_factory_model_sanitize-fixture.js.html +0 -0
- package/docs/lib_factory_model_sanitize-record.js.html +0 -0
- package/docs/lib_factory_model_update-record.js.html +0 -0
- package/docs/lib_factory_model_upsert-record.js.html +0 -0
- package/docs/lib_factory_model_validate.js.html +0 -0
- package/docs/lib_helper.js.html +0 -0
- package/docs/module-Helper.html +0 -0
- package/docs/module-Helper_Model.html +0 -0
- package/docs/module-Hook.html +0 -0
- package/docs/scripts/core.js +0 -0
- package/docs/scripts/core.min.js +0 -0
- package/docs/scripts/resize.js +0 -0
- package/docs/scripts/search.js +0 -0
- package/docs/scripts/search.min.js +5 -5
- package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
- package/docs/scripts/third-party/fuse.js +0 -0
- package/docs/scripts/third-party/hljs-line-num-original.js +0 -0
- package/docs/scripts/third-party/hljs-line-num.js +0 -0
- package/docs/scripts/third-party/hljs-original.js +0 -0
- package/docs/scripts/third-party/hljs.js +0 -0
- package/docs/scripts/third-party/popper.js +0 -0
- package/docs/scripts/third-party/tippy.js +0 -0
- package/docs/scripts/third-party/tocbot.js +0 -0
- package/docs/scripts/third-party/tocbot.min.js +0 -0
- package/docs/static/bitcoin.jpeg +0 -0
- package/docs/static/home.md +0 -0
- package/docs/static/logo-ecosystem.png +0 -0
- package/docs/static/logo.png +0 -0
- package/docs/styles/clean-jsdoc-theme-base.css +0 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
- package/docs/styles/clean-jsdoc-theme-light.css +0 -0
- package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
- package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
- package/docs/styles/clean-jsdoc-theme.min.css +0 -0
- package/extend/bajo/hook.js +236 -236
- package/extend/bajo/intl/en-US.json +0 -0
- package/extend/bajo/intl/id.json +0 -0
- package/extend/bajoCli/applet/aggregate.js +0 -0
- package/extend/bajoCli/applet/clear-record.js +0 -0
- package/extend/bajoCli/applet/connection.js +0 -0
- package/extend/bajoCli/applet/count-record.js +0 -0
- package/extend/bajoCli/applet/create-record.js +0 -0
- package/extend/bajoCli/applet/find-record.js +0 -0
- package/extend/bajoCli/applet/get-record.js +0 -0
- package/extend/bajoCli/applet/histogram.js +0 -0
- package/extend/bajoCli/applet/lib/post-process.js +0 -0
- package/extend/bajoCli/applet/model.js +0 -0
- package/extend/bajoCli/applet/rebuild-model.js +0 -0
- package/extend/bajoCli/applet/remove-record.js +0 -0
- package/extend/bajoCli/applet/update-record.js +0 -0
- package/extend/bajoCli/applet.js +0 -0
- package/extend/dobo/adapter/memory.js +175 -175
- package/extend/dobo/feature/created-at.js +0 -0
- package/extend/dobo/feature/dt.js +0 -0
- package/extend/dobo/feature/image.js +0 -0
- package/extend/dobo/feature/immutable.js +0 -0
- package/extend/dobo/feature/removed-at.js +0 -0
- package/extend/dobo/feature/unique.js +0 -0
- package/extend/dobo/feature/updated-at.js +0 -0
- package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +0 -0
- package/extend/waibuStatic/virtual.json +0 -0
- package/index.js +0 -0
- package/lib/factory/action.js +287 -287
- package/lib/factory/adapter.js +1055 -1055
- package/lib/factory/connection.js +109 -109
- package/lib/factory/feature.js +52 -52
- package/lib/factory/model/aggregate.js +23 -23
- package/lib/factory/model/build.js +25 -25
- package/lib/factory/model/bulk-create-record.js +36 -36
- package/lib/factory/model/clear-record.js +30 -30
- package/lib/factory/model/count-record.js +42 -42
- package/lib/factory/model/create-attachment.js +36 -36
- package/lib/factory/model/create-record.js +49 -49
- package/lib/factory/model/drop.js +26 -26
- package/lib/factory/model/exists.js +26 -26
- package/lib/factory/model/find-all-record.js +112 -112
- package/lib/factory/model/find-attachment.js +28 -28
- package/lib/factory/model/find-one-record.js +38 -38
- package/lib/factory/model/find-record.js +82 -82
- package/lib/factory/model/get-attachment.js +15 -15
- package/lib/factory/model/get-record.js +52 -52
- package/lib/factory/model/helper.js +575 -576
- package/lib/factory/model/histogram.js +23 -23
- package/lib/factory/model/list-attachment.js +40 -40
- package/lib/factory/model/load-fixtures.js +63 -63
- package/lib/factory/model/remove-attachment.js +24 -24
- package/lib/factory/model/remove-record.js +44 -44
- package/lib/factory/model/sanitize-body.js +57 -57
- package/lib/factory/model/sanitize-fixture.js +56 -56
- package/lib/factory/model/sanitize-record.js +80 -80
- package/lib/factory/model/transaction.js +15 -15
- package/lib/factory/model/update-attachment.js +9 -9
- package/lib/factory/model/update-record.js +58 -58
- package/lib/factory/model/upsert-record.js +71 -71
- package/lib/factory/model/validate.js +0 -0
- package/lib/factory/model.js +503 -503
- package/lib/helper.js +463 -463
- package/package.json +1 -1
- package/test/e2e/_run.js +12 -12
- package/test/e2e/e2e-factory-process.test.js +25 -25
- package/test/e2e/e2e-model-adapter-process.test.js +52 -52
- package/test/integration/aspect-01-start-connections.test.js +33 -33
- package/test/integration/aspect-02-query-regex.test.js +34 -34
- package/test/integration/aspect-03-model-adapter-flow.test.js +88 -88
- package/test/unit/_stub.js +244 -244
- package/test/unit/dobo-action.test.js +58 -58
- package/test/unit/dobo-connection.test.js +37 -37
- package/test/unit/dobo-core.test.js +136 -136
- package/test/unit/dobo-feature.test.js +25 -25
- package/test/unit/dobo-model.test.js +115 -115
- package/test/unit/helper-sanitize-all.test.js +40 -40
- package/test/unit/helper-sanitize-ref.test.js +64 -64
- package/wiki/APPLETS.md +0 -0
- package/wiki/CHANGES.md +477 -469
- package/wiki/CONFIG.md +0 -0
- package/wiki/CONTRIBUTING.md +0 -0
- package/wiki/DEV-GUIDE.md +0 -0
- package/wiki/ECOSYSTEM.md +0 -0
- package/wiki/GETTING-STARTED.md +0 -0
- package/wiki/QUERY-LANGUAGE.md +0 -0
- package/wiki/USER-GUIDE.md +0 -0
package/lib/factory/action.js
CHANGED
|
@@ -1,287 +1,287 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dobo model's chainable methods. Only the keys listed here are allowed to be called in chainable methods.
|
|
3
|
-
* The values are the only allowed arguments for the corresponding chainable methods.
|
|
4
|
-
* @typedef {Object} TMethods
|
|
5
|
-
* @type {Object}
|
|
6
|
-
* @memberof DoboAction
|
|
7
|
-
* @property {string[]} [createRecord=['body']]
|
|
8
|
-
* @property {string[]} [updateRecord=['id', 'body']]
|
|
9
|
-
* @property {string[]} [upsertRecord=['body']]
|
|
10
|
-
* @property {string[]} [removeRecord=['id']]
|
|
11
|
-
* @property {string[]} [getRecord=['id']]
|
|
12
|
-
* @property {string[]} [findRecord=['filter']]
|
|
13
|
-
* @property {string[]} [findOneRecord=['filter']]
|
|
14
|
-
* @property {string[]} [findAllRecord=['filter']]
|
|
15
|
-
* @property {string[]} [findAllRecords=['filter']] - Alias of `findAllRecord`
|
|
16
|
-
* @property {string[]} [countRecord=['params']]
|
|
17
|
-
* @property {string[]} [aggregate=['params']]
|
|
18
|
-
* @property {string[]} [histogram=['params']]
|
|
19
|
-
* @property {string[]} [createAttachment=['id']]
|
|
20
|
-
* @property {string[]} [findAttachment=['id']]
|
|
21
|
-
* @property {string[]} [getAttachment=['id', 'field', 'file']]
|
|
22
|
-
* @property {string[]} [listAttachment=['params']]
|
|
23
|
-
* @property {string[]} [removeAttachment=['id', 'field', 'file']]
|
|
24
|
-
* @property {string[]} [updateAttachment=['id']]
|
|
25
|
-
*/
|
|
26
|
-
const methods = {
|
|
27
|
-
createRecord: ['body'],
|
|
28
|
-
updateRecord: ['id', 'body'],
|
|
29
|
-
upsertRecord: ['body'],
|
|
30
|
-
removeRecord: ['id'],
|
|
31
|
-
getRecord: ['id'],
|
|
32
|
-
findRecord: ['filter'],
|
|
33
|
-
findOneRecord: ['filter'],
|
|
34
|
-
findAllRecord: ['filter'],
|
|
35
|
-
findAllRecords: ['filter'],
|
|
36
|
-
countRecord: ['params'],
|
|
37
|
-
aggregate: ['params'],
|
|
38
|
-
histogram: ['params'],
|
|
39
|
-
createAttachment: ['id'],
|
|
40
|
-
findAttachment: ['id'],
|
|
41
|
-
getAttachment: ['id', 'field', 'file'],
|
|
42
|
-
listAttachment: ['params'],
|
|
43
|
-
removeAttachment: ['id', 'field', 'file'],
|
|
44
|
-
updateAttachment: ['id']
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Allowed options for Dobo model's chainable methods. Only the keys listed here are allowed to be called
|
|
49
|
-
* in chainable methods. The values are the default values for the corresponding options.
|
|
50
|
-
* @typedef {Object} TOptions
|
|
51
|
-
* @type {Object}
|
|
52
|
-
* @memberof DoboAction
|
|
53
|
-
* @property {boolean} [truncateString=true]
|
|
54
|
-
* @property {boolean} [noResult=false]
|
|
55
|
-
* @property {boolean} [noBodySanitizer=false]
|
|
56
|
-
* @property {boolean} [noResultSanitizer=false]
|
|
57
|
-
* @property {boolean} [noValidation=false]
|
|
58
|
-
* @property {boolean} [dataOnly=true]
|
|
59
|
-
* @property {boolean} [noHook=false]
|
|
60
|
-
* @property {boolean} [noModelHook=false]
|
|
61
|
-
* @property {boolean} [noDynHook=false]
|
|
62
|
-
* @property {Array} [extFields=[]]
|
|
63
|
-
* @property {Array} [fields=[]]
|
|
64
|
-
* @property {boolean} [noFlash=false]
|
|
65
|
-
* @property {Array} [hidden=[]]
|
|
66
|
-
* @property {Array} [refs=[]]
|
|
67
|
-
* @property {Array} [types=[]]
|
|
68
|
-
* @property {string|undefined} [type=undefined]
|
|
69
|
-
* @property {string|undefined} [group=undefined]
|
|
70
|
-
* @property {Array} [aggregates=[]]
|
|
71
|
-
* @property {string|undefined} [field=undefined]
|
|
72
|
-
* @property {string|undefined} [queryHandler=undefined]
|
|
73
|
-
* @property {boolean} [count=true]
|
|
74
|
-
* @property {boolean} [noCache=true]
|
|
75
|
-
* @property {boolean} [partial=true]
|
|
76
|
-
* @property {boolean} [mimeType=true]
|
|
77
|
-
* @property {boolean} [fullPath=true]
|
|
78
|
-
* @property {boolean} [stats=true]
|
|
79
|
-
* @property {boolean} [dirOnly=true]
|
|
80
|
-
* @property {string|undefined} [setField=undefined]
|
|
81
|
-
* @property {string|undefined} [setFile=undefined]
|
|
82
|
-
* @property {string|undefined} [source=undefined]
|
|
83
|
-
* @property {boolean} [uriEncoded=true]
|
|
84
|
-
*/
|
|
85
|
-
const options = {
|
|
86
|
-
truncateString: true,
|
|
87
|
-
noResult: false,
|
|
88
|
-
noBodySanitizer: false,
|
|
89
|
-
noResultSanitizer: false,
|
|
90
|
-
noValidation: false,
|
|
91
|
-
dataOnly: true,
|
|
92
|
-
noHook: false,
|
|
93
|
-
noModelHook: false,
|
|
94
|
-
noDynHook: false,
|
|
95
|
-
extFields: [],
|
|
96
|
-
fields: [],
|
|
97
|
-
noFlash: false,
|
|
98
|
-
hidden: [],
|
|
99
|
-
refs: [],
|
|
100
|
-
types: [],
|
|
101
|
-
type: undefined,
|
|
102
|
-
group: undefined,
|
|
103
|
-
aggregates: [],
|
|
104
|
-
field: undefined,
|
|
105
|
-
queryHandler: undefined,
|
|
106
|
-
count: true,
|
|
107
|
-
noCache: true,
|
|
108
|
-
partial: true,
|
|
109
|
-
// attachment
|
|
110
|
-
mimeType: true,
|
|
111
|
-
fullPath: true,
|
|
112
|
-
stats: true,
|
|
113
|
-
dirOnly: true,
|
|
114
|
-
setField: undefined,
|
|
115
|
-
setFile: undefined,
|
|
116
|
-
source: undefined,
|
|
117
|
-
uriEncoded: true
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Action factory function
|
|
122
|
-
*
|
|
123
|
-
* @async
|
|
124
|
-
* @returns {Promise<void>}
|
|
125
|
-
*/
|
|
126
|
-
async function actionFactory () {
|
|
127
|
-
const { Tools } = this.app.baseClass
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Action class enables you to call model's method with all parameters and options in chainable methods
|
|
131
|
-
* in addition of the normal call.
|
|
132
|
-
*
|
|
133
|
-
* Action class is created by calling model method without any parameter.
|
|
134
|
-
* The resulted class instance can be used to call model's method with all parameters and options
|
|
135
|
-
* in chainable methods.
|
|
136
|
-
*
|
|
137
|
-
* Action class can also be created by calling `model.action()` method, with or without parameters.
|
|
138
|
-
* Please see the example below:
|
|
139
|
-
*
|
|
140
|
-
* You always need to call the `run()` method as the last step. The `run()` method will return the result
|
|
141
|
-
* of the model's method call.
|
|
142
|
-
*
|
|
143
|
-
* @class
|
|
144
|
-
* @example
|
|
145
|
-
* // method 1:
|
|
146
|
-
* const action = await model.getRecord() // Important: no parameter passed
|
|
147
|
-
* const result = action.id('rec-id').noHook().dataOnly(false).run()
|
|
148
|
-
* // method 2:
|
|
149
|
-
* const result = await model.action().getRecord('rec-id').noHook().dataOnly(false).run()
|
|
150
|
-
* // method 3:
|
|
151
|
-
* const result = await model.action('getRecord').id('rec-id').noHook().dataOnly(false).run()
|
|
152
|
-
* // method 4:
|
|
153
|
-
* const result = await model.action('getRecord', 'rec-id').noHook().dataOnly(false).run()
|
|
154
|
-
* // Instead of chaining options as methods, you can also pass options object as the parameter to the run() method
|
|
155
|
-
* const result = await model.action('getRecord', 'rec-id').run({ noHook: true, dataOnly: false })
|
|
156
|
-
*/
|
|
157
|
-
class DoboAction extends Tools {
|
|
158
|
-
constructor (model, name, ...args) {
|
|
159
|
-
super(model.plugin)
|
|
160
|
-
this.model = model
|
|
161
|
-
this.name = name
|
|
162
|
-
this._options = {}
|
|
163
|
-
if (name) this._setArgs(name, args)
|
|
164
|
-
// create methods
|
|
165
|
-
for (const method in methods) {
|
|
166
|
-
this[method] = (...args) => {
|
|
167
|
-
this.name = method
|
|
168
|
-
this._setArgs(method, args)
|
|
169
|
-
this._options = {}
|
|
170
|
-
return this
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// create options builder methods
|
|
174
|
-
for (const option in options) {
|
|
175
|
-
this[option] = (value) => {
|
|
176
|
-
this._options[option] = value ?? options[option]
|
|
177
|
-
return this
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Internal method to set the arguments to the instance properties based on the method name
|
|
184
|
-
* and the arguments passed.
|
|
185
|
-
* @internal
|
|
186
|
-
* @method
|
|
187
|
-
* @param {string} method - The name of the method being called
|
|
188
|
-
* @param {Array} args - The arguments passed to the method
|
|
189
|
-
* @returns {void}
|
|
190
|
-
*/
|
|
191
|
-
_setArgs = (method, args) => {
|
|
192
|
-
if (args.length === 0) return
|
|
193
|
-
for (const idx in methods[method]) {
|
|
194
|
-
this['_' + methods[method][idx]] = args[idx]
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Set the ID for the corresponding record. You need this for `updateRecord` or `removeRecord`
|
|
200
|
-
* operations. This method is chainable.
|
|
201
|
-
* @method
|
|
202
|
-
* @param {string|number} value - The ID value to set
|
|
203
|
-
* @returns {DoboAction} The current instance for chaining
|
|
204
|
-
*/
|
|
205
|
-
id = value => {
|
|
206
|
-
this._id = value
|
|
207
|
-
return this
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Set the body for the corresponding record. You need this for `createRecord`, `updateRecord`
|
|
212
|
-
* or `upsertRecord` operations. This method is chainable.
|
|
213
|
-
* @method
|
|
214
|
-
* @param {object} value - The body value to set
|
|
215
|
-
* @returns {DoboAction} The current instance for chaining
|
|
216
|
-
*/
|
|
217
|
-
body = value => {
|
|
218
|
-
this._body = value
|
|
219
|
-
return this
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Set the filter for the corresponding record. You optionally need this for `findRecord`,
|
|
224
|
-
* `findOneRecord` or `findAllRecord` operations. This method is chainable.
|
|
225
|
-
* @method
|
|
226
|
-
* @param {object} value - The filter value to set
|
|
227
|
-
* @returns {DoboAction} The current instance for chaining
|
|
228
|
-
*/
|
|
229
|
-
filter = value => {
|
|
230
|
-
this._filter = value
|
|
231
|
-
return this
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
field = value => {
|
|
235
|
-
this._field = value
|
|
236
|
-
return this
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
file = value => {
|
|
240
|
-
this._file = value
|
|
241
|
-
return this
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Set the options for the corresponding method. This method is chainable.
|
|
246
|
-
* @method
|
|
247
|
-
* @param {DoboAction.TOptions} value - The options to set
|
|
248
|
-
* @returns {DoboAction} The current instance for chaining
|
|
249
|
-
*/
|
|
250
|
-
options = (value = {}) => {
|
|
251
|
-
for (const k in value) {
|
|
252
|
-
this._options[k] = value
|
|
253
|
-
}
|
|
254
|
-
return this
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Execute the corresponding method with the set arguments and options. This method is chainable.
|
|
259
|
-
* @async
|
|
260
|
-
* @method
|
|
261
|
-
* @param {DoboAction.TOptions} value - If set, it will override the options set by the `options()` method. This is useful if you want to set options at the last step.
|
|
262
|
-
* @returns {Promise<*>} The result of the method execution
|
|
263
|
-
*/
|
|
264
|
-
run = async (value = {}) => {
|
|
265
|
-
this.options(value)
|
|
266
|
-
const args = methods[this.name].map(item => this['_' + item])
|
|
267
|
-
args.push(this._options)
|
|
268
|
-
return await this.model[this.name](...args)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Dispose the instance and clean up resources.
|
|
273
|
-
* @async
|
|
274
|
-
* @method
|
|
275
|
-
* @returns {Promise<void>}
|
|
276
|
-
*/
|
|
277
|
-
dispose = async () => {
|
|
278
|
-
await super.dispose()
|
|
279
|
-
this.model = null
|
|
280
|
-
this._options = null
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
this.app.baseClass.DoboAction = DoboAction
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
export default actionFactory
|
|
1
|
+
/**
|
|
2
|
+
* Dobo model's chainable methods. Only the keys listed here are allowed to be called in chainable methods.
|
|
3
|
+
* The values are the only allowed arguments for the corresponding chainable methods.
|
|
4
|
+
* @typedef {Object} TMethods
|
|
5
|
+
* @type {Object}
|
|
6
|
+
* @memberof DoboAction
|
|
7
|
+
* @property {string[]} [createRecord=['body']]
|
|
8
|
+
* @property {string[]} [updateRecord=['id', 'body']]
|
|
9
|
+
* @property {string[]} [upsertRecord=['body']]
|
|
10
|
+
* @property {string[]} [removeRecord=['id']]
|
|
11
|
+
* @property {string[]} [getRecord=['id']]
|
|
12
|
+
* @property {string[]} [findRecord=['filter']]
|
|
13
|
+
* @property {string[]} [findOneRecord=['filter']]
|
|
14
|
+
* @property {string[]} [findAllRecord=['filter']]
|
|
15
|
+
* @property {string[]} [findAllRecords=['filter']] - Alias of `findAllRecord`
|
|
16
|
+
* @property {string[]} [countRecord=['params']]
|
|
17
|
+
* @property {string[]} [aggregate=['params']]
|
|
18
|
+
* @property {string[]} [histogram=['params']]
|
|
19
|
+
* @property {string[]} [createAttachment=['id']]
|
|
20
|
+
* @property {string[]} [findAttachment=['id']]
|
|
21
|
+
* @property {string[]} [getAttachment=['id', 'field', 'file']]
|
|
22
|
+
* @property {string[]} [listAttachment=['params']]
|
|
23
|
+
* @property {string[]} [removeAttachment=['id', 'field', 'file']]
|
|
24
|
+
* @property {string[]} [updateAttachment=['id']]
|
|
25
|
+
*/
|
|
26
|
+
const methods = {
|
|
27
|
+
createRecord: ['body'],
|
|
28
|
+
updateRecord: ['id', 'body'],
|
|
29
|
+
upsertRecord: ['body'],
|
|
30
|
+
removeRecord: ['id'],
|
|
31
|
+
getRecord: ['id'],
|
|
32
|
+
findRecord: ['filter'],
|
|
33
|
+
findOneRecord: ['filter'],
|
|
34
|
+
findAllRecord: ['filter'],
|
|
35
|
+
findAllRecords: ['filter'],
|
|
36
|
+
countRecord: ['params'],
|
|
37
|
+
aggregate: ['params'],
|
|
38
|
+
histogram: ['params'],
|
|
39
|
+
createAttachment: ['id'],
|
|
40
|
+
findAttachment: ['id'],
|
|
41
|
+
getAttachment: ['id', 'field', 'file'],
|
|
42
|
+
listAttachment: ['params'],
|
|
43
|
+
removeAttachment: ['id', 'field', 'file'],
|
|
44
|
+
updateAttachment: ['id']
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Allowed options for Dobo model's chainable methods. Only the keys listed here are allowed to be called
|
|
49
|
+
* in chainable methods. The values are the default values for the corresponding options.
|
|
50
|
+
* @typedef {Object} TOptions
|
|
51
|
+
* @type {Object}
|
|
52
|
+
* @memberof DoboAction
|
|
53
|
+
* @property {boolean} [truncateString=true]
|
|
54
|
+
* @property {boolean} [noResult=false]
|
|
55
|
+
* @property {boolean} [noBodySanitizer=false]
|
|
56
|
+
* @property {boolean} [noResultSanitizer=false]
|
|
57
|
+
* @property {boolean} [noValidation=false]
|
|
58
|
+
* @property {boolean} [dataOnly=true]
|
|
59
|
+
* @property {boolean} [noHook=false]
|
|
60
|
+
* @property {boolean} [noModelHook=false]
|
|
61
|
+
* @property {boolean} [noDynHook=false]
|
|
62
|
+
* @property {Array} [extFields=[]]
|
|
63
|
+
* @property {Array} [fields=[]]
|
|
64
|
+
* @property {boolean} [noFlash=false]
|
|
65
|
+
* @property {Array} [hidden=[]]
|
|
66
|
+
* @property {Array} [refs=[]]
|
|
67
|
+
* @property {Array} [types=[]]
|
|
68
|
+
* @property {string|undefined} [type=undefined]
|
|
69
|
+
* @property {string|undefined} [group=undefined]
|
|
70
|
+
* @property {Array} [aggregates=[]]
|
|
71
|
+
* @property {string|undefined} [field=undefined]
|
|
72
|
+
* @property {string|undefined} [queryHandler=undefined]
|
|
73
|
+
* @property {boolean} [count=true]
|
|
74
|
+
* @property {boolean} [noCache=true]
|
|
75
|
+
* @property {boolean} [partial=true]
|
|
76
|
+
* @property {boolean} [mimeType=true]
|
|
77
|
+
* @property {boolean} [fullPath=true]
|
|
78
|
+
* @property {boolean} [stats=true]
|
|
79
|
+
* @property {boolean} [dirOnly=true]
|
|
80
|
+
* @property {string|undefined} [setField=undefined]
|
|
81
|
+
* @property {string|undefined} [setFile=undefined]
|
|
82
|
+
* @property {string|undefined} [source=undefined]
|
|
83
|
+
* @property {boolean} [uriEncoded=true]
|
|
84
|
+
*/
|
|
85
|
+
const options = {
|
|
86
|
+
truncateString: true,
|
|
87
|
+
noResult: false,
|
|
88
|
+
noBodySanitizer: false,
|
|
89
|
+
noResultSanitizer: false,
|
|
90
|
+
noValidation: false,
|
|
91
|
+
dataOnly: true,
|
|
92
|
+
noHook: false,
|
|
93
|
+
noModelHook: false,
|
|
94
|
+
noDynHook: false,
|
|
95
|
+
extFields: [],
|
|
96
|
+
fields: [],
|
|
97
|
+
noFlash: false,
|
|
98
|
+
hidden: [],
|
|
99
|
+
refs: [],
|
|
100
|
+
types: [],
|
|
101
|
+
type: undefined,
|
|
102
|
+
group: undefined,
|
|
103
|
+
aggregates: [],
|
|
104
|
+
field: undefined,
|
|
105
|
+
queryHandler: undefined,
|
|
106
|
+
count: true,
|
|
107
|
+
noCache: true,
|
|
108
|
+
partial: true,
|
|
109
|
+
// attachment
|
|
110
|
+
mimeType: true,
|
|
111
|
+
fullPath: true,
|
|
112
|
+
stats: true,
|
|
113
|
+
dirOnly: true,
|
|
114
|
+
setField: undefined,
|
|
115
|
+
setFile: undefined,
|
|
116
|
+
source: undefined,
|
|
117
|
+
uriEncoded: true
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Action factory function
|
|
122
|
+
*
|
|
123
|
+
* @async
|
|
124
|
+
* @returns {Promise<void>}
|
|
125
|
+
*/
|
|
126
|
+
async function actionFactory () {
|
|
127
|
+
const { Tools } = this.app.baseClass
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Action class enables you to call model's method with all parameters and options in chainable methods
|
|
131
|
+
* in addition of the normal call.
|
|
132
|
+
*
|
|
133
|
+
* Action class is created by calling model method without any parameter.
|
|
134
|
+
* The resulted class instance can be used to call model's method with all parameters and options
|
|
135
|
+
* in chainable methods.
|
|
136
|
+
*
|
|
137
|
+
* Action class can also be created by calling `model.action()` method, with or without parameters.
|
|
138
|
+
* Please see the example below:
|
|
139
|
+
*
|
|
140
|
+
* You always need to call the `run()` method as the last step. The `run()` method will return the result
|
|
141
|
+
* of the model's method call.
|
|
142
|
+
*
|
|
143
|
+
* @class
|
|
144
|
+
* @example
|
|
145
|
+
* // method 1:
|
|
146
|
+
* const action = await model.getRecord() // Important: no parameter passed
|
|
147
|
+
* const result = action.id('rec-id').noHook().dataOnly(false).run()
|
|
148
|
+
* // method 2:
|
|
149
|
+
* const result = await model.action().getRecord('rec-id').noHook().dataOnly(false).run()
|
|
150
|
+
* // method 3:
|
|
151
|
+
* const result = await model.action('getRecord').id('rec-id').noHook().dataOnly(false).run()
|
|
152
|
+
* // method 4:
|
|
153
|
+
* const result = await model.action('getRecord', 'rec-id').noHook().dataOnly(false).run()
|
|
154
|
+
* // Instead of chaining options as methods, you can also pass options object as the parameter to the run() method
|
|
155
|
+
* const result = await model.action('getRecord', 'rec-id').run({ noHook: true, dataOnly: false })
|
|
156
|
+
*/
|
|
157
|
+
class DoboAction extends Tools {
|
|
158
|
+
constructor (model, name, ...args) {
|
|
159
|
+
super(model.plugin)
|
|
160
|
+
this.model = model
|
|
161
|
+
this.name = name
|
|
162
|
+
this._options = {}
|
|
163
|
+
if (name) this._setArgs(name, args)
|
|
164
|
+
// create methods
|
|
165
|
+
for (const method in methods) {
|
|
166
|
+
this[method] = (...args) => {
|
|
167
|
+
this.name = method
|
|
168
|
+
this._setArgs(method, args)
|
|
169
|
+
this._options = {}
|
|
170
|
+
return this
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// create options builder methods
|
|
174
|
+
for (const option in options) {
|
|
175
|
+
this[option] = (value) => {
|
|
176
|
+
this._options[option] = value ?? options[option]
|
|
177
|
+
return this
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Internal method to set the arguments to the instance properties based on the method name
|
|
184
|
+
* and the arguments passed.
|
|
185
|
+
* @internal
|
|
186
|
+
* @method
|
|
187
|
+
* @param {string} method - The name of the method being called
|
|
188
|
+
* @param {Array} args - The arguments passed to the method
|
|
189
|
+
* @returns {void}
|
|
190
|
+
*/
|
|
191
|
+
_setArgs = (method, args) => {
|
|
192
|
+
if (args.length === 0) return
|
|
193
|
+
for (const idx in methods[method]) {
|
|
194
|
+
this['_' + methods[method][idx]] = args[idx]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Set the ID for the corresponding record. You need this for `updateRecord` or `removeRecord`
|
|
200
|
+
* operations. This method is chainable.
|
|
201
|
+
* @method
|
|
202
|
+
* @param {string|number} value - The ID value to set
|
|
203
|
+
* @returns {DoboAction} The current instance for chaining
|
|
204
|
+
*/
|
|
205
|
+
id = value => {
|
|
206
|
+
this._id = value
|
|
207
|
+
return this
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Set the body for the corresponding record. You need this for `createRecord`, `updateRecord`
|
|
212
|
+
* or `upsertRecord` operations. This method is chainable.
|
|
213
|
+
* @method
|
|
214
|
+
* @param {object} value - The body value to set
|
|
215
|
+
* @returns {DoboAction} The current instance for chaining
|
|
216
|
+
*/
|
|
217
|
+
body = value => {
|
|
218
|
+
this._body = value
|
|
219
|
+
return this
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Set the filter for the corresponding record. You optionally need this for `findRecord`,
|
|
224
|
+
* `findOneRecord` or `findAllRecord` operations. This method is chainable.
|
|
225
|
+
* @method
|
|
226
|
+
* @param {object} value - The filter value to set
|
|
227
|
+
* @returns {DoboAction} The current instance for chaining
|
|
228
|
+
*/
|
|
229
|
+
filter = value => {
|
|
230
|
+
this._filter = value
|
|
231
|
+
return this
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
field = value => {
|
|
235
|
+
this._field = value
|
|
236
|
+
return this
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
file = value => {
|
|
240
|
+
this._file = value
|
|
241
|
+
return this
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Set the options for the corresponding method. This method is chainable.
|
|
246
|
+
* @method
|
|
247
|
+
* @param {DoboAction.TOptions} value - The options to set
|
|
248
|
+
* @returns {DoboAction} The current instance for chaining
|
|
249
|
+
*/
|
|
250
|
+
options = (value = {}) => {
|
|
251
|
+
for (const k in value) {
|
|
252
|
+
this._options[k] = value
|
|
253
|
+
}
|
|
254
|
+
return this
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Execute the corresponding method with the set arguments and options. This method is chainable.
|
|
259
|
+
* @async
|
|
260
|
+
* @method
|
|
261
|
+
* @param {DoboAction.TOptions} value - If set, it will override the options set by the `options()` method. This is useful if you want to set options at the last step.
|
|
262
|
+
* @returns {Promise<*>} The result of the method execution
|
|
263
|
+
*/
|
|
264
|
+
run = async (value = {}) => {
|
|
265
|
+
this.options(value)
|
|
266
|
+
const args = methods[this.name].map(item => this['_' + item])
|
|
267
|
+
args.push(this._options)
|
|
268
|
+
return await this.model[this.name](...args)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Dispose the instance and clean up resources.
|
|
273
|
+
* @async
|
|
274
|
+
* @method
|
|
275
|
+
* @returns {Promise<void>}
|
|
276
|
+
*/
|
|
277
|
+
dispose = async () => {
|
|
278
|
+
await super.dispose()
|
|
279
|
+
this.model = null
|
|
280
|
+
this._options = null
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
this.app.baseClass.DoboAction = DoboAction
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export default actionFactory
|