dobo 2.30.7 → 2.32.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 (123) hide show
  1. package/.jsdoc.conf.json +1 -1
  2. package/docs/Dobo.html +1 -24
  3. package/docs/DoboAction.html +13 -0
  4. package/docs/DoboAdapter.html +3 -0
  5. package/docs/DoboConnection.html +3 -0
  6. package/docs/DoboFeature.html +3 -0
  7. package/docs/DoboModel.html +51 -0
  8. package/docs/data/search.json +1 -1
  9. package/docs/extend_bajo_hook-docs.js.html +241 -0
  10. package/docs/external-Tools.html +3 -0
  11. package/docs/global.html +1 -5
  12. package/docs/index.html +1 -1
  13. package/docs/index.js.html +434 -380
  14. package/docs/lib_factory_action.js.html +290 -0
  15. package/docs/lib_factory_adapter.js.html +1057 -0
  16. package/docs/lib_factory_connection.js.html +112 -0
  17. package/docs/lib_factory_feature.js.html +55 -0
  18. package/docs/lib_factory_model.js.html +503 -0
  19. package/docs/lib_factory_model_build.js.html +28 -0
  20. package/docs/lib_factory_model_clear-record.js.html +33 -0
  21. package/docs/lib_factory_model_count-record.js.html +45 -0
  22. package/docs/lib_factory_model_create-record.js.html +52 -0
  23. package/docs/lib_factory_model_drop.js.html +29 -0
  24. package/docs/lib_factory_model_exists.js.html +29 -0
  25. package/docs/lib_factory_model_find-all-record.js.html +115 -0
  26. package/docs/lib_factory_model_find-one-record.js.html +41 -0
  27. package/docs/lib_factory_model_find-record.js.html +85 -0
  28. package/docs/lib_factory_model_get-record.js.html +55 -0
  29. package/docs/lib_factory_model_helper.js.html +579 -0
  30. package/docs/lib_factory_model_remove-record.js.html +47 -0
  31. package/docs/lib_factory_model_sanitize-body.js.html +60 -0
  32. package/docs/lib_factory_model_sanitize-fixture.js.html +59 -0
  33. package/docs/lib_factory_model_sanitize-record.js.html +73 -0
  34. package/docs/lib_factory_model_update-record.js.html +61 -0
  35. package/docs/lib_factory_model_upsert-record.js.html +74 -0
  36. package/docs/{method_validate.js.html → lib_factory_model_validate.js.html} +109 -73
  37. package/docs/lib_helper.js.html +466 -0
  38. package/docs/module-Helper.html +3 -0
  39. package/docs/module-Helper_Model.html +3 -0
  40. package/docs/module-Hook.html +15 -0
  41. package/docs/scripts/core.js +477 -476
  42. package/docs/scripts/resize.js +36 -36
  43. package/docs/scripts/search.js +105 -105
  44. package/docs/scripts/third-party/fuse.js +1 -1
  45. package/docs/scripts/third-party/hljs-line-num-original.js +285 -282
  46. package/docs/scripts/third-party/hljs-line-num.js +1 -1
  47. package/docs/scripts/third-party/hljs-original.js +1202 -1195
  48. package/docs/scripts/third-party/hljs.js +1 -1
  49. package/docs/scripts/third-party/popper.js +1 -1
  50. package/docs/scripts/third-party/tippy.js +1 -1
  51. package/docs/scripts/third-party/tocbot.js +509 -508
  52. package/docs/static/home.md +3 -1
  53. package/extend/bajo/hook-docs.js +238 -0
  54. package/extend/bajo/intl/en-US.json +9 -9
  55. package/extend/bajo/intl/id.json +9 -9
  56. package/extend/bajoCli/applet/rebuild-model.js +2 -2
  57. package/extend/dobo/{driver → adapter}/memory.js +6 -6
  58. package/extend/dobo/feature/immutable.js +2 -2
  59. package/extend/dobo/feature/removed-at.js +1 -1
  60. package/index.js +33 -30
  61. package/lib/factory/action.js +145 -18
  62. package/lib/factory/adapter.js +1054 -0
  63. package/lib/factory/connection.js +46 -22
  64. package/lib/factory/feature.js +23 -3
  65. package/lib/factory/model/build.js +11 -2
  66. package/lib/factory/model/bulk-create-record.js +2 -2
  67. package/lib/factory/model/clear-record.js +13 -3
  68. package/lib/factory/model/count-record.js +13 -2
  69. package/lib/factory/model/create-aggregate.js +2 -2
  70. package/lib/factory/model/create-attachment.js +1 -1
  71. package/lib/factory/model/create-histogram.js +2 -2
  72. package/lib/factory/model/create-record.js +15 -2
  73. package/lib/factory/model/drop.js +12 -2
  74. package/lib/factory/model/exists.js +10 -6
  75. package/lib/factory/model/find-all-record.js +14 -3
  76. package/lib/factory/model/find-attachment.js +1 -1
  77. package/lib/factory/model/find-one-record.js +13 -1
  78. package/lib/factory/model/find-record.js +17 -53
  79. package/lib/factory/model/get-record.js +11 -39
  80. package/lib/factory/model/{_util.js → helper.js} +176 -16
  81. package/lib/factory/model/remove-attachment.js +1 -1
  82. package/lib/factory/model/remove-record.js +11 -28
  83. package/lib/factory/model/sanitize-body.js +14 -12
  84. package/lib/factory/model/sanitize-fixture.js +17 -4
  85. package/lib/factory/model/sanitize-record.js +9 -6
  86. package/lib/factory/model/transaction.js +2 -2
  87. package/lib/factory/model/update-record.js +12 -40
  88. package/lib/factory/model/upsert-record.js +13 -42
  89. package/lib/factory/model/validate.js +47 -14
  90. package/lib/factory/model.js +301 -23
  91. package/lib/{collect-models.js → helper.js} +463 -364
  92. package/package.json +1 -1
  93. package/wiki/CHANGES.md +17 -7
  94. package/wiki/ECOSYSTEM.md +7 -7
  95. package/wiki/GETTING-STARTED.md +3 -3
  96. package/wiki/QUERY-LANGUAGE.md +1 -1
  97. package/docs/lib_collect-connections.js.html +0 -39
  98. package/docs/lib_collect-drivers.js.html +0 -52
  99. package/docs/lib_collect-features.js.html +0 -36
  100. package/docs/lib_collect-schemas.js.html +0 -94
  101. package/docs/lib_index.js.html +0 -6
  102. package/docs/method_model_create.js.html +0 -35
  103. package/docs/method_model_drop.js.html +0 -34
  104. package/docs/method_model_exists.js.html +0 -40
  105. package/docs/method_record_count.js.html +0 -69
  106. package/docs/method_record_create.js.html +0 -114
  107. package/docs/method_record_find-all.js.html +0 -44
  108. package/docs/method_record_find-one.js.html +0 -73
  109. package/docs/method_record_find.js.html +0 -118
  110. package/docs/method_record_get.js.html +0 -92
  111. package/docs/method_record_remove.js.html +0 -75
  112. package/docs/method_record_update.js.html +0 -107
  113. package/docs/method_record_upsert.js.html +0 -54
  114. package/docs/method_sanitize_body.js.html +0 -88
  115. package/docs/method_sanitize_date.js.html +0 -30
  116. package/docs/method_sanitize_id.js.html +0 -20
  117. package/docs/module-Lib.html +0 -3
  118. package/lib/collect-connections.js +0 -56
  119. package/lib/collect-drivers.js +0 -35
  120. package/lib/collect-features.js +0 -40
  121. package/lib/factory/driver.js +0 -574
  122. package/lib/factory/model/sanitize-id.js +0 -7
  123. package/lib/index.js +0 -3
@@ -1,9 +1,21 @@
1
+ /**
2
+ * @typedef TOptions
3
+ * @memberof DoboConnection
4
+ * @property {string} [name='default'] - Connection name
5
+ * @property {string[]} models - List of model names to be used with this connection. Use this property to force models to be bound to this connection only.
6
+ */
7
+
8
+ /**
9
+ * Connection factory
10
+ *
11
+ * @async
12
+ */
1
13
  async function connectionFactory () {
2
14
  const { Tools } = this.app.baseClass
3
15
  const { omit } = this.app.lib._
4
16
 
5
17
  /**
6
- * Connection class
18
+ * Connection class definition.
7
19
  *
8
20
  * @class
9
21
  */
@@ -11,71 +23,83 @@ async function connectionFactory () {
11
23
  constructor (plugin, options = {}) {
12
24
  super(plugin)
13
25
  /**
14
- * Driver object
15
- *
26
+ * Adapter object
16
27
  * @type {Object}
17
28
  */
18
- this.driver = undefined
29
+ this.adapter = undefined
19
30
 
20
31
  /**
21
32
  * Client instance
33
+ * @type {Object}
22
34
  */
23
35
  this.client = undefined
24
36
 
25
37
  /**
26
38
  * Connection name
27
- *
28
39
  * @type {string}
29
40
  */
30
41
  this.name = options.name
42
+
43
+ /**
44
+ * Connection options
45
+ * @type {DoboConnection.TOptions}
46
+ */
31
47
  this.options = {
32
48
  models: []
33
49
  }
34
50
 
35
51
  /**
36
52
  * Options object from connection defined on ```dobo.config.connections```
37
- *
38
53
  * @type {Object}
39
54
  */
40
- if (options instanceof this.app.baseClass.DoboNullDriver) {
41
- this.driver = options
42
- this.options.connName = 'nulldriver'
55
+ if (options instanceof this.app.baseClass.DoboNullAdapter) {
56
+ this.adapter = options
57
+ this.options.connName = 'nulladapter'
43
58
  } else {
44
- this.options = omit(options, ['name', 'driver'])
59
+ this.options = omit(options, ['name', 'adapter'])
45
60
  this.options.connName = options.name
46
61
  this.options.models = this.options.models ?? []
47
62
  }
48
63
  }
49
64
 
50
65
  /**
51
- * Init driver. Called automatically during connections collection
52
- *
53
- * @param {strin} name - Driver name
66
+ * Initialize the adapter for this connection. If the adapter is already an instance of `DoboAdapter`,
67
+ * it will be used directly. Otherwise, it will be retrieved from the plugin's adapter registry
68
+ * and sanitized with the connection options.
69
+ * @param {string} name - Adapter name
54
70
  * @async
71
+ * @returns {Promise<void>}
55
72
  */
56
- async initDriver (name) {
57
- if (name instanceof this.app.baseClass.DoboDriver) this.driver = name
73
+ async initAdapter (name) {
74
+ if (name instanceof this.app.baseClass.DoboAdapter) this.adapter = name
58
75
  else {
59
- this.driver = this.plugin.getDriver(name)
60
- await this.driver.sanitizeConnection(this.options)
76
+ this.adapter = this.plugin.getAdapter(name)
77
+ await this.adapter.sanitizeConnection(this.options)
61
78
  }
62
79
  }
63
80
 
64
81
  /**
65
- * Establish this connection through the driver to the actual database system. Driver developer must
66
- * provide a method named ```connect()``` to connect the underlying database and (optionally) return its client instance.
82
+ * Establish this connection through the adapter to the actual database system. Adapter developer must
83
+ * provide a method named `connect()` to connect the underlying database and (optionally)
84
+ * return its client instance.
67
85
  *
68
- * @param {boolean} [noRebuild] - If ```true```, the database table/collection won't be build automatically
86
+ * @param {boolean} [noRebuild] - If `true`, the database table/collection won't be build automatically
87
+ * @retyrns {Promise<void>}
69
88
  */
70
89
  async connect (noRebuild) {
71
- const client = await this.driver.connect(this, noRebuild)
90
+ const client = await this.adapter.connect(this, noRebuild)
72
91
  if (client) this.client = client
73
92
  this.connected = true
74
93
  }
75
94
 
95
+ /**
96
+ * Dispose this connection
97
+ * @async
98
+ * @returns {Promise<void>}
99
+ */
76
100
  dispose = async () => {
77
101
  await super.dispose()
78
- this.driver = null
102
+ this.adapter = null
79
103
  }
80
104
  }
81
105
 
@@ -1,24 +1,44 @@
1
+ /**
2
+ * Feature factory function.
3
+ *
4
+ * @async
5
+ * @returns {Promise<void>}
6
+ */
7
+
1
8
  async function featureFactory () {
2
9
  const { Tools } = this.app.baseClass
3
10
 
4
11
  /**
5
- * Feature class
12
+ * Feature class definition.
6
13
  *
7
- * ```this.plugin``` should be the one who owned this driver
14
+ * `this.plugin` should be the one who owned this adapter
8
15
  * @class
9
16
  */
10
17
  class DoboFeature extends Tools {
18
+ /**
19
+ * Constructor.
20
+ */
11
21
  constructor (plugin, options = {}) {
12
22
  super(plugin)
13
23
  /**
14
24
  * Feature name
15
- *
16
25
  * @type {string}
17
26
  */
18
27
  this.name = options.name
28
+
29
+ /**
30
+ * Feature handler function.
31
+ * @type {Function}
32
+ */
19
33
  this.handler = options.handler
20
34
  }
21
35
 
36
+ /**
37
+ * Dispose the instance and clean up resources.
38
+ * @async
39
+ * @method
40
+ * @returns {Promise<void>}
41
+ */
22
42
  dispose = async () => {
23
43
  await super.dispose()
24
44
  this.name = null
@@ -1,13 +1,22 @@
1
- import { getFilterAndOptions, execHook, execModelHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook } from './helper.js'
2
2
  const action = 'build'
3
3
 
4
+ /**
5
+ * Build a model's definition based on its properties and rules.
6
+ *
7
+ * @async
8
+ * @memberof DoboModel
9
+ * @method
10
+ * @param {DoboModel.TOptions} opts - The options for building the model
11
+ * @returns {DoboModel.TResultRecord|DoboModel.TRecord}
12
+ */
4
13
  async function build (opts = {}) {
5
14
  opts.dataOnly = opts.dataOnly ?? true
6
15
  const { dataOnly } = opts
7
16
  const { options } = await getFilterAndOptions.call(this, null, opts, action)
8
17
  await execHook.call(this, 'beforeBuildModel', options)
9
18
  await execModelHook.call(this, 'beforeBuildModel', options)
10
- const result = (await this.driver._buildModel(this, options)) ?? {}
19
+ const result = (await this.adapter._buildModel(this, options)) ?? {}
11
20
  await execModelHook.call(this, 'afterBuildModel', result, options)
12
21
  await execHook.call(this, 'afterBuildModel', result, options)
13
22
  return dataOnly ? result.data : result
@@ -1,4 +1,4 @@
1
- import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook } from './helper.js'
2
2
 
3
3
  export const onlyTypes = ['datetime', 'date', 'time', 'timestamp']
4
4
  const action = 'bulkCreateRecord'
@@ -26,7 +26,7 @@ async function bulkCreateRecord (...args) {
26
26
  }
27
27
  }
28
28
  // TODO: bulk don't return anything currently, it should return at least a stat
29
- await this.driver._bulkCreateRecords(this, inputs, options)
29
+ await this.adapter._bulkCreateRecord(this, inputs, options)
30
30
  await execDynHook.call(this, 'afterBulkCreateRecord', inputs, options)
31
31
  await execModelHook.call(this, 'afterBulkCreateRecord', inputs, options)
32
32
  await execHook.call(this, 'afterBulkCreateRecord', inputs, options)
@@ -1,6 +1,16 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './helper.js'
2
2
  const action = 'clearRecord'
3
3
 
4
+ /**
5
+ * Clears all records from the model's underlying data store.
6
+ *
7
+ * If no arguments are provided, it automatically turns into a chainable {@link DoboAction} object.
8
+ * @async
9
+ * @memberof DoboModel
10
+ * @method
11
+ * @param {DoboModel.TOptions} [opts={}] - Options object.
12
+ * @returns {DoboAction|DoboModel.TResultRecord|DoboModel.TRecord}
13
+ */
4
14
  async function clearRecord (...args) {
5
15
  if (args.length === 0) return this.action(action, ...args)
6
16
  const [opts = {}] = args
@@ -10,8 +20,8 @@ async function clearRecord (...args) {
10
20
  await execHook.call(this, 'beforeClearRecord', options)
11
21
  await execModelHook.call(this, 'beforeClearRecord', options)
12
22
  await execDynHook.call(this, 'beforeClearRecord', options)
13
- const result = (await this.driver._clearRecord(this, options)) ?? {}
14
- await execDynHook.call(this, 'beforeClearRecord', result, options)
23
+ const result = (await this.adapter._clearRecord(this, options)) ?? {}
24
+ await execDynHook.call(this, 'afterClearRecord', result, options)
15
25
  await execModelHook.call(this, 'afterClearRecord', result, options)
16
26
  await execHook.call(this, 'afterClearRecord', result, options)
17
27
  return dataOnly ? result.data : result
@@ -1,6 +1,17 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './helper.js'
2
2
  const action = 'countRecord'
3
3
 
4
+ /**
5
+ * Counts the number of records in the model's underlying data store that match the provided filter criteria.
6
+ *
7
+ * If no arguments are provided, it automatically turns into a chainable {@link DoboAction} object.
8
+ * @async
9
+ * @memberof DoboModel
10
+ * @method
11
+ * @param {DoboModel.TFilter} [filter={}] - The filter criteria to apply when counting records.
12
+ * @param {DoboModel.TOptions} [opts={}] - Options object.
13
+ * @returns {DoboAction|DoboModel.TResultRecord|DoboModel.TRecord}
14
+ */
4
15
  async function countRecord (...args) {
5
16
  const { getDefaultValues } = this.app.dobo
6
17
  if (args.length === 0) return this.action(action, ...args)
@@ -12,7 +23,7 @@ async function countRecord (...args) {
12
23
  await execHook.call(this, 'beforeCountRecord', filter, options)
13
24
  await execModelHook.call(this, 'beforeCountRecord', filter, options)
14
25
  await execDynHook.call(this, 'beforeCountRecord', filter, options)
15
- const result = (await this.driver._countRecord(this, filter, options)) ?? {}
26
+ const result = (await this.adapter._countRecord(this, filter, options)) ?? {}
16
27
  if (result.data > hardCap) {
17
28
  result.warnings = result.warnings ?? []
18
29
  result.warnings.push(t('hardCapWarning%s%s', result.data, hardCap))
@@ -1,4 +1,4 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './helper.js'
2
2
  const action = 'createAggregate'
3
3
 
4
4
  async function createAggregate (...args) {
@@ -11,7 +11,7 @@ async function createAggregate (...args) {
11
11
  await execHook.call(this, 'beforeCreateAggregate', filter, params, options)
12
12
  await execModelHook.call(this, 'beforeCreateAggregate', filter, params, options)
13
13
  await execDynHook.call(this, 'beforeCreateAggregate', filter, params, options)
14
- const result = (await this.driver._createAggregate(this, filter, params, options)) ?? {}
14
+ const result = (await this.adapter._createAggregate(this, filter, params, options)) ?? {}
15
15
  const { warnings } = getDefaultValues(options)
16
16
  if (!warnings) delete result.warnings
17
17
  await execDynHook.call(this, 'afterCreateAggregate', filter, params, result, options)
@@ -1,4 +1,4 @@
1
- import { mergeAttachmentInfo, getAttachmentPath } from './_util.js'
1
+ import { mergeAttachmentInfo, getAttachmentPath } from './helper.js'
2
2
  const action = 'createAttachment'
3
3
 
4
4
  async function createAttachment (...args) {
@@ -1,4 +1,4 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook } from './helper.js'
2
2
  const action = 'createHistogram'
3
3
 
4
4
  async function createHistogram (...args) {
@@ -11,7 +11,7 @@ async function createHistogram (...args) {
11
11
  await execHook.call(this, 'beforeCreateHistogram', filter, params, options)
12
12
  await execModelHook.call(this, 'beforeCreateHistogram', filter, params, options)
13
13
  await execDynHook.call(this, 'beforeCreateHistogram', filter, params, options)
14
- const result = (await this.driver._createHistogram(this, filter, params, options)) ?? {}
14
+ const result = (await this.adapter._createHistogram(this, filter, params, options)) ?? {}
15
15
  const { warnings } = getDefaultValues(options)
16
16
  if (!warnings) delete result.warnings
17
17
  await execDynHook.call(this, 'afterCreateHistogram', filter, params, result, options)
@@ -1,8 +1,21 @@
1
- import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook, getRefs, handleReq } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook, getRefs, handleReq } from './helper.js'
2
2
 
3
3
  export const onlyTypes = ['datetime', 'date', 'time', 'timestamp', 'array', 'object']
4
4
  const action = 'createRecord'
5
5
 
6
+ /**
7
+ * Creates a new record in the model's underlying data store with the provided data.
8
+ *
9
+ * If no arguments are provided, it automatically turns into a chainable {@link DoboAction} object.
10
+ * @async
11
+ * @memberof DoboModel
12
+ * @method
13
+ * @param {object} body - The data for the new record to be created
14
+ * @param {DoboModel.TOptions} [opts] - Options object
15
+ * @returns {DoboAction|DoboModel.TResultCreateRecord|DoboModel.TRecord}
16
+ * @see {@link module:Hook.beforeCreateRecord}
17
+ * @see {@link module:Hook.afterCreateRecord}
18
+ */
6
19
  async function createRecord (...args) {
7
20
  if (args.length === 0) return this.action(action, ...args)
8
21
  const [body = {}, opts = {}] = args
@@ -19,7 +32,7 @@ async function createRecord (...args) {
19
32
  await execModelHook.call(this, 'beforeCreateRecord', input, options)
20
33
  await execDynHook.call(this, 'beforeCreateRecord', input, options)
21
34
  if (!noValidation) await execValidation.call(this, input, options)
22
- let result = options.record ?? (await this.driver._createRecord(this, input, options)) ?? {}
35
+ let result = options.record ?? (await this.adapter._createRecord(this, input, options)) ?? {}
23
36
  if (noResult) return
24
37
  await handleReq.call(this, result.data.id, 'created', options)
25
38
  result = result ?? {}
@@ -1,13 +1,23 @@
1
- import { getFilterAndOptions, execHook, execModelHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook } from './helper.js'
2
2
  const action = 'drop'
3
3
 
4
+ /**
5
+ * Drops the model from the underlying data store.
6
+ * @async
7
+ * @memberof DoboModel
8
+ * @method
9
+ * @param {DoboModel.TOptions} [opts] - Options object.
10
+ * @returns {DoboAction|DoboModel.TResult|boolean}
11
+ * @see {@link module:Hook.beforeDropModel}
12
+ * @see {@link module:Hook.afterDropModel}
13
+ */
4
14
  async function drop (opts = {}) {
5
15
  opts.dataOnly = opts.dataOnly ?? true
6
16
  const { dataOnly } = opts
7
17
  const { options } = await getFilterAndOptions.call(this, null, opts, action)
8
18
  await execHook.call(this, 'beforeDropModel', options)
9
19
  await execModelHook.call(this, 'beforeDropModel', options)
10
- const result = (await this.driver._dropModel(this, options)) ?? {}
20
+ const result = (await this.adapter._dropModel(this, options)) ?? {}
11
21
  await execModelHook.call(this, 'afterDropModel', result, options)
12
22
  await execHook.call(this, 'afterModelDrop', result, options)
13
23
  return dataOnly ? result.data : result
@@ -1,11 +1,15 @@
1
- import { getFilterAndOptions, execHook, execModelHook } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook } from './helper.js'
2
2
  const action = 'modelExists'
3
3
 
4
4
  /**
5
- * Method to check if the underlaying table/collection exists already
6
- *
7
- * @param {Object} [options]
8
- * @returns {Object}
5
+ * Checks if the model exists in the underlying data store.
6
+ * @async
7
+ * @memberof DoboModel
8
+ * @method
9
+ * @param {DoboModel.TOptions} [opts] - Options object.
10
+ * @returns {DoboAction|DoboModel.TResult|boolean}
11
+ * @see {@link module:Hook.beforeModelExists}
12
+ * @see {@link module:Hook.afterModelExists}
9
13
  */
10
14
  async function isExists (opts = {}) {
11
15
  opts.dataOnly = opts.dataOnly ?? true
@@ -13,7 +17,7 @@ async function isExists (opts = {}) {
13
17
  const { options } = await getFilterAndOptions.call(this, null, opts, action)
14
18
  await execHook.call(this, 'beforeModelExists', options)
15
19
  await execModelHook.call(this, 'beforeModelExists', options)
16
- const result = (await this.driver._modelExists(this, options)) ?? {}
20
+ const result = (await this.adapter._modelExists(this, options)) ?? {}
17
21
  await execModelHook.call(this, 'afterModelExists', result, options)
18
22
  await execHook.call(this, 'afterModelExists', result, options)
19
23
  return dataOnly ? result.data : result
@@ -1,4 +1,4 @@
1
- import { getRefs, execHook, execModelHook, execDynHook, getFilterAndOptions, cloneOptions, sanitizeQuery } from './_util.js'
1
+ import { getRefs, execHook, execModelHook, execDynHook, getFilterAndOptions, cloneOptions, sanitizeQuery } from './helper.js'
2
2
  const action = 'findAllRecord'
3
3
 
4
4
  async function native (...args) {
@@ -28,7 +28,7 @@ async function native (...args) {
28
28
  return dataOnly ? resp.data : resp
29
29
  }
30
30
  }
31
- let result = options.record ?? (await this.driver._findAllRecord(this, filter, options)) ?? {}
31
+ let result = options.record ?? (await this.adapter._findAllRecord(this, filter, options)) ?? {}
32
32
  result.limit = filter.limit
33
33
  result.filter = pick(filter, ['query', 'match', 'sort'])
34
34
  result.warnings = result.warnings ?? []
@@ -89,10 +89,21 @@ async function loop (...args) {
89
89
  return dataOnly ? data : result
90
90
  }
91
91
 
92
+ /**
93
+ * Finds all records from the model's underlying data store based on the provided filter.
94
+ * @async
95
+ * @memberof DoboModel
96
+ * @method
97
+ * @param {DoboModel.TFilter} filter - The filter parameters for finding the records.
98
+ * @param {DoboModel.TOptions} [opts] - Options object.
99
+ * @returns {DoboAction|DoboModel.TResultFindRecord|Array<DoboModel.TRecord>}
100
+ * @see {@link module:Hook.beforeFindAllRecord}
101
+ * @see {@link module:Hook.afterFindAllRecord}
102
+ */
92
103
  async function findAllRecord (...args) {
93
104
  // can't use action here, because people tends to use is without arguments
94
105
  // if (args.length === 0) return this.action(action, ...args)
95
- if (this.driver.findAllRecord) {
106
+ if (this.adapter.findAllRecord) {
96
107
  return await native.call(this, ...args)
97
108
  }
98
109
  return await loop.call(this, ...args)
@@ -1,4 +1,4 @@
1
- import { mergeAttachmentInfo } from './_util.js'
1
+ import { mergeAttachmentInfo } from './helper.js'
2
2
  const action = 'findAttachment'
3
3
 
4
4
  async function findAttachment (...args) {
@@ -1,7 +1,19 @@
1
- import { cloneOptions } from './_util.js'
1
+ import { cloneOptions } from './helper.js'
2
2
 
3
3
  const action = 'findOneRecord'
4
4
 
5
+ /**
6
+ * Finds a single record from the model's underlying data store based on the provided filter.
7
+ *
8
+ * If no arguments are provided, it automatically turns into a chainable {@link DoboAction} object.
9
+ * @async
10
+ * @memberof DoboModel
11
+ * @method
12
+ * @param {DoboModel.TFilter} filter - The filter parameters for finding the record.
13
+ * @param {DoboModel.TOptions} [opts] - Options object.
14
+ * @returns {DoboAction|DoboModel.TResultFindRecord|Array<DoboModel.TRecord>}
15
+ * @see {@link module:Hook.beforeFindRecord}
16
+ */
5
17
  async function findOneRecord (...args) {
6
18
  if (args.length === 0) return this.action(action, ...args)
7
19
  const { getDefaultValues } = this.app.dobo
@@ -1,68 +1,32 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook, getRefs, sanitizeQuery } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook, getRefs, sanitizeQuery } from './helper.js'
2
2
  const action = 'findRecord'
3
3
 
4
4
  /**
5
- * @typedef {Object} TRecordFilter
5
+ * @typedef TFilter
6
+ * @type {Object}
7
+ * @memberof DoboModel
6
8
  * @see Dobo#recordFind
7
9
  * @see Dobo#recordFindOne
8
10
  * @see Dobo#recordFindAll
9
11
  * @property {(string|Object)} [query={}] - Query definition. See {@tutorial query-language} for more
10
- * @property {number} limit - Max number of records per page
11
- * @property {number} page - Which page is the returned records currently at
12
+ * @property {number} limit - Maximum number of records to return
13
+ * @property {number} page - Which page to return
12
14
  * @property {number} skip - Records to skip
13
- * @property {TRecordSort} sort - Sort order info
15
+ * @property {DoboModel.TSort} sort - Sort order info
14
16
  */
15
17
 
16
18
  /**
17
- * @typedef {Object} TRecordFindResult
18
- * @see Dobo#recordFind
19
- * @see Dobo#recordFindAll
20
- * @see Dobo#recordGet
21
- * @property {Array.<Object>} data - Array of returned records
22
- * @property {boolean} success - Whether operation is successfull or failed
23
- * @property {number} page - Which page is the returned records currently at
24
- * @property {number} limit - Max number of records per page
25
- * @property {number} count - Total number of records returned
26
- * @property {number} pages - Total number of pages returned
27
- */
28
-
29
- /**
30
- * @typedef {Object} TRecordFindOptions
31
- * @see Dobo#recordFind
32
- * @see Dobo#recordFindOne
33
- * @see Dobo#recordFindAll
34
- * @property {boolean} [dataOnly=true] - If ```true``` (default) returns array of records. Otherwise {@link TFindRecordResult}
35
- * @property {boolean} [count=false] - If ```true``` and ```dataOnly``` is also ```true```, the total number of records found will be returned
36
- * @property {boolean} [noCache=true] - If ```true``` (default), result set won't be cached. This will overwrite model's ```cacheable``` property. Only applicable if {@link https://github.com/ardhi/bajo-cache|bajo-cache} is loaded
37
- * @property {boolean} [noHook=false] - If ```true```, no model's hook will be executed
38
- * @property {boolean} [noFeatureHook=false] - If ```true```, no model's feature hook will be executed
39
- * @property {boolean} [fields=[]] - If not empty, return only these fields EXCLUDING hidden fields
40
- * @property {boolean} [hidden=[]] - Additional fields to hide, in addition the one set in model's model
41
- * @property {boolean} [forceNoHidden=false] - If ```true```, hidden fields will be ignored and ALL fields will be returned
42
- */
43
-
44
- /**
45
- * Find records by model's name and given filter
19
+ * Finds records in the model's underlying data store that match the provided filter criteria.
46
20
  *
47
- * Example: find records from model **CdbCountry** where its id is 'ID' or 'MY',
48
- * sorted by ```name``` in ascending order and return only its ```id```, ```name``` and ```iso3```
49
- * ```javascript
50
- * const { recordFind } = this.app.dobo
51
- * const query = { id: { $in: ['ID', 'MY'] } }
52
- * const sort = { name: 1 }
53
- * const fields = ['id', 'name', 'iso3']
54
- * const result = await recordFind('CdbCountry', { query, sort }, { fields })
55
- * ```
56
- *
57
- * @method
58
- * @memberof Dobo
21
+ * If no arguments are provided, it automatically turns into a chainable {@link DoboAction} object.
59
22
  * @async
60
- * @instance
61
- * @name recordFind
62
- * @param {string} name - Model's name
63
- * @param {Object} [filter={}] - Filter object
64
- * @param {TRecordFindOptions} [options={}]
65
- * @returns {(TRecordFindResult|Array.<Object>)} Return ```array``` of records if ```options.dataOnly``` is set. {@link TRecordFindResult} otherwise
23
+ * @memberof DoboModel
24
+ * @method
25
+ * @param {DoboModel.TFilter} [filter={}] - The filter criteria to apply when finding records.
26
+ * @param {DoboModel.TOptions} [opts={}] - Options object.
27
+ * @returns {DoboAction|DoboModel.TResultFindRecord|Array.<DoboModel.TRecord>}
28
+ * @see {@link module:Hook.beforeFindRecord}
29
+ * @see {@link module:Hook.afterFindRecord}
66
30
  */
67
31
  async function findRecord (...args) {
68
32
  if (args.length === 0) return this.action(action, ...args)
@@ -89,7 +53,7 @@ async function findRecord (...args) {
89
53
  return dataOnly ? resp.data : resp
90
54
  }
91
55
  }
92
- let result = options.record ?? (await this.driver._findRecord(this, filter, options)) ?? {}
56
+ let result = options.record ?? (await this.adapter._findRecord(this, filter, options)) ?? {}
93
57
  result.page = filter.page
94
58
  result.limit = filter.limit
95
59
  result.filter = pick(filter, ['query', 'search', 'sort'])
@@ -1,46 +1,18 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook, getRefs } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook, getRefs } from './helper.js'
2
2
  const action = 'getRecord'
3
3
 
4
4
  /**
5
- * @typedef {Object} TRecordGetResult
6
- * @see Dobo#recordGet
7
- * @see Dobo#recordFindOne
8
- * @property {Object} data - Returned record
9
- * @property {boolean} success - Whether operation is successfull or failed
10
- */
11
-
12
- /**
13
- * @typedef {Object} TRecordgetFilterAndOptions
14
- * @see Dobo#recordGet
15
- * @property {boolean} [dataOnly=true] - If ```true``` (default) returns array of records. Otherwise {@link TFindRecordResult}
16
- * @property {boolean} [count=false] - If ```true``` and ```dataOnly``` is also ```true```, the total number of records found will be returned
17
- * @property {boolean} [noCache=true] - If ```true``` (default), result set won't be cached. This will overwrite model's ```cacheable``` property. Only applicable if {@link https://github.com/ardhi/bajo-cache|bajo-cache} is loaded
18
- * @property {boolean} [noHook=false] - If ```true```, no model's hook will be executed
19
- * @property {boolean} [noFeatureHook=false] - If ```true```, no model's feature hook will be executed
20
- * @property {boolean} [fields=[]] - If not empty, return only these fields EXCLUDING hidden fields
21
- * @property {boolean} [hidden=[]] - Additional fields to hide, in addition the one set in model's model
22
- * @property {boolean} [forceNoHidden=false] - If ```true```, hidden fields will be ignored and ALL fields will be returned
23
- */
24
-
25
- /**
26
- * Get record by model's name and record ID
27
- *
28
- * Example:
29
- * ```javascript
30
- * const { recordGet } = this.app.dobo
31
- * const fields = ['id', 'name', 'iso3']
32
- * const result = await recordGet('CdbCountry', 'ID', { fields })
33
- * ```
5
+ * Gets a record from the model's underlying data store based on the provided ID.
34
6
  *
35
- * @method
36
- * @memberof Dobo
7
+ * If no arguments are provided, it automatically turns into a chainable {@link DoboAction} object.
37
8
  * @async
38
- * @instance
39
- * @name recordGet
40
- * @param {string} name - Model's name
41
- * @param {(string|number)} - Record's ID
42
- * @param {TRecordgetFilterAndOptions} [options={}]
43
- * @returns {(TRecordGetResult|Object)} Return record's ```object``` if ```options.dataOnly``` is set. {@link TRecordGetResult} otherwise
9
+ * @memberof DoboModel
10
+ * @method
11
+ * @param {string|number} id - The ID of the record to be retrieved.
12
+ * @param {DoboModel.TOptions} [opts] - Options object.
13
+ * @returns {DoboAction|DoboModel.TResultGetRecord|DoboModel.TRecord}
14
+ * @see {@link module:Hook.beforeGetRecord}
15
+ * @see {@link module:Hook.afterGetRecord}
44
16
  */
45
17
  async function getRecord (...args) {
46
18
  if (args.length === 0) return this.action(action, ...args)
@@ -64,7 +36,7 @@ async function getRecord (...args) {
64
36
  return dataOnly ? resp.data : resp
65
37
  }
66
38
  }
67
- const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
39
+ const result = options.record ?? (await this.adapter._getRecord(this, id, options)) ?? {}
68
40
  const { warnings } = getDefaultValues(options)
69
41
  if (!warnings) delete result.warnings
70
42
  if (isEmpty(result.data) && !options.throwNotFound) return dataOnly ? undefined : { data: undefined }