dobo 2.0.0 → 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 (197) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/.github/workflows/repo-lockdown.yml +24 -0
  3. package/.jsdoc.conf.json +45 -0
  4. package/LICENSE +1 -1
  5. package/README.md +38 -19
  6. package/docs/Dobo.html +26 -0
  7. package/docs/data/search.json +1 -0
  8. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  9. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  10. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  11. package/docs/global.html +7 -0
  12. package/docs/index.html +3 -0
  13. package/docs/index.js.html +578 -0
  14. package/docs/lib_collect-connections.js.html +39 -0
  15. package/docs/lib_collect-drivers.js.html +52 -0
  16. package/docs/lib_collect-features.js.html +36 -0
  17. package/docs/lib_collect-schemas.js.html +94 -0
  18. package/docs/lib_index.js.html +6 -0
  19. package/docs/method_model_create.js.html +35 -0
  20. package/docs/method_model_drop.js.html +34 -0
  21. package/docs/method_model_exists.js.html +40 -0
  22. package/docs/method_record_count.js.html +69 -0
  23. package/docs/method_record_create.js.html +114 -0
  24. package/docs/method_record_find-all.js.html +44 -0
  25. package/docs/method_record_find-one.js.html +73 -0
  26. package/docs/method_record_find.js.html +118 -0
  27. package/docs/method_record_get.js.html +92 -0
  28. package/docs/method_record_remove.js.html +75 -0
  29. package/docs/method_record_update.js.html +107 -0
  30. package/docs/method_record_upsert.js.html +54 -0
  31. package/docs/method_sanitize_body.js.html +88 -0
  32. package/docs/method_sanitize_date.js.html +30 -0
  33. package/docs/method_sanitize_id.js.html +20 -0
  34. package/docs/method_validate.js.html +249 -0
  35. package/docs/module-Lib.html +3 -0
  36. package/docs/scripts/core.js +725 -0
  37. package/docs/scripts/core.min.js +23 -0
  38. package/docs/scripts/resize.js +90 -0
  39. package/docs/scripts/search.js +265 -0
  40. package/docs/scripts/search.min.js +6 -0
  41. package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
  42. package/docs/scripts/third-party/fuse.js +9 -0
  43. package/docs/scripts/third-party/hljs-line-num-original.js +366 -0
  44. package/docs/scripts/third-party/hljs-line-num.js +1 -0
  45. package/docs/scripts/third-party/hljs-original.js +5164 -0
  46. package/docs/scripts/third-party/hljs.js +1 -0
  47. package/docs/scripts/third-party/popper.js +5 -0
  48. package/docs/scripts/third-party/tippy.js +1 -0
  49. package/docs/scripts/third-party/tocbot.js +671 -0
  50. package/docs/scripts/third-party/tocbot.min.js +1 -0
  51. package/docs/static/bitcoin.jpeg +0 -0
  52. package/docs/static/home.md +25 -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 +1159 -0
  56. package/docs/styles/clean-jsdoc-theme-dark.css +412 -0
  57. package/docs/styles/clean-jsdoc-theme-light.css +482 -0
  58. package/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
  59. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
  60. package/docs/styles/clean-jsdoc-theme.min.css +1 -0
  61. package/extend/bajo/intl/en-US.json +69 -30
  62. package/extend/bajo/intl/id.json +58 -29
  63. package/extend/bajoCli/applet/clear-record.js +22 -0
  64. package/extend/bajoCli/applet/connection.js +5 -5
  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 +25 -26
  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 +10 -8
  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 +35 -57
  83. package/extend/dobo/feature/updated-at.js +14 -12
  84. package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +5 -9
  85. package/extend/waibuStatic/virtual.json +0 -0
  86. package/index.js +420 -337
  87. package/lib/collect-connections.js +60 -21
  88. package/lib/collect-drivers.js +29 -35
  89. package/lib/collect-features.js +40 -0
  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/lib/factory/model/find-record.js +103 -0
  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/lib/factory/model/validate.js +232 -0
  122. package/lib/factory/model.js +150 -0
  123. package/lib/index.js +3 -0
  124. package/package.json +45 -36
  125. package/wiki/APPLETS.md +57 -0
  126. package/wiki/CHANGES.md +46 -0
  127. package/wiki/CONFIG.md +25 -0
  128. package/wiki/CONTRIBUTING.md +5 -0
  129. package/wiki/DEV-GUIDE.md +1 -0
  130. package/wiki/ECOSYSTEM.md +20 -0
  131. package/wiki/GETTING-STARTED.md +166 -0
  132. package/{docs/query-language.md → wiki/QUERY-LANGUAGE.md} +0 -0
  133. package/wiki/USER-GUIDE.md +1 -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 -41
  137. package/extend/bajoCli/applet/record-find.js +0 -27
  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-feature.js +0 -25
  146. package/lib/collect-schemas.js +0 -83
  147. package/lib/exec-feature-hook.js +0 -13
  148. package/lib/exec-validation.js +0 -21
  149. package/lib/generic-prop-sanitizer.js +0 -31
  150. package/lib/handle-attachment-upload.js +0 -16
  151. package/lib/mem-db/conn-sanitizer.js +0 -8
  152. package/lib/mem-db/instantiate.js +0 -41
  153. package/lib/mem-db/method/model/clear.js +0 -6
  154. package/lib/mem-db/method/model/create.js +0 -5
  155. package/lib/mem-db/method/model/drop.js +0 -5
  156. package/lib/mem-db/method/model/exists.js +0 -5
  157. package/lib/mem-db/method/record/create.js +0 -12
  158. package/lib/mem-db/method/record/find.js +0 -20
  159. package/lib/mem-db/method/record/get.js +0 -9
  160. package/lib/mem-db/method/record/remove.js +0 -13
  161. package/lib/mem-db/method/record/update.js +0 -15
  162. package/lib/mem-db/method/stat/count.js +0 -11
  163. package/lib/mem-db/start.js +0 -25
  164. package/lib/merge-attachment-info.js +0 -16
  165. package/lib/multi-rel-rows.js +0 -42
  166. package/lib/resolve-method.js +0 -16
  167. package/lib/sanitize-schema.js +0 -197
  168. package/lib/single-rel-rows.js +0 -38
  169. package/method/attachment/copy-uploaded.js +0 -34
  170. package/method/attachment/create.js +0 -29
  171. package/method/attachment/find.js +0 -27
  172. package/method/attachment/get-path.js +0 -12
  173. package/method/attachment/get.js +0 -12
  174. package/method/attachment/pre-check.js +0 -9
  175. package/method/attachment/remove.js +0 -11
  176. package/method/attachment/update.js +0 -7
  177. package/method/bulk/create.js +0 -46
  178. package/method/model/clear.js +0 -22
  179. package/method/model/create.js +0 -19
  180. package/method/model/drop.js +0 -19
  181. package/method/model/exists.js +0 -24
  182. package/method/record/clear.js +0 -24
  183. package/method/record/count.js +0 -44
  184. package/method/record/create.js +0 -71
  185. package/method/record/find-all.js +0 -25
  186. package/method/record/find-one.js +0 -56
  187. package/method/record/find.js +0 -52
  188. package/method/record/get.js +0 -47
  189. package/method/record/remove.js +0 -41
  190. package/method/record/update.js +0 -63
  191. package/method/record/upsert.js +0 -35
  192. package/method/sanitize/body.js +0 -70
  193. package/method/sanitize/date.js +0 -14
  194. package/method/sanitize/id.js +0 -7
  195. package/method/stat/aggregate.js +0 -23
  196. package/method/stat/histogram.js +0 -26
  197. package/method/validate.js +0 -157
@@ -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,33 +33,33 @@
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'",
62
- "unsupportedAllowedChoices%s%s%s%s%s": "Unsupported %s '%s' for '%s@%s'. Allowed choices: %s",
62
+ "unsupportedAllowedChoices%s%s%s%s%s": "Unsupported %s '%s' for '%s@%s'. Allowed values: %s",
63
63
  "methodIsDisabled%s%s": "Method '%s@%s' is disabled",
64
64
  "invalidModelForPersistence%s": "Invalid model for persistence: %s",
65
65
  "cantLoad%s%s": "Can't load %s: %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,13 +96,12 @@
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",
106
- "unsupportedIndexType%s%s%s%s": "Unsupported index type %s for '%s@%s'. Allowed choices: %s",
103
+ "invalidFeatureHandler%s%s": "Invalid handler for feature '%s:%s'",
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'",
109
107
  "invalidFieldName%s%s": "Invalid 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",
@@ -123,6 +122,29 @@
123
122
  "memoryDbSkipped%s": "'%s' is a memory DB, skipped",
124
123
  "db": "DB",
125
124
  "invalidQuery": "Invalid Query",
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",
126
148
  "field": {
127
149
  "id": "ID",
128
150
  "code": "Kode",
@@ -185,7 +207,9 @@
185
207
  "cycle": "Cycle",
186
208
  "default": "Default",
187
209
  "type": "Type",
188
- "schema": "Schema"
210
+ "model": "Model",
211
+ "age": "Age",
212
+ "provider": "Provider"
189
213
  },
190
214
  "validationError": "Validation Error",
191
215
  "validation": {
@@ -218,6 +242,21 @@
218
242
  "trim": "Must not have leading or trailing whitespace",
219
243
  "uri": "Must be a valid uri",
220
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"
221
260
  }
222
261
  }
223
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,32 +32,33 @@
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'",
60
- "unsupportedAllowedChoices%s%s%s%s%s": "Unsupported %s '%s' for '%s@%s'. Allowed choices: %s",
61
+ "unsupportedAllowedChoices%s%s%s%s%s": "Unsupported %s '%s' for '%s@%s'. Allowed values: %s",
61
62
  "methodIsDisabled%s%sMethod": "Metode '%s@%s' dinonaktifkan",
62
63
  "invalidModelForPersistence%s": "Model untuk penyimpanan tidak valid: %s",
63
64
  "cantLoad%s%s": "Tidak bisa memuat %s: %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,13 +95,12 @@
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",
104
- "unsupportedIndexType%s%s%s%s": "Unsupported index type %s for '%s@%s'. Allowed choices: %s",
102
+ "invalidFeatureHandler%s%s": "Handler untuk fitur '%s:%s' tidak valid",
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'",
107
106
  "invalidFieldName%s%s": "Invalid field name '%s@%s'",
@@ -110,12 +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",
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'",
119
146
  "field": {
120
147
  "id": "ID",
121
148
  "code": "Kode",
@@ -178,7 +205,9 @@
178
205
  "cycle": "Cycle",
179
206
  "default": "Default",
180
207
  "type": "Tipe",
181
- "schema": "Skema"
208
+ "model": "Model",
209
+ "age": "Usia",
210
+ "provider": "Penyedia"
182
211
  },
183
212
  "validationError": "Kesalahan Validasi",
184
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
@@ -1,22 +1,22 @@
1
1
  async function connection (path, ...args) {
2
2
  const { importPkg } = this.app.bajo
3
- const { isEmpty, map, find } = this.lib._
3
+ const { isEmpty, map, find } = this.app.lib._
4
4
  const select = await importPkg('bajoCli:@inquirer/select')
5
5
  const { getOutputFormat, writeOutput } = this.app.bajoCli
6
6
  const format = getOutputFormat()
7
- if (isEmpty(this.connections)) return this.print.fail('notFound%s', 'connection', { exit: this.app.bajo.applet })
7
+ if (isEmpty(this.connections)) return this.print.fail('notFound%s', 'connection', { exit: this.app.applet })
8
8
  let name = args[0]
9
9
  if (isEmpty(name)) {
10
10
  const choices = map(this.connections, s => ({ value: s.name }))
11
11
  name = await select({
12
- message: this.print.write('chooseConn'),
12
+ message: this.print.buildText('chooseConn'),
13
13
  choices
14
14
  })
15
15
  }
16
16
  const result = find(this.connections, { name })
17
- if (!result) return this.print.fail('cantFind%s%s', this.print.write('connection'), name, { exit: this.app.bajo.applet })
17
+ if (!result) return this.print.fail('cantFind%s%s', this.t('connection'), name, { exit: this.app.applet })
18
18
  this.print.info('done')
19
- await writeOutput(result, path, format)
19
+ await writeOutput(result, `${this.ns}-${path}-${name}`, format, true)
20
20
  }
21
21
 
22
22
  export default connection
@@ -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