dobo 2.0.1 → 2.2.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 (194) hide show
  1. package/.github/FUNDING.yml +0 -0
  2. package/.github/workflows/repo-lockdown.yml +0 -0
  3. package/.jsdoc.conf.json +0 -0
  4. package/LICENSE +0 -0
  5. package/README.md +2 -2
  6. package/docs/Dobo.html +0 -0
  7. package/docs/data/search.json +0 -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 +0 -0
  12. package/docs/index.html +0 -0
  13. package/docs/index.js.html +0 -0
  14. package/docs/lib_collect-connections.js.html +0 -0
  15. package/docs/lib_collect-drivers.js.html +0 -0
  16. package/docs/lib_collect-features.js.html +0 -0
  17. package/docs/lib_collect-schemas.js.html +0 -0
  18. package/docs/lib_index.js.html +0 -0
  19. package/docs/method_model_create.js.html +0 -0
  20. package/docs/method_model_drop.js.html +0 -0
  21. package/docs/method_model_exists.js.html +0 -0
  22. package/docs/method_record_count.js.html +0 -0
  23. package/docs/method_record_create.js.html +0 -0
  24. package/docs/method_record_find-all.js.html +0 -0
  25. package/docs/method_record_find-one.js.html +0 -0
  26. package/docs/method_record_find.js.html +0 -0
  27. package/docs/method_record_get.js.html +0 -0
  28. package/docs/method_record_remove.js.html +0 -0
  29. package/docs/method_record_update.js.html +0 -0
  30. package/docs/method_record_upsert.js.html +0 -0
  31. package/docs/method_sanitize_body.js.html +0 -0
  32. package/docs/method_sanitize_date.js.html +0 -0
  33. package/docs/method_sanitize_id.js.html +0 -0
  34. package/docs/method_validate.js.html +0 -0
  35. package/docs/module-Lib.html +0 -0
  36. package/docs/scripts/core.js +476 -477
  37. package/docs/scripts/core.min.js +0 -0
  38. package/docs/scripts/resize.js +36 -36
  39. package/docs/scripts/search.js +105 -105
  40. package/docs/scripts/search.min.js +0 -0
  41. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
  42. package/docs/scripts/third-party/fuse.js +1 -1
  43. package/docs/scripts/third-party/hljs-line-num-original.js +282 -285
  44. package/docs/scripts/third-party/hljs-line-num.js +1 -1
  45. package/docs/scripts/third-party/hljs-original.js +1195 -1202
  46. package/docs/scripts/third-party/hljs.js +1 -1
  47. package/docs/scripts/third-party/popper.js +1 -1
  48. package/docs/scripts/third-party/tippy.js +1 -1
  49. package/docs/scripts/third-party/tocbot.js +508 -509
  50. package/docs/scripts/third-party/tocbot.min.js +0 -0
  51. package/docs/static/bitcoin.jpeg +0 -0
  52. package/docs/static/home.md +0 -0
  53. package/docs/static/logo-ecosystem.png +0 -0
  54. package/docs/static/logo.png +0 -0
  55. package/docs/styles/clean-jsdoc-theme-base.css +0 -0
  56. package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
  57. package/docs/styles/clean-jsdoc-theme-light.css +0 -0
  58. package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  59. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  60. package/docs/styles/clean-jsdoc-theme.min.css +0 -0
  61. package/extend/bajo/intl/en-US.json +66 -28
  62. package/extend/bajo/intl/id.json +55 -27
  63. package/extend/bajoCli/applet/clear-record.js +22 -0
  64. package/extend/bajoCli/applet/connection.js +0 -0
  65. package/extend/bajoCli/applet/count-record.js +27 -0
  66. package/extend/bajoCli/applet/create-aggregate.js +33 -0
  67. package/extend/bajoCli/applet/create-histogram.js +33 -0
  68. package/extend/bajoCli/applet/create-record.js +39 -0
  69. package/extend/bajoCli/applet/find-record.js +27 -0
  70. package/extend/bajoCli/applet/get-record.js +27 -0
  71. package/extend/bajoCli/applet/lib/post-process.js +10 -17
  72. package/extend/bajoCli/applet/model.js +22 -0
  73. package/extend/bajoCli/applet/rebuild-model.js +91 -0
  74. package/extend/bajoCli/applet/remove-record.js +27 -0
  75. package/extend/bajoCli/applet/update-record.js +44 -0
  76. package/extend/bajoCli/applet.js +0 -0
  77. package/extend/dobo/driver/memory.js +170 -0
  78. package/extend/dobo/feature/created-at.js +9 -7
  79. package/extend/dobo/feature/dt.js +0 -0
  80. package/extend/dobo/feature/immutable.js +30 -0
  81. package/extend/dobo/feature/int-id.js +0 -0
  82. package/extend/dobo/feature/removed-at.js +32 -54
  83. package/extend/dobo/feature/updated-at.js +14 -12
  84. package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +2 -6
  85. package/extend/waibuStatic/virtual.json +0 -0
  86. package/index.js +291 -366
  87. package/lib/collect-connections.js +49 -21
  88. package/lib/collect-drivers.js +19 -33
  89. package/lib/collect-features.js +24 -17
  90. package/lib/collect-models.js +319 -0
  91. package/lib/factory/action.js +161 -0
  92. package/lib/factory/connection.js +62 -0
  93. package/lib/factory/driver.js +358 -0
  94. package/lib/factory/feature.js +33 -0
  95. package/lib/factory/model/_util.js +402 -0
  96. package/lib/factory/model/build.js +15 -0
  97. package/lib/factory/model/clear-record.js +17 -0
  98. package/lib/factory/model/count-record.js +17 -0
  99. package/lib/factory/model/create-aggregate.js +17 -0
  100. package/lib/factory/model/create-attachment.js +29 -0
  101. package/lib/factory/model/create-histogram.js +17 -0
  102. package/lib/factory/model/create-record.js +35 -0
  103. package/lib/factory/model/drop.js +15 -0
  104. package/lib/factory/model/exists.js +21 -0
  105. package/lib/factory/model/find-all-record.js +71 -0
  106. package/lib/factory/model/find-attachment.js +29 -0
  107. package/lib/factory/model/find-one-record.js +19 -0
  108. package/{method/record/find.js → lib/factory/model/find-record.js} +103 -115
  109. package/lib/factory/model/get-attachment.js +15 -0
  110. package/lib/factory/model/get-record.js +79 -0
  111. package/lib/factory/model/list-attachment.js +37 -0
  112. package/lib/{add-fixtures.js → factory/model/load-fixtures.js} +69 -67
  113. package/lib/factory/model/remove-attachment.js +15 -0
  114. package/lib/factory/model/remove-record.js +59 -0
  115. package/lib/factory/model/sanitize-body.js +62 -0
  116. package/lib/factory/model/sanitize-id.js +7 -0
  117. package/lib/factory/model/sanitize-record.js +26 -0
  118. package/lib/factory/model/update-attachment.js +9 -0
  119. package/lib/factory/model/update-record.js +81 -0
  120. package/lib/factory/model/upsert-record.js +95 -0
  121. package/{method → lib/factory/model}/validate.js +38 -52
  122. package/lib/factory/model.js +150 -0
  123. package/lib/index.js +0 -0
  124. package/package.json +8 -4
  125. package/wiki/APPLETS.md +0 -0
  126. package/wiki/CHANGES.md +46 -0
  127. package/wiki/CONFIG.md +0 -0
  128. package/wiki/CONTRIBUTING.md +0 -0
  129. package/wiki/DEV-GUIDE.md +0 -0
  130. package/wiki/ECOSYSTEM.md +0 -0
  131. package/wiki/GETTING-STARTED.md +10 -10
  132. package/wiki/QUERY-LANGUAGE.md +0 -0
  133. package/wiki/USER-GUIDE.md +0 -0
  134. package/extend/bajoCli/applet/model-clear.js +0 -11
  135. package/extend/bajoCli/applet/model-rebuild.js +0 -101
  136. package/extend/bajoCli/applet/record-create.js +0 -43
  137. package/extend/bajoCli/applet/record-find.js +0 -28
  138. package/extend/bajoCli/applet/record-get.js +0 -24
  139. package/extend/bajoCli/applet/record-remove.js +0 -24
  140. package/extend/bajoCli/applet/record-update.js +0 -47
  141. package/extend/bajoCli/applet/schema.js +0 -22
  142. package/extend/bajoCli/applet/stat-count.js +0 -24
  143. package/lib/build-bulk-action.js +0 -12
  144. package/lib/check-unique.js +0 -39
  145. package/lib/collect-schemas.js +0 -91
  146. package/lib/exec-feature-hook.js +0 -13
  147. package/lib/exec-validation.js +0 -21
  148. package/lib/generic-prop-sanitizer.js +0 -32
  149. package/lib/handle-attachment-upload.js +0 -16
  150. package/lib/mem-db/conn-sanitizer.js +0 -8
  151. package/lib/mem-db/instantiate.js +0 -41
  152. package/lib/mem-db/method/model/clear.js +0 -6
  153. package/lib/mem-db/method/model/create.js +0 -5
  154. package/lib/mem-db/method/model/drop.js +0 -5
  155. package/lib/mem-db/method/model/exists.js +0 -5
  156. package/lib/mem-db/method/record/create.js +0 -12
  157. package/lib/mem-db/method/record/find.js +0 -20
  158. package/lib/mem-db/method/record/get.js +0 -9
  159. package/lib/mem-db/method/record/remove.js +0 -13
  160. package/lib/mem-db/method/record/update.js +0 -15
  161. package/lib/mem-db/method/stat/count.js +0 -11
  162. package/lib/mem-db/start.js +0 -25
  163. package/lib/merge-attachment-info.js +0 -16
  164. package/lib/multi-rel-rows.js +0 -42
  165. package/lib/resolve-method.js +0 -16
  166. package/lib/sanitize-schema.js +0 -198
  167. package/lib/single-rel-rows.js +0 -38
  168. package/method/attachment/copy-uploaded.js +0 -34
  169. package/method/attachment/create.js +0 -29
  170. package/method/attachment/find.js +0 -27
  171. package/method/attachment/get-path.js +0 -12
  172. package/method/attachment/get.js +0 -12
  173. package/method/attachment/pre-check.js +0 -9
  174. package/method/attachment/remove.js +0 -11
  175. package/method/attachment/update.js +0 -7
  176. package/method/bulk/create.js +0 -46
  177. package/method/model/clear.js +0 -22
  178. package/method/model/create.js +0 -32
  179. package/method/model/drop.js +0 -31
  180. package/method/model/exists.js +0 -37
  181. package/method/record/clear.js +0 -24
  182. package/method/record/count.js +0 -66
  183. package/method/record/create.js +0 -111
  184. package/method/record/find-all.js +0 -41
  185. package/method/record/find-one.js +0 -70
  186. package/method/record/get.js +0 -89
  187. package/method/record/remove.js +0 -72
  188. package/method/record/update.js +0 -104
  189. package/method/record/upsert.js +0 -51
  190. package/method/sanitize/body.js +0 -85
  191. package/method/sanitize/date.js +0 -27
  192. package/method/sanitize/id.js +0 -17
  193. package/method/stat/aggregate.js +0 -23
  194. package/method/stat/histogram.js +0 -26
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -2,15 +2,15 @@
2
2
  "isConnected%s%s": "%s' is connected",
3
3
  "errorOn%s%s": "Error on '%s': %s",
4
4
  "isDestroyed%s%s": "'%s' is destroyed",
5
- "loadedSchemas%s": "Loaded schemas: %s",
6
- "loadSchema%s%s%d": "Load schema: %s (%d)",
5
+ "loadedModels%s": "Loaded models: %s",
6
+ "loadModek%s%s%d": "Load model: %s (%d)",
7
7
  "loadedConns%s%s": "Loaded connections: %s",
8
8
  "unsupportedPropTypeIn%s%s": "Unsupported property type '%s' in '%s'",
9
- "noSchemaFound": "No schema found!",
10
- "enterSchemaName": "Enter schema name, separated by space:",
11
- "noSchemaMatched": "No schema matched",
12
- "schema%d": "Schema (%d)",
13
- "schemasWillBeRebuiltContinue": "The above mentioned schema(s) will be rebuilt as model. Continue?",
9
+ "noModelFound": "No model found!",
10
+ "enterModelName": "Enter model name, separated by space:",
11
+ "noModelMatched": "No model matched",
12
+ "model%d": "Model (%d)",
13
+ "modelsWillBeRebuiltContinue": "The above mentioned model(s) will be rebuilt. Continue?",
14
14
  "rebuilding%s": "Rebuilding '%s'...",
15
15
  "noDbConn%s%s": "No DB connection '%s' for '%s'. Aborted!",
16
16
  "errorDroppingModel%s%s": "Error dropping model '%s': %s",
@@ -22,10 +22,10 @@
22
22
  "memoryDbSkipped%s%s": "DB '%s' for '%s' is a memory DB, skipped",
23
23
  "modelBuiltOnthefly%s%s%s": "Model '%s@%s' successfully built on the fly",
24
24
  "unableToBuildModel%s%s%s": "Unable to re-build model '%s' in '%s': %s",
25
- "unknownSchema%s": "Unknown schema '%s'",
25
+ "unknownModel%s": "Unknown model '%s'",
26
26
  "payloadMustBeJson": "Payload must be a valid JSON",
27
- "selectSchema": "Please select a schema:",
28
- "enterJsonPayload": "Enter JSON payload:",
27
+ "selectModel": "Please select a model:",
28
+ "enterPayload": "Enter payload:",
29
29
  "payloadRequired": "Payload is required",
30
30
  "invalidPayloadSyntax": "Invalid payload syntax",
31
31
  "creatingRecord": "Creating record",
@@ -33,29 +33,29 @@
33
33
  "idIsRequired": "ID is required",
34
34
  "gettingRecord": "Getting record",
35
35
  "removingRecord": "Deleting record",
36
- "cantFindSchema%s": "Can't find schema named %s",
37
- "cantFind%s%s": "Can't find %s named %s",
38
- "recordNotFound%s%s": "Record '%s@%s' not found",
39
- "invalidSchema%s": "Invalid schema '%s'",
40
- "noPropsFoundOnSchema%s": "Schema '%s' doesn't have any property at all",
36
+ "cantFind%s%s": "Can't find %s|toLower named '%s'",
37
+ "recordNotFound%s%s": "Record with ID: '%s' & model: '%s' is nowhere to be found",
38
+ "invalidModel%s": "Invalid model '%s'",
39
+ "noPropsFoundOnModel%s": "Model '%s' doesn't have any property at all",
41
40
  "fieldIdReserved%s": "Field 'id@%s' is a reserved column and should not added manually",
42
41
  "missingPropType%s%s": "Property type for '%s@%s' is missing",
43
42
  "unsupportedPropType%s%s%s": "Unsupported property type '%s@%s' in '%s'",
44
- "unknownConn%s%s": "Unknown connection '%s@%s'",
43
+ "unknownConn%s%s": "Unknown connection '%s' for '%s'",
45
44
  "fieldIsRequired%s%s": "Column '%s@%s' is required",
46
45
  "keyIsRequired%s": "Key '%s' is required",
47
- "enterQueryIfAny": "Please enter your query (if any):",
46
+ "enterFilterIfAny": "Please enter your filter (if any):",
48
47
  "findingRecords": "Finding records",
49
- "recordExists%s%s": "Record '%s@%s' exists already",
50
- "fieldGroupAggregateMissing": "Field to group aggregate is missing",
51
- "fieldCalcAggregateMissing": "Field to calculate aggregate is missing",
52
- "baseFieldForHistogramMissing": "Base field for histogram must be provided",
53
- "unknownBaseFieldForHistogram%s": "Unknown base field for histogram '%s'",
48
+ "recordExists%s%s": "Record with ID: '%s' & model: '%s' exists already",
49
+ "fieldGroupMissing": "Field to group aggregate/histogram is missing",
50
+ "fieldCalcMissing": "Field to calculate aggregate is missing",
51
+ "aggregateTypesMissing": "One or more aggregate type must be provided",
54
52
  "fieldTypeMustBeDatetime%s%s": "Field type '%s@%s' must be a datetime field",
55
53
  "groupFieldToAggregateMissing": "Group field to aggregate is missing",
56
54
  "unknownGroupField%s%s": "Unknown group field '%s@%s'",
57
55
  "grupFieldMustBeNumber": "Group field must be of type integer, smallint or float",
58
56
  "unsupportedAggregateType%s": "Unsupported aggregate type: '%s'",
57
+ "unsupportedHistogramType%s": "Unsupported histogram type: '%s'",
58
+ "histogramTypeMissing": "Histogram type is missing",
59
59
  "keyIsRequired%s%s": "'%s@%s' key is required",
60
60
  "fulltextNeedIntegerId%s%s": "Full text index need integer type primary id in '%s@%s'",
61
61
  "unsupportedAggregate%s": "Unsupported aggregate '%s'",
@@ -79,7 +79,6 @@
79
79
  "recordUpdated": "Record successfully updated",
80
80
  "attachmentUploaded": "Attachment successfully uploaded",
81
81
  "attachmentRemoved": "Attachment successfully removed",
82
- "unknownModelSchema%s": "Unknown model/schema '%s'",
83
82
  "sortOnUnindexedField%s%s": "Sort on unindexed field: '%s@%s'",
84
83
  "modelNotExists%s": "Model '%s' doesn't exist yet. Please do model rebuild first",
85
84
  "invalidDate": "Invalid date",
@@ -97,12 +96,11 @@
97
96
  "proxiedConnBound%s": "'%s' is bound to a proxied connection, skipped!'",
98
97
  "addingMemoryPersistenceIgnored": "'%s' is a memory persistence model. Adding records from fixture is ignored!",
99
98
  "onlyOneConnType%s": "There could only be one connection type '%s'",
100
- "mustValidDbType": "Connection must have a valid DB type",
101
99
  "unsupportedDbType%s": "Unsupported DB type '%s'",
102
100
  "driverMustProvideDbType": "A DB driver must provide at least one database type",
103
101
  "driverMustHaveName": "A DB driver must have a driver name",
104
102
  "dbTypeAlreadySupportedByDriver%s%s": "Database type '%s' already supported by driver '%s'",
105
- "featureNotAsync%s": "Feature '%s' should be an async function",
103
+ "invalidFeatureHandler%s%s": "Invalid handler for feature '%s:%s'",
106
104
  "unsupportedIndexType%s%s%s%s": "Unsupported index type %s for '%s@%s'. Allowed values: %s",
107
105
  "unknownFeature%s%s": "'Unknown feature '%s@%s'",
108
106
  "onlyAcceptFields%s%s": "Only accept array of field names or single string of field name '%s@%s'",
@@ -112,10 +110,11 @@
112
110
  "sureContinue": "Are you sure to continue?",
113
111
  "loadingDbFeature": "Loading DB feature",
114
112
  "totalLoadedFeatures%d": "Total loaded features: %d",
115
- "loadingDbSchemas": "Loading DB schemas",
113
+ "loadingDbModels": "Loading DB models",
116
114
  "addingFixtureToMemDb": "Adding fixture for memory database",
117
115
  "recordsAdded%s%d%d": "%s: %d of %d records added",
118
- "driverInstantiated%s%s": "- Driver '%s:%s' instantiated",
116
+ "dbInit": "Initialize database",
117
+ "dbInit%s%s%s": "- %s:%s on connection: '%s'",
119
118
  "cantContinueAddFixture": "Can't continue with fixture adding because one or more models failed to rebuilt",
120
119
  "addingFixture%s": "Adding fixture '%s'...",
121
120
  "fixtureAdded%s%s%s": "Fixture on '%s': added %s, rejected: %s",
@@ -124,6 +123,28 @@
124
123
  "db": "DB",
125
124
  "invalidQuery": "Invalid Query",
126
125
  "noResultFound": "No result found",
126
+ "invalidDriverClassFactory%s%s": "Invalid driver class factory '%s:%s'",
127
+ "invalidDriverClass%s%s": "Invalid driver class '%s:%s'",
128
+ "multipleConnection%s": "Model '%s' is attached to more than one connection",
129
+ "invalidFeature%s%s": "Invalid feature '%s@%s'",
130
+ "invalidModelExtender%s%s": "Invalid model extender '%s' on '%s'",
131
+ "unknownDbDriver%s": "Unknown database driver '%s'",
132
+ "unknownPropType%s%s": "Unknown property type '%s' on '%s'",
133
+ "unknownIndexType%s%s": "Unknown index type '%s' on '%s'",
134
+ "unknownPropNameOnIndex%s%s": "Unknown property name '%s' on index for '%s'",
135
+ "unknownModelForRef%s%s%s": "Unknown model for reference '%s' on '%s:%s'",
136
+ "unknownPropForRef%s%s%s": "Unknown property for reference '%s:%s' on '%s:%s'",
137
+ "noConnectionUsingDriver%s": "No connection using driver '%s'. To save resource, disabling this driver/plugin is recommended",
138
+ "keyIsRequired%s%s%s": "Key '%s' on %s|toLower '%s' is required",
139
+ "enterRecordId": "Enter record ID:",
140
+ "allowedPropType%s%s": "Allowed property type for field '%s': %s",
141
+ "invalidIdType%s%s": "Invalid ID type for '%s'. Please only use one of these: %s",
142
+ "noDefaultConnection": "No default connection found. All models will use the built-in memory database instead",
143
+ "recordImmutable%s%s": "Record with ID: '%s' & model: '%s' is immutable and can't be modified or deleted",
144
+ "notSupported%s%s%s": "%s|upperFirst '%s' is not supported by driver '%s'",
145
+ "inMemoryDb%s%s": "'%s' is an in-memory database, %s is not allowed",
146
+ "buildOp": "'build' operation",
147
+ "dropOp": "'drop' operation",
127
148
  "field": {
128
149
  "id": "ID",
129
150
  "code": "Kode",
@@ -186,7 +207,9 @@
186
207
  "cycle": "Cycle",
187
208
  "default": "Default",
188
209
  "type": "Type",
189
- "schema": "Schema"
210
+ "model": "Model",
211
+ "age": "Age",
212
+ "provider": "Provider"
190
213
  },
191
214
  "validationError": "Validation Error",
192
215
  "validation": {
@@ -219,6 +242,21 @@
219
242
  "trim": "Must not have leading or trailing whitespace",
220
243
  "uri": "Must be a valid uri",
221
244
  "uppercase": "Must only contain uppercase characters"
245
+ },
246
+ "number": {
247
+ "base": "Must be a number",
248
+ "greater": "Must be greater than %(limit)s",
249
+ "infinity": "Can't be infinity",
250
+ "integer": "Must be an integer number",
251
+ "less": "Must be less than %(limit)s",
252
+ "max": "Must be less or equals than %(limit)s",
253
+ "min": "Must be greater or equals than %(limit)s",
254
+ "multiple": "Must be a multiple of %(multiple)s",
255
+ "negative": "Must be a negative number",
256
+ "port": "Must be a valid port",
257
+ "positive": "Must be a positive number",
258
+ "precision": "Must have no more than %(limit)s decimal point",
259
+ "unsafe": "Must be a safe number"
222
260
  }
223
261
  }
224
262
  }
@@ -2,15 +2,15 @@
2
2
  "isConnected%s%s": "'%s' telah tersambung",
3
3
  "errorOn%s%s": "Kesalahan pada '%s': %s",
4
4
  "isDestroyed%s%s": "'%s' telah dimusnahkan",
5
- "loadedSchemas%s": "Skema termuat: %s",
6
- "loadSchema%s%s%d": "Muat skema: %s (%d)",
5
+ "loadedModels%s": "Model termuat: %s",
6
+ "loadModel%s%s%d": "Muat skema: %s (%d)",
7
7
  "loadedConns%s%s": "Koneksi termuat: %s",
8
8
  "unsupportedPropTypeIn%s%s": "Tipe properti '%s' di '%s' tidak didukung",
9
- "noSchemaFound": "Tidak ditemukan skema!",
10
- "enterSchemaName": "Masukkan nama skema, dipisah dengan spasi:",
11
- "noSchemaMatched": "Tidak ditemukan skema yang cocok",
12
- "schema%d": "Skema (%d)",
13
- "schemasWillBeRebuiltContinue": "Semua skema tersebut diatas akan dibuat ulang sebagai model. Anda yakin?",
9
+ "noModelFound": "Tidak ditemukan skema!",
10
+ "enterModelName": "Masukkan nama skema, dipisah dengan spasi:",
11
+ "noModelMatched": "Tidak ditemukan skema yang cocok",
12
+ "model%d": "Model (%d)",
13
+ "modelsWillBeRebuiltContinue": "Semua skema tersebut diatas akan dibuat ulang sebagai model. Anda yakin?",
14
14
  "rebuilding%s": "Pembuatan ulang '%s'...",
15
15
  "noDbConn%s%s": "Tidak ada koneksi database '%s' untuk '%s'. Batalkan!",
16
16
  "errorDroppingModel%s%s": "Gagal menghapus model '%s': %s",
@@ -21,10 +21,10 @@
21
21
  "memoryDbSkipped%s%s": "Db '%s' untuk '%s' adalah database memori, lewati",
22
22
  "modelBuiltOnthefly%s%s%s": "Model '%s@%s' sukses dibuat ulang on the fly",
23
23
  "unableToBuildModel%s%s%s": "Gagal membuat ulang model '%s' di '%s': %s",
24
- "unknownSchema%s": "Skema '%s' tidak dikenal",
24
+ "unknownModel%s": "Model '%s' tidak dikenal",
25
25
  "payloadMustBeJson": "Data harus berupa obyek JSON yang valid",
26
- "selectSchema": "Silahkan masukkan sebuah skema:",
27
- "enterJsonPayload": "Masukkan data JSON:",
26
+ "selectModel": "Silahkan masukkan sebuah skema:",
27
+ "enterPayload": "Masukkan data:",
28
28
  "payloadRequired": "Data harus diisi",
29
29
  "invalidPayloadSyntax": "Sintak data tidak valid",
30
30
  "creatingRecord": "Pembuatan data",
@@ -32,28 +32,29 @@
32
32
  "idIsRequired": "ID harus diisi",
33
33
  "gettingRecord": "Mengambil data",
34
34
  "removingRecord": "Menghapus data",
35
- "cantFindSchema%s": "Tidak bisa menemukan skema dengan nama %s",
36
- "recordNotFound%s%s": "Data '%s@%s' tidak ditemukan",
37
- "invalidSchema%s": "Skema '%s' tidak valid",
38
- "noPropsFoundOnSchema%s": "Skema '%s' tidak memiliki properti sama sekali",
35
+ "cantFind%s%s": "Tidak menemukan %s|toLower dengan nama '%s'",
36
+ "recordNotFound%s%s": "Data dengan ID: '%s', model: '%s' tidak ditemukan",
37
+ "invalidModel%s": "Model '%s' tidak valid",
38
+ "noPropsFoundOnModel%s": "Model '%s' tidak memiliki properti sama sekali",
39
39
  "fieldIdReserved%s": "Kolom 'id@%s' adalah kolom ter-reservasi dan seharusnya tidak ditambahkan secara manual",
40
40
  "missingPropType%s%s": "Tipe properti untuk '%s@%s' tidak ditemukan",
41
41
  "unsupportedPropType%s%s%s": "Tipe properti '%s@%s' di '%s' tidak didukung",
42
- "unknownConn%s%s": "Koneksi '%s@%s' tidak dikenal",
42
+ "unknownConn%s%s": "Koneksi '%s' untuk '%s' tidak dikenal",
43
43
  "fieldIsRequired%s%s": "Kolom '%s@%s' harus diisi",
44
44
  "keyIsRequired%s": "Kunci '%s' harus diisi",
45
- "enterQueryIfAny": "Silahkan masukkan kueri (jika ada):",
45
+ "enterFilterIfAny": "Silahkan masukkan filter (jika ada):",
46
46
  "findingRecords": "Temukan data",
47
- "recordExists%s%s": "Data '%s@%s' sudah ada",
48
- "fieldGroupAggregateMissing": "Field to group aggregate is missing",
49
- "fieldCalcAggregateMissing": "Field to calculate aggregate is missing",
50
- "baseFieldForHistogramMissing": "Base field for histogram must be provided",
51
- "unknownBaseFieldForHistogram%s": "Unknown base field for histogram '%s'",
47
+ "recordExists%s%s": "Data dengan ID: '%s' & model: '%s' sudah ada",
48
+ "fieldGroupMissing": "Field to group aggregate/histogram is missing",
49
+ "fieldCalcMissing": "Field to calculate aggregate is missing",
50
+ "aggregateTypesMissing": "One or more aggregate type must be provided",
52
51
  "fieldTypeMustBeDatetime%s%s": "Field type '%s@%s' must be a datetime field",
53
52
  "groupFieldToAggregateMissing": "Group field to aggregate is missing",
54
53
  "unknownGroupField%s%s": "Unknown group field '%s@%s'",
55
54
  "grupFieldMustBeNumber": "Group field must be of type integer, smallint or float",
56
55
  "unsupportedAggregateType%s": "Unsupported aggregate type: '%s'",
56
+ "unsupportedHistogramType%s": "Unsupported histogram type: '%s'",
57
+ "histogramTypeMissing": "Histogram type is missing",
57
58
  "keyIsRequired%s%s": "'%s@%s' key is required",
58
59
  "fulltextNeedIntegerId%s%s": "Full text index need integer type primary id in '%s@%s'",
59
60
  "unsupportedAggregate%s": "Unsupported aggregate '%s'",
@@ -77,7 +78,6 @@
77
78
  "recordUpdated": "Record successfully updated",
78
79
  "attachmentUploaded": "Attachment successfully uploaded",
79
80
  "attachmentRemoved": "Attachment successfully removed",
80
- "unknownModelSchema%s": "Unknown model/schema '%s'",
81
81
  "sortOnUnindexedField%s%s": "Sort on unindexed field: '%s@%s'",
82
82
  "modelNotExists%s": "Model '%s' doesn't exist yet. Please do model rebuild first",
83
83
  "invalidDate": "Invalid date",
@@ -95,12 +95,11 @@
95
95
  "proxiedConnBound%s": "'%s' is bound to a proxied connection, skipped!'",
96
96
  "addingMemoryPersistenceIgnored": "'%s' is a memory persistence model. Adding records from fixture is ignored!",
97
97
  "onlyOneConnType%s": "There could only be one connection type '%s'",
98
- "mustValidDbType": "Connection must have a valid DB type",
99
98
  "unsupportedDbType%s": "Unsupported DB type '%s'",
100
99
  "driverMustProvideDbType": "A DB driver must provide at least one database type",
101
100
  "driverMustHaveName": "A DB driver must have a driver name",
102
101
  "dbTypeAlreadySupportedByDriver%s%s": "Database type '%s' already supported by driver '%s'",
103
- "featureNotAsync%s": "Feature '%s' should be an async function",
102
+ "invalidFeatureHandler%s%s": "Handler untuk fitur '%s:%s' tidak valid",
104
103
  "unsupportedIndexType%s%s%s%s": "Unsupported index type %s for '%s@%s'. Allowed values: %s",
105
104
  "unknownFeature%s%s": "'Unknown feature '%s@%s'",
106
105
  "onlyAcceptFields%s%s": "Only accept array of field names or single string of field name '%s@%s'",
@@ -110,13 +109,40 @@
110
109
  "sureContinue": "Are you sure to continue?",
111
110
  "loadingDbFeature": "Loading DB feature",
112
111
  "totalLoadedFeatures%d": "Total loaded features: %d",
113
- "loadingDbSchemas": "Loading DB schemas",
112
+ "loadingDbModels": "Loading DB models",
114
113
  "addingFixtureToMemDb": "Adding fixture for memory database",
115
114
  "recordsAdded%s%d%d": "%s: %d of %d records added",
116
- "driverInstantiated%s%s": "- Driver '%s:%s' instantiated",
115
+ "dbInit": "Initialize database",
116
+ "dbInit%s%s%s": "- %s:%s on connection: '%s'",
117
+ "cantContinueAddFixture": "Can't continue with fixture adding because one or more models failed to rebuilt",
118
+ "addingFixture%s": "Adding fixture '%s'...",
119
+ "fixtureAdded%s%s%s": "Fixture on '%s': added %s, rejected: %s",
120
+ "errorAddingFixture%s%s": "Error adding fixture on model '%s': %s",
121
+ "memoryDbSkipped%s": "'%s' is a memory DB, skipped",
117
122
  "db": "DB",
118
123
  "invalidQuery": "Kueri Tidak Valid",
119
124
  "noResultFound": "Tidak ditemukan hasil",
125
+ "invalidDriverClass%s%s": "Kelas driver '%s:%s' tidak valid",
126
+ "invalidDriverClassFactory%s%s": "Faktori kelas driver '%s:%s' tidak valid",
127
+ "multipleConnection%s": "Model '%s' terhubung dengan lebih dari satu koneksi",
128
+ "invalidFeature%s%s": "Fitur tidak '%s@%s' valid",
129
+ "invalidModelExtender%s%s": "Extender skema '%s@%s' tidak valid",
130
+ "unknownDbDriver%s": "Driver database '%s' tidak dikenal",
131
+ "unknownPropType%s%s": "Tipe properti '%s' di '%s' tidak dikenal",
132
+ "unknownIndexType%s%s": "Tipe index '%s' di '%s' tidak dikenal",
133
+ "unknownPropNameOnIndex%s%s": "Nama properti '%s' di index untuk '%s' tidak dikenal",
134
+ "unknownModelForRef%s%s%s": "Unknown model for reference '%s' on '%s:%s'",
135
+ "unknownPropForRef%s%s%s": "Unknown property for reference '%s:%s' on '%s:%s'",
136
+ "noConnectionUsingDriver%s": "No connection using driver '%s'. To save resource, disabling this driver/plugin is recommended",
137
+ "keyIsRequired%s%s%s": "Key '%s' on %s|toLower '%s' is required",
138
+ "enterRecordId": "Enter record ID:",
139
+ "allowedPropType%s%s": "Allowed property type for field '%s': %s",
140
+ "invalidIdType%s%s": "Invalid ID type for '%s'. Please only use one of these: %s",
141
+ "noDefaultConnection": "No default connection found. All models will use the built-in memory database instead",
142
+ "recordImmutable%s%s": "Data dengan ID: '%s' & model: '%s' adalah immutable dan tidak bisa diubah atau dihapus",
143
+ "inMemoryDb%s%s": "'%s' adalah database in-memory, %s tidak diizinkan",
144
+ "buildOp": "operasi 'build'",
145
+ "dropOp": "operasi 'drop'",
120
146
  "field": {
121
147
  "id": "ID",
122
148
  "code": "Kode",
@@ -179,7 +205,9 @@
179
205
  "cycle": "Cycle",
180
206
  "default": "Default",
181
207
  "type": "Tipe",
182
- "schema": "Skema"
208
+ "model": "Model",
209
+ "age": "Usia",
210
+ "provider": "Penyedia"
183
211
  },
184
212
  "validationError": "Kesalahan Validasi",
185
213
  "validation": {
@@ -0,0 +1,22 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function clearRecord (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const select = await importPkg('bajoCli:@inquirer/select')
8
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
9
+ let [model, options] = args
10
+ options = isEmpty(options) ? {} : parseKvString(options)
11
+ if (isEmpty(model)) {
12
+ model = await select({
13
+ message: this.print.buildText('selectModel'),
14
+ choices: map(this.models, s => ({ value: s.name }))
15
+ })
16
+ }
17
+ await postProcess.call(this, { noConfirmation: options.noConfirmation, handler: 'clearRecord', params: [model, options], path, processMsg: 'Clearing all records' })
18
+ // if (!result) await createRecord.call(this, path, ...args)
19
+ this.app.exit()
20
+ }
21
+
22
+ export default clearRecord
File without changes
@@ -0,0 +1,27 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function countRecord (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const [select, input] = await importPkg('bajoCli:@inquirer/select', 'bajoCli:@inquirer/input')
8
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
9
+ let [model, filter, options] = args
10
+ options = isEmpty(options) ? {} : parseKvString(options)
11
+ if (isEmpty(model)) {
12
+ model = await select({
13
+ message: this.print.buildText('selectModel'),
14
+ choices: map(this.models, s => ({ value: s.name }))
15
+ })
16
+ }
17
+ if (isEmpty(filter)) {
18
+ filter = await input({
19
+ message: this.print.buildText('enterFilterIfAny')
20
+ })
21
+ }
22
+ filter = isEmpty(filter) ? {} : parseKvString(filter)
23
+ await postProcess.call(this, { noConfirmation: true, handler: 'countRecord', params: [model, filter, options], path, processMsg: 'Count records' })
24
+ this.app.exit()
25
+ }
26
+
27
+ export default countRecord
@@ -0,0 +1,33 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function createAggregate (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const [select, input] = await importPkg('bajoCli:@inquirer/select', 'bajoCli:@inquirer/input')
8
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
9
+ let [model, filter, params, options] = args
10
+ options = isEmpty(options) ? {} : parseKvString(options)
11
+ if (isEmpty(model)) {
12
+ model = await select({
13
+ message: this.print.buildText('selectModel'),
14
+ choices: map(this.models, s => ({ value: s.name }))
15
+ })
16
+ }
17
+ if (isEmpty(filter)) {
18
+ filter = await input({
19
+ message: this.print.buildText('enterFilterIfAny')
20
+ })
21
+ }
22
+ filter = isEmpty(filter) ? {} : parseKvString(filter)
23
+ if (isEmpty(params)) {
24
+ params = await input({
25
+ message: this.print.buildText('enterParams')
26
+ })
27
+ }
28
+ params = isEmpty(params) ? {} : parseKvString(params)
29
+ await postProcess.call(this, { noConfirmation: true, handler: 'createAggregate', params: [model, filter, params, options], path, processMsg: 'Create aggregate' })
30
+ this.app.exit()
31
+ }
32
+
33
+ export default createAggregate
@@ -0,0 +1,33 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function createHistogram (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const [select, input] = await importPkg('bajoCli:@inquirer/select', 'bajoCli:@inquirer/input')
8
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
9
+ let [model, filter, params, options] = args
10
+ options = isEmpty(options) ? {} : parseKvString(options)
11
+ if (isEmpty(model)) {
12
+ model = await select({
13
+ message: this.print.buildText('selectModel'),
14
+ choices: map(this.models, s => ({ value: s.name }))
15
+ })
16
+ }
17
+ if (isEmpty(filter)) {
18
+ filter = await input({
19
+ message: this.print.buildText('enterFilterIfAny')
20
+ })
21
+ }
22
+ filter = isEmpty(filter) ? {} : parseKvString(filter)
23
+ if (isEmpty(params)) {
24
+ params = await input({
25
+ message: this.print.buildText('enterParams')
26
+ })
27
+ }
28
+ params = isEmpty(params) ? {} : parseKvString(params)
29
+ await postProcess.call(this, { noConfirmation: true, handler: 'createHistogram', params: [model, filter, params, options], path, processMsg: 'Create histogram' })
30
+ this.app.exit()
31
+ }
32
+
33
+ export default createHistogram
@@ -0,0 +1,39 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function createRecord (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const [input, select, boxen] = await importPkg('bajoCli:@inquirer/input',
8
+ 'bajoCli:@inquirer/select', 'bajoCli:boxen')
9
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
10
+ let [model, body, options] = args
11
+ options = isEmpty(options) ? {} : parseKvString(options)
12
+ if (isEmpty(model)) {
13
+ model = await select({
14
+ message: this.print.buildText('selectModel'),
15
+ choices: map(this.models, s => ({ value: s.name }))
16
+ })
17
+ }
18
+ if (isEmpty(body)) {
19
+ body = await input({
20
+ message: this.print.buildText('enterPayload'),
21
+ validate: text => {
22
+ if (isEmpty(text)) return this.t('payloadRequired')
23
+ return true
24
+ }
25
+ })
26
+ }
27
+ let payload
28
+ try {
29
+ payload = body[0] === '{' ? JSON.parse(body) : parseKvString(body)
30
+ } catch (err) {
31
+ return this.print.fail('invalidPayloadSyntax', { exit: this.app.applet })
32
+ }
33
+ console.log(boxen(JSON.stringify(payload, null, 2), { title: model, padding: 0.5, borderStyle: 'round' }))
34
+ await postProcess.call(this, { noConfirmation: options.noConfirmation, handler: 'createRecord', params: [model, payload, options], path, processMsg: 'Creating record' })
35
+ // if (!result) await createRecord.call(this, path, ...args)
36
+ this.app.exit()
37
+ }
38
+
39
+ export default createRecord
@@ -0,0 +1,27 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function findRecord (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const [select, input] = await importPkg('bajoCli:@inquirer/select', 'bajoCli:@inquirer/input')
8
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
9
+ let [model, filter, options] = args
10
+ options = isEmpty(options) ? {} : parseKvString(options)
11
+ if (isEmpty(model)) {
12
+ model = await select({
13
+ message: this.print.buildText('selectModel'),
14
+ choices: map(this.models, s => ({ value: s.name }))
15
+ })
16
+ }
17
+ if (isEmpty(filter)) {
18
+ filter = await input({
19
+ message: this.print.buildText('enterFilterIfAny')
20
+ })
21
+ }
22
+ filter = isEmpty(filter) ? {} : parseKvString(filter)
23
+ await postProcess.call(this, { noConfirmation: true, handler: 'findRecord', params: [model, filter, options], path, processMsg: 'Finding record(s)' })
24
+ this.app.exit()
25
+ }
26
+
27
+ export default findRecord
@@ -0,0 +1,27 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function getRecord (path, ...args) {
4
+ const { importPkg } = this.app.bajo
5
+ const { isEmpty, map } = this.app.lib._
6
+ const { parseKvString } = this.app.lib.aneka
7
+ const [input, select] = await importPkg('bajoCli:@inquirer/input', 'bajoCli:@inquirer/select')
8
+ if (isEmpty(this.models)) return this.print.fail('notFound%s', this.t('field.model'), { exit: this.app.applet })
9
+ let [model, id, options] = args
10
+ options = isEmpty(options) ? {} : parseKvString(options)
11
+ if (isEmpty(model)) {
12
+ model = await select({
13
+ message: this.print.buildText('Please select a model:'),
14
+ choices: map(this.models, s => ({ value: s.name }))
15
+ })
16
+ }
17
+ if (isEmpty(id + '')) {
18
+ id = await input({
19
+ message: this.print.buildText('Enter record ID:'),
20
+ validate: text => isEmpty(text) ? this.t('ID is required') : true
21
+ })
22
+ }
23
+ await postProcess.call(this, { noConfirmation: true, handler: 'getRecord', params: [model, id, options], path, processMsg: 'Getting record' })
24
+ this.app.exit()
25
+ }
26
+
27
+ export default getRecord
@@ -1,16 +1,13 @@
1
- const conns = []
2
-
3
1
  async function postProcess ({ handler, params, path, processMsg, noConfirmation } = {}) {
4
- const { importPkg, generateId } = this.app.bajo
2
+ const { importPkg } = this.app.bajo
3
+ const { generateId } = this.app.lib.aneka
5
4
  const { writeOutput } = this.app.bajoCli
6
- const { find, get, isEmpty } = this.app.lib._
7
- const [confirm] = await importPkg('bajoCli:strip-ansi', 'bajoCli:@inquirer/confirm')
8
- const { confirmation, fields, full } = this.app.bajo.config
9
- if (!noConfirmation && confirmation === false) noConfirmation = true
10
- params.push({ fields, dataOnly: !full })
5
+ const { get, isEmpty } = this.app.lib._
6
+ const confirm = await importPkg('bajoCli:@inquirer/confirm')
11
7
 
12
- const schema = find(this.schemas, { name: params[0] })
13
- if (!schema) return this.print.fatal('notFound%s', this.t('field.schema'))
8
+ const name = params.shift()
9
+ const model = this.getModel(name)
10
+ if (!model) return this.print.fatal('notFound%s', this.t('field.model'))
14
11
  let cont = true
15
12
  if (!noConfirmation) {
16
13
  const answer = await confirm({ message: this.print.buildText('sureContinue'), default: false })
@@ -21,13 +18,9 @@ async function postProcess ({ handler, params, path, processMsg, noConfirmation
21
18
  }
22
19
  if (!cont) return
23
20
  const spin = this.print.spinner().start(`${processMsg}...`)
24
- const { connection } = this.getInfo(schema)
25
- if (!conns.includes(connection.name)) {
26
- await this.start(connection.name)
27
- conns.push(connection.name)
28
- }
21
+ await this.start([model.connection.name])
29
22
  try {
30
- const resp = await this[handler](...params)
23
+ const resp = await model[handler](...params)
31
24
  if (isEmpty(resp)) {
32
25
  spin.warn('noResultFound')
33
26
  return false
@@ -45,7 +38,7 @@ async function postProcess ({ handler, params, path, processMsg, noConfirmation
45
38
  if (this.app.bajo.config.log.applet) {
46
39
  spin.stop()
47
40
  console.error(err)
48
- } else spin.fail('error%s', err.message)
41
+ } else spin.fail('error%s', err.detailsMessage ?? err.message)
49
42
  return false
50
43
  }
51
44
  }