dobo 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bajo/init.js +2 -2
- package/bajo/intl/en-US.json +215 -0
- package/bajo/intl/id.json +228 -0
- package/bajo/method/attachment/copy-uploaded.js +2 -2
- package/bajo/method/attachment/create.js +2 -2
- package/bajo/method/attachment/remove.js +1 -1
- package/bajo/method/get-schema.js +1 -1
- package/bajo/method/model/exists.js +1 -1
- package/bajo/method/prep-pagination.js +1 -1
- package/bajo/method/record/create.js +1 -1
- package/bajo/method/record/remove.js +1 -1
- package/bajo/method/record/update.js +1 -1
- package/bajo/method/sanitize/date.js +1 -1
- package/bajo/method/stat/histogram.js +1 -1
- package/bajo/method/validate.js +1 -1
- package/bajo/start.js +1 -1
- package/bajoCli/applet/connection.js +4 -4
- package/bajoCli/applet/lib/post-process.js +5 -5
- package/bajoCli/applet/model-clear.js +1 -1
- package/bajoCli/applet/model-rebuild.js +14 -14
- package/bajoCli/applet/record-create.js +6 -6
- package/bajoCli/applet/record-find.js +3 -3
- package/bajoCli/applet/record-get.js +1 -1
- package/bajoCli/applet/record-remove.js +1 -1
- package/bajoCli/applet/record-update.js +8 -8
- package/bajoCli/applet/schema.js +4 -4
- package/bajoCli/applet/stat-count.js +3 -3
- package/lib/add-fixtures.js +3 -4
- package/lib/build-bulk-action.js +2 -2
- package/lib/check-unique.js +2 -2
- package/lib/collect-connections.js +2 -2
- package/lib/collect-drivers.js +3 -3
- package/lib/collect-feature.js +3 -3
- package/lib/collect-schemas.js +3 -3
- package/lib/generic-prop-sanitizer.js +2 -9
- package/lib/mem-db/instantiate.js +1 -1
- package/lib/mem-db/method/record/create.js +1 -1
- package/lib/mem-db/method/record/get.js +1 -1
- package/lib/mem-db/start.js +2 -2
- package/lib/resolve-method.js +2 -2
- package/lib/sanitize-schema.js +5 -5
- package/package.json +1 -1
- package/bajoI18N/resource/en-US.json +0 -92
- package/bajoI18N/resource/id.json +0 -185
package/bajo/init.js
CHANGED
|
@@ -6,7 +6,7 @@ import collectSchemas from '../lib/collect-schemas.js'
|
|
|
6
6
|
async function checkType (item, items) {
|
|
7
7
|
const { filter } = this.app.bajo.lib._
|
|
8
8
|
const existing = filter(items, { type: 'dobo:memory' })
|
|
9
|
-
if (existing.length > 1) this.fatal('
|
|
9
|
+
if (existing.length > 1) this.fatal('onlyOneConnType%s', item.type)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
async function init () {
|
|
@@ -21,7 +21,7 @@ async function init () {
|
|
|
21
21
|
})
|
|
22
22
|
}
|
|
23
23
|
this.connections = await buildCollections({ ns: this.name, container: 'connections', handler: collectConnections, dupChecks: ['name', checkType] })
|
|
24
|
-
if (this.connections.length === 0) this.log.warn('
|
|
24
|
+
if (this.connections.length === 0) this.log.warn('notFound%s', this.print.write('connection'))
|
|
25
25
|
await collectFeature.call(this)
|
|
26
26
|
await collectSchemas.call(this)
|
|
27
27
|
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
{
|
|
2
|
+
"isConnected%s%s": "[%s] '%s' is connected",
|
|
3
|
+
"errorOn%s%s": "[%s] Error on '%s': %s",
|
|
4
|
+
"isDestroyed%s%s": "[%s] '%s' is destroyed",
|
|
5
|
+
"loadedSchemas%s": "[%s] Loaded schemas: %s",
|
|
6
|
+
"loadSchema%s%s%d": "[%s] Load schema: %s (%d)",
|
|
7
|
+
"loadedConns%s%s": "[%s] Loaded connections: %s",
|
|
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?",
|
|
14
|
+
"rebuilding%s": "Rebuilding '%s'...",
|
|
15
|
+
"noDbConn%s%s": "No DB connection '%s' for '%s'. Aborted!",
|
|
16
|
+
"errorDroppingModel%s%s": "Error dropping model '%s': %s",
|
|
17
|
+
"modelExistsNeedForce%s": "Model '%s' exists already. Can't rebuild without --force",
|
|
18
|
+
"modelCreated%s": "Model '%s' successfully created",
|
|
19
|
+
"modelCreatedWithFixture%s%s%s": "Model '%s' successfully created, with fixture: added %s, rejected: %s",
|
|
20
|
+
"errorCreatingModel%s%s": "Error creating model '%s': %s",
|
|
21
|
+
"modelDropped%s": "Model '%s' successfully dropped",
|
|
22
|
+
"memoryDbSkipped%s%s": "DB '%s' for '%s' is a memory DB, skipped",
|
|
23
|
+
"modelBuiltOnthefly%s%s%s": "[%s] Model '%s@%s' successfully built on the fly",
|
|
24
|
+
"unableToBuildModel%s%s%s": "Unable to re-build model '%s' in '%s': %s",
|
|
25
|
+
"unknownSchema%s": "Unknown schema '%s'",
|
|
26
|
+
"payloadMustBeJson": "Payload must be a valid JSON",
|
|
27
|
+
"selectSchema": "Please select a schema:",
|
|
28
|
+
"enterJsonPayload": "Enter JSON payload:",
|
|
29
|
+
"payloadRequired": "Payload is required",
|
|
30
|
+
"invalidPayloadSyntax": "Invalid payload syntax",
|
|
31
|
+
"creatingRecord": "Creating record",
|
|
32
|
+
"enterRecordId:": "Enter record ID:",
|
|
33
|
+
"idIsRequired": "ID is required",
|
|
34
|
+
"gettingRecord": "Getting record",
|
|
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",
|
|
41
|
+
"fieldIdReserved%s": "Field 'id@%s' is a reserved column and should not added manually",
|
|
42
|
+
"missingPropType%s%s": "Property type for '%s@%s' is missing",
|
|
43
|
+
"unsupportedPropType%s%s%s": "Unsupported property type '%s@%s' in '%s'",
|
|
44
|
+
"unknownConn%s%s": "Unknown connection '%s@%s'",
|
|
45
|
+
"fieldIsRequired%s%s": "Column '%s@%s' is required",
|
|
46
|
+
"keyIsRequired%s": "Key '%s' is required",
|
|
47
|
+
"enterQueryIfAny": "Please enter your query (if any):",
|
|
48
|
+
"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'",
|
|
54
|
+
"fieldTypeMustBeDatetime%s%s": "Field type '%s@%s' must be a datetime field",
|
|
55
|
+
"groupFieldToAggregateMissing": "Group field to aggregate is missing",
|
|
56
|
+
"unknownGroupField%s%s": "Unknown group field '%s@%s'",
|
|
57
|
+
"grupFieldMustBeNumber": "Group field must be of type integer, smallint or float",
|
|
58
|
+
"unsupportedAggregateType%s": "Unsupported aggregate type: '%s'",
|
|
59
|
+
"keyIsRequired%s%s": "'%s@%s' key is required",
|
|
60
|
+
"fulltextNeedIntegerId%s%s": "Full text index need integer type primary id in '%s@%s'",
|
|
61
|
+
"unsupportedAggregate%s": "Unsupported aggregate '%s'",
|
|
62
|
+
"unsupportedAllowedChoices%s%s%s%s%s": "Unsupported %s '%s' for '%s@%s'. Allowed choices: %s",
|
|
63
|
+
"methodIsDisabled%s%s": "Method '%s@%s' is disabled",
|
|
64
|
+
"invalidModelForPersistence%s": "Invalid model for persistence: %s",
|
|
65
|
+
"cantLoad%s%s": "Can't load %s: %s",
|
|
66
|
+
"noRecordFound": "No record found",
|
|
67
|
+
"recordsFound%d": "%d record(s) found",
|
|
68
|
+
"add": "Add",
|
|
69
|
+
"edit": "Edit",
|
|
70
|
+
"delete": "Delete",
|
|
71
|
+
"export": "Export",
|
|
72
|
+
"query": "Query",
|
|
73
|
+
"queryBuilder": "Query Builder",
|
|
74
|
+
"list": "List",
|
|
75
|
+
"submitQuery": "Submit Query",
|
|
76
|
+
"dataExport": "Data Export",
|
|
77
|
+
"recordCreated": "Record successfully created",
|
|
78
|
+
"recordRemoved": "Record successfully removed",
|
|
79
|
+
"recordUpdated": "Record successfully updated",
|
|
80
|
+
"attachmentUploaded": "Attachment successfully uploaded",
|
|
81
|
+
"attachmentRemoved": "Attachment successfully removed",
|
|
82
|
+
"unknownModelSchema%s": "Unknown model/schema '%s'",
|
|
83
|
+
"sortOnUnindexedField%s%s": "Sort on unindexed field: '%s@%s'",
|
|
84
|
+
"modelNotExists%s": "Model '%s' doesn't exist yet. Please do model rebuild first",
|
|
85
|
+
"invalidDate": "Invalid date",
|
|
86
|
+
"histogramTypeMusBe%s": "Histogram type must be one of these: %s",
|
|
87
|
+
"methodUnsupported%s%s": "Method '%s@%s' is unsupported",
|
|
88
|
+
"uniqueConstraintError": "Unique constraint error",
|
|
89
|
+
"taskMustHaveModel%s": "Task must have %s model",
|
|
90
|
+
"driverNotInstalled%s": "Problem with '%s' driver file. Not installed yet?",
|
|
91
|
+
"generalDbError": "General Database Error",
|
|
92
|
+
"dbConstrainError": "Database Constraint Error",
|
|
93
|
+
"onlySupportThese%s": "Only support one of these: %s",
|
|
94
|
+
"isMissing%s": "%s is missing",
|
|
95
|
+
"notFound%s": "No %s found!",
|
|
96
|
+
"clientInstanceNotConnected%s": "Client instance not connected '%s@%s'. Skipped!",
|
|
97
|
+
"proxiedConnBound%s": "'%s' is bound to a proxied connection, skipped!'",
|
|
98
|
+
"addingMemoryPersistenceIgnored": "'%s' is a memory persistence model. Adding records from fixture is ignored!",
|
|
99
|
+
"onlyOneConnType%s": "There could only be one connection type '%s'",
|
|
100
|
+
"mustValidDbType": "Connection must have a valid DB type",
|
|
101
|
+
"unsupportedDbType%s": "Unsupported DB type '%s'",
|
|
102
|
+
"driverMustProvideDbType": "A DB driver must provide at least one database type",
|
|
103
|
+
"driverMustHaveName": "A DB driver must have a driver name",
|
|
104
|
+
"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",
|
|
107
|
+
"unknownFeature%s%s": "'Unknown feature '%s@%s'",
|
|
108
|
+
"onlyAccepFields%s%s": "Only accept array of field names or single string of field name '%s@%s'",
|
|
109
|
+
"invalidFieldName%s%s": "Invalid field name '%s@%s'",
|
|
110
|
+
"error%s": "Error: %s",
|
|
111
|
+
"succeedFailSkip%d%d%d": "Done! Succeded: %d, failed: %s, skipped: %d",
|
|
112
|
+
"chooseConn": "Please choose a connection:",
|
|
113
|
+
"sureContinue": "Are you sure to continue?",
|
|
114
|
+
"loadingDbFeature": "Loading DB feature",
|
|
115
|
+
"totalLoadedFeatures%d": "Total loaded features: %d",
|
|
116
|
+
"loadingDbSchemas": "Loading DB schemas",
|
|
117
|
+
"addingFixtureToMemDb": "Adding fixture for memory database",
|
|
118
|
+
"recordsAdded%s%d%d": "%s: %d of %d records added",
|
|
119
|
+
"driverInstantiated%s%s": "- Driver '%s:%s' instantiated",
|
|
120
|
+
"field": {
|
|
121
|
+
"id": "ID",
|
|
122
|
+
"code": "Kode",
|
|
123
|
+
"name": "Name",
|
|
124
|
+
"dt": "Date/Time",
|
|
125
|
+
"createdAt": "Created At",
|
|
126
|
+
"updatedAt": "Updated At",
|
|
127
|
+
"title": "Title",
|
|
128
|
+
"description": "Description",
|
|
129
|
+
"subTitle": "Sub Title",
|
|
130
|
+
"plugin": "Plugin",
|
|
131
|
+
"author": "Author",
|
|
132
|
+
"dir": "Directory",
|
|
133
|
+
"file": "File",
|
|
134
|
+
"meta": "Meta Info",
|
|
135
|
+
"level": "Level",
|
|
136
|
+
"ref": "Reference",
|
|
137
|
+
"section": "Section",
|
|
138
|
+
"asset": "Asset",
|
|
139
|
+
"category": "Category",
|
|
140
|
+
"categoryId": "Category ID",
|
|
141
|
+
"username": "Username",
|
|
142
|
+
"password": "Password",
|
|
143
|
+
"password2": "Repeat Password",
|
|
144
|
+
"firstName": "First Name",
|
|
145
|
+
"lastName": "Last Name",
|
|
146
|
+
"address1": "Address 1",
|
|
147
|
+
"address2": "Address 2",
|
|
148
|
+
"city": "City Name",
|
|
149
|
+
"zipCode": "Zip Code",
|
|
150
|
+
"provinceState": "State",
|
|
151
|
+
"country": "Country",
|
|
152
|
+
"phone": "Phone",
|
|
153
|
+
"email": "Email",
|
|
154
|
+
"key": "Key",
|
|
155
|
+
"status": "Status",
|
|
156
|
+
"orgName": "Organization",
|
|
157
|
+
"picName": "PIC Name",
|
|
158
|
+
"picRole": "PIC Role",
|
|
159
|
+
"picPhone": "PIC Phone",
|
|
160
|
+
"picEmail": "PIC Email",
|
|
161
|
+
"website": "Website",
|
|
162
|
+
"alias": "Alias",
|
|
163
|
+
"twitter": "Twitter",
|
|
164
|
+
"instagram": "Instagram",
|
|
165
|
+
"linkedIn": "Linked In",
|
|
166
|
+
"facebook": "Faceboook",
|
|
167
|
+
"userId": "User ID",
|
|
168
|
+
"siteId": "Site ID",
|
|
169
|
+
"theme": "Theme",
|
|
170
|
+
"token": "Token",
|
|
171
|
+
"field": "Field",
|
|
172
|
+
"agree": "Agreement",
|
|
173
|
+
"method": "Metode",
|
|
174
|
+
"masterId": "Master ID",
|
|
175
|
+
"details": "Details",
|
|
176
|
+
"qty": "QTY",
|
|
177
|
+
"link": "Link",
|
|
178
|
+
"amount": "Amount",
|
|
179
|
+
"cycle": "Cycle",
|
|
180
|
+
"default": "Default"
|
|
181
|
+
},
|
|
182
|
+
"validationError": "Kesalahan Validasi",
|
|
183
|
+
"validation": {
|
|
184
|
+
"any": {
|
|
185
|
+
"required": "Required",
|
|
186
|
+
"only": "Must match with {{ref}}"
|
|
187
|
+
},
|
|
188
|
+
"string": {
|
|
189
|
+
"alphanum": "Must only contain alpha-numeric characters",
|
|
190
|
+
"base": "Must be a string",
|
|
191
|
+
"base64": "Must be a valid base64 string",
|
|
192
|
+
"creditCard": "Must be a credit card",
|
|
193
|
+
"dataUri": "Must be a valid dataUri string",
|
|
194
|
+
"domain": "Must contain a valid domain name",
|
|
195
|
+
"email": "Must be a valid email",
|
|
196
|
+
"empty": "Required",
|
|
197
|
+
"guid": "Must be a valid GUID",
|
|
198
|
+
"hex": "Must only contain hexadecimal characters",
|
|
199
|
+
"hexAlign": "Hex decoded representation must be byte aligned",
|
|
200
|
+
"hostname": "Must be a valid hostname",
|
|
201
|
+
"ip": "must be a valid ip address with a {{cidr}} CIDR",
|
|
202
|
+
"ipVersion": "Must be a valid ip address of one of the following versions {{version}} with a {{cidr}} CIDR",
|
|
203
|
+
"isoDate": "Must be in iso format",
|
|
204
|
+
"isoDuration": "Must be a valid ISO 8601 duration",
|
|
205
|
+
"length": "Length must be {{limit}} characters long",
|
|
206
|
+
"lowercase": "Must only contain lowercase characters",
|
|
207
|
+
"max": "Length must be less than or equal to {{limit}} characters long",
|
|
208
|
+
"min": "Length must be at least {{limit}} characters long",
|
|
209
|
+
"token": "Must only contain alpha-numeric and underscore characters",
|
|
210
|
+
"trim": "Must not have leading or trailing whitespace",
|
|
211
|
+
"uri": "Must be a valid uri",
|
|
212
|
+
"uppercase": "Must only contain uppercase characters"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
{
|
|
2
|
+
"isConnected%s%s": "[%s] '%s' telah tersambung",
|
|
3
|
+
"errorOn%s%s": "[%s] Kesalahan pada '%s': %s",
|
|
4
|
+
"isDestroyed%s%s": "[%s] '%s' telah dimusnahkan",
|
|
5
|
+
"loadedSchemas%s": "[%s] Skema termuat: %s",
|
|
6
|
+
"loadSchema%s%s%d": "[%s] Muat skema: %s (%d)",
|
|
7
|
+
"loadedConns%s%s": "[%s] Koneksi termuat: %s",
|
|
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?",
|
|
14
|
+
"rebuilding%s": "Pembuatan ulang '%s'...",
|
|
15
|
+
"noDbConn%s%s": "Tidak ada koneksi database '%s' untuk '%s'. Batalkan!",
|
|
16
|
+
"errorDroppingModel%s%s": "Gagal menghapus model '%s': %s",
|
|
17
|
+
"modelExistsNeedForce%s": "Model '%s' telah ada. Tidak dilakukan pembuatan ulang tanpa --force",
|
|
18
|
+
"modelCreated%s": "Model '%s' sukses dibuat",
|
|
19
|
+
"errorCreatingModel%s%s": "Gagal membuat model '%s': %s",
|
|
20
|
+
"modelDropped%s": "Model '%s' sukses dihapus",
|
|
21
|
+
"memoryDbSkipped%s%s": "Db '%s' untuk '%s' adalah database memori, lewati",
|
|
22
|
+
"modelBuiltOnthefly%s%s%s": "[%s] Model '%s@%s' sukses dibuat ulang on the fly",
|
|
23
|
+
"unableToBuildModel%s%s%s": "Gagal membuat ulang model '%s' di '%s': %s",
|
|
24
|
+
"unknownSchema%s": "Skema '%s' tidak dikenal",
|
|
25
|
+
"payloadMustBeJson": "Data harus berupa obyek JSON yang valid",
|
|
26
|
+
"selectSchema": "Silahkan masukkan sebuah skema:",
|
|
27
|
+
"enterJsonPayload": "Masukkan data JSON:",
|
|
28
|
+
"payloadRequired": "Data harus diisi",
|
|
29
|
+
"invalidPayloadSyntax": "Sintak data tidak valid",
|
|
30
|
+
"creatingRecord": "Pembuatan data",
|
|
31
|
+
"enterRecordId:": "Masukkan ID data:",
|
|
32
|
+
"idIsRequired": "ID harus diisi",
|
|
33
|
+
"gettingRecord": "Mengambil data",
|
|
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",
|
|
39
|
+
"fieldIdReserved%s": "Kolom 'id@%s' adalah kolom ter-reservasi dan seharusnya tidak ditambahkan secara manual",
|
|
40
|
+
"missingPropType%s%s": "Tipe properti untuk '%s@%s' tidak ditemukan",
|
|
41
|
+
"unsupportedPropType%s%s%s": "Tipe properti '%s@%s' di '%s' tidak didukung",
|
|
42
|
+
"unknownConn%s%s": "Koneksi '%s@%s' tidak dikenal",
|
|
43
|
+
"fieldIsRequired%s%s": "Kolom '%s@%s' harus diisi",
|
|
44
|
+
"keyIsRequired%s": "Kunci '%s' harus diisi",
|
|
45
|
+
"enterQueryIfAny": "Silahkan masukkan kueri (jika ada):",
|
|
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'",
|
|
52
|
+
"fieldTypeMustBeDatetime%s%s": "Field type '%s@%s' must be a datetime field",
|
|
53
|
+
"groupFieldToAggregateMissing": "Group field to aggregate is missing",
|
|
54
|
+
"unknownGroupField%s%s": "Unknown group field '%s@%s'",
|
|
55
|
+
"grupFieldMustBeNumber": "Group field must be of type integer, smallint or float",
|
|
56
|
+
"unsupportedAggregateType%s": "Unsupported aggregate type: '%s'",
|
|
57
|
+
"keyIsRequired%s%s": "'%s@%s' key is required",
|
|
58
|
+
"fulltextNeedIntegerId%s%s": "Full text index need integer type primary id in '%s@%s'",
|
|
59
|
+
"unsupportedAggregate%s": "Unsupported aggregate '%s'",
|
|
60
|
+
"unsupportedAllowedChoices%s%s%s%s%s": "Unsupported %s '%s' for '%s@%s'. Allowed choices: %s",
|
|
61
|
+
"methodIsDisabled%s%sMethod": "Metode '%s@%s' dinonaktifkan",
|
|
62
|
+
"invalidModelForPersistence%s": "Model untuk penyimpanan tidak valid: %s",
|
|
63
|
+
"cantLoad%s%s": "Tidak bisa memuat %s: %s",
|
|
64
|
+
"noRecordFound": "Tidak ditemukan data",
|
|
65
|
+
"recordsFound%d": "Ditemukan %d data",
|
|
66
|
+
"add": "Tambah",
|
|
67
|
+
"edit": "Ubah",
|
|
68
|
+
"delete": "Hapus",
|
|
69
|
+
"export": "Ekspor",
|
|
70
|
+
"query": "Kueri",
|
|
71
|
+
"queryBuilder": "Pembuat Kueri",
|
|
72
|
+
"list": "Daftar",
|
|
73
|
+
"submitQuery": "Kirim Kueri",
|
|
74
|
+
"dataExport": "Ekspor Data",
|
|
75
|
+
"recordCreated": "Record successfully created",
|
|
76
|
+
"recordRemoved": "Record successfully removed",
|
|
77
|
+
"recordUpdated": "Record successfully updated",
|
|
78
|
+
"attachmentUploaded": "Attachment successfully uploaded",
|
|
79
|
+
"attachmentRemoved": "Attachment successfully removed",
|
|
80
|
+
"unknownModelSchema%s": "Unknown model/schema '%s'",
|
|
81
|
+
"sortOnUnindexedField%s%s": "Sort on unindexed field: '%s@%s'",
|
|
82
|
+
"modelNotExists%s": "Model '%s' doesn't exist yet. Please do model rebuild first",
|
|
83
|
+
"invalidDate": "Invalid date",
|
|
84
|
+
"histogramTypeMusBe%s": "Histogram type must be one of these: %s",
|
|
85
|
+
"methodUnsupported%s%s": "Method '%s@%s' is unsupported",
|
|
86
|
+
"uniqueConstraintError": "Unique constraint error",
|
|
87
|
+
"taskMustHaveModel%s": "Task must have %s model",
|
|
88
|
+
"driverNotInstalled%s": "Problem with '%s' driver file. Not installed yet?",
|
|
89
|
+
"generalDbError": "General Database Error",
|
|
90
|
+
"dbConstrainError": "Database Constraint Error",
|
|
91
|
+
"onlySupportThese%s": "Only support one of these: %s",
|
|
92
|
+
"isMissing%s": "%s is missing",
|
|
93
|
+
"notFound%s": "No %s found!",
|
|
94
|
+
"clientInstanceNotConnected%s": "Client instance not connected '%s@%s'. Skipped!",
|
|
95
|
+
"proxiedConnBound%s": "'%s' is bound to a proxied connection, skipped!'",
|
|
96
|
+
"addingMemoryPersistenceIgnored": "'%s' is a memory persistence model. Adding records from fixture is ignored!",
|
|
97
|
+
"onlyOneConnType%s": "There could only be one connection type '%s'",
|
|
98
|
+
"mustValidDbType": "Connection must have a valid DB type",
|
|
99
|
+
"unsupportedDbType%s": "Unsupported DB type '%s'",
|
|
100
|
+
"driverMustProvideDbType": "A DB driver must provide at least one database type",
|
|
101
|
+
"driverMustHaveName": "A DB driver must have a driver name",
|
|
102
|
+
"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",
|
|
105
|
+
"unknownFeature%s%s": "'Unknown feature '%s@%s'",
|
|
106
|
+
"onlyAccepFields%s%s": "Only accept array of field names or single string of field name '%s@%s'",
|
|
107
|
+
"invalidFieldName%s%s": "Invalid field name '%s@%s'",
|
|
108
|
+
"error%s": "Error: %s",
|
|
109
|
+
"succeedFailSkip%d%d%d": "Done! Succeded: %d, failed: %s, skipped: %d",
|
|
110
|
+
"chooseConn": "Please choose a connection:",
|
|
111
|
+
"sureContinue": "Are you sure to continue?",
|
|
112
|
+
"loadingDbFeature": "Loading DB feature",
|
|
113
|
+
"totalLoadedFeatures%d": "Total loaded features: %d",
|
|
114
|
+
"loadingDbSchemas": "Loading DB schemas",
|
|
115
|
+
"addingFixtureToMemDb": "Adding fixture for memory database",
|
|
116
|
+
"recordsAdded%s%d%d": "%s: %d of %d records added",
|
|
117
|
+
"driverInstantiated%s%s": "- Driver '%s:%s' instantiated",
|
|
118
|
+
"field": {
|
|
119
|
+
"id": "ID",
|
|
120
|
+
"code": "Kode",
|
|
121
|
+
"name": "Nama",
|
|
122
|
+
"dt": "Tgl/Jam",
|
|
123
|
+
"createdAt": "Dibuat Pada",
|
|
124
|
+
"updatedAt": "Diubah Pada",
|
|
125
|
+
"title": "Judul",
|
|
126
|
+
"description": "Keterangan",
|
|
127
|
+
"subTitle": "Sub Judul",
|
|
128
|
+
"plugin": "Plugin",
|
|
129
|
+
"author": "Penulis",
|
|
130
|
+
"dir": "Direktori",
|
|
131
|
+
"file": "Berkas",
|
|
132
|
+
"meta": "Info Meta",
|
|
133
|
+
"level": "Tingkat",
|
|
134
|
+
"ref": "Referensi",
|
|
135
|
+
"section": "Bagian",
|
|
136
|
+
"asset": "Aset",
|
|
137
|
+
"category": "Kategori",
|
|
138
|
+
"categoryId": "ID Kategori",
|
|
139
|
+
"username": "Nama Pengguna",
|
|
140
|
+
"password": "Kata Sandi",
|
|
141
|
+
"password2": "Ulangi Kata Sandi",
|
|
142
|
+
"firstName": "Nama Depan",
|
|
143
|
+
"lastName": "Nama Belakang",
|
|
144
|
+
"address1": "Alamat 1",
|
|
145
|
+
"address2": "Alamat 2",
|
|
146
|
+
"city": "Nama Kota",
|
|
147
|
+
"zipCode": "Kode Pos",
|
|
148
|
+
"provinceState": "Propinsi",
|
|
149
|
+
"country": "Negara",
|
|
150
|
+
"phone": "Telepon",
|
|
151
|
+
"email": "Surel",
|
|
152
|
+
"key": "Kunci",
|
|
153
|
+
"status": "Status",
|
|
154
|
+
"orgName": "Organisasi",
|
|
155
|
+
"picName": "Nama PJ",
|
|
156
|
+
"picRole": "Peran PJ",
|
|
157
|
+
"picPhone": "Telpon PJ",
|
|
158
|
+
"picEmail": "Surel PJ",
|
|
159
|
+
"website": "Alamat Situs",
|
|
160
|
+
"alias": "Alias",
|
|
161
|
+
"twitter": "Twitter",
|
|
162
|
+
"instagram": "Instagram",
|
|
163
|
+
"linkedIn": "Linked In",
|
|
164
|
+
"facebook": "Faceboook",
|
|
165
|
+
"userId": "ID Pengguna",
|
|
166
|
+
"siteId": "ID Situs",
|
|
167
|
+
"theme": "Tema",
|
|
168
|
+
"token": "Token",
|
|
169
|
+
"field": "Field",
|
|
170
|
+
"agree": "Persetujuan",
|
|
171
|
+
"method": "Metode",
|
|
172
|
+
"masterId": "ID Master",
|
|
173
|
+
"details": "Detil",
|
|
174
|
+
"qty": "JML",
|
|
175
|
+
"link": "Tautan",
|
|
176
|
+
"amount": "Nilai",
|
|
177
|
+
"cycle": "Cycle",
|
|
178
|
+
"default": "Default"
|
|
179
|
+
},
|
|
180
|
+
"validationError": "Kesalahan Validasi",
|
|
181
|
+
"validation": {
|
|
182
|
+
"any": {
|
|
183
|
+
"required": "Harus diisi/dipilih",
|
|
184
|
+
"only": "Harus sesuai dengan {{ref}}"
|
|
185
|
+
},
|
|
186
|
+
"string": {
|
|
187
|
+
"alphanum": "Harus berupa alfa numerik karakter saja",
|
|
188
|
+
"base": "Harus berupa string",
|
|
189
|
+
"base64": "Harus berupa string base64 yang valid",
|
|
190
|
+
"creditCard": "Harus berupa nomor kartu kredit",
|
|
191
|
+
"dataUri": "Harus berupa string dataUri yang valid",
|
|
192
|
+
"domain": "Harus mengandung nama domain yang valid",
|
|
193
|
+
"email": "Harus berupa surel yang valid",
|
|
194
|
+
"empty": "Harus diisi/dipilih",
|
|
195
|
+
"guid": "Harus berupa GUID yang valid",
|
|
196
|
+
"hex": "Harus mengandung hexadesimal karakter yang valid saja",
|
|
197
|
+
"hexAlign": "Representasi hex yang terdekode harus byte aligned",
|
|
198
|
+
"hostname": "Harus berupa nama host yang valid",
|
|
199
|
+
"ip": "Harus berupa alamat ip yang valid dengan CIDR {{cidr}}",
|
|
200
|
+
"ipVersion": "Harus berupa alamat ip yang valid dengan versi {{version}} dan CIDR {{cidr}}",
|
|
201
|
+
"isoDate": "Harus dalam format ISO",
|
|
202
|
+
"isoDuration": "Harus berupa durasi ISO 8601 yang valid",
|
|
203
|
+
"length": "Panjang harus pas {{limit}} karakter",
|
|
204
|
+
"lowercase": "Hanya boleh mengandung huruf kecil saja",
|
|
205
|
+
"max": "Panjang karakter harus lebih kecil atau sama dengan {{limit}} karakter",
|
|
206
|
+
"min": "Panjang karakter harus setidaknya {{limit}} karakter",
|
|
207
|
+
"token": "Hanya boleh terdiri atas karakter alfanumerik dan garis bawah saja",
|
|
208
|
+
"trim": "Tidak boleh memiliki spasi didepan atau dibelakang",
|
|
209
|
+
"uri": "Harus berupa URI yang valid",
|
|
210
|
+
"uppercase": "Hanya boleh mengandung huruf besar saja"
|
|
211
|
+
},
|
|
212
|
+
"number": {
|
|
213
|
+
"base": "Harus berupa angka",
|
|
214
|
+
"greater": "Harus lebih besar dari {{limit}}",
|
|
215
|
+
"infinity": "Tidak bisa tak terbatas",
|
|
216
|
+
"integer": "Harus berupa integer",
|
|
217
|
+
"less": "Harus lebih kecil dari {{limit}}",
|
|
218
|
+
"max": "Harus lebih kecil atau sama dengan {{limit}}",
|
|
219
|
+
"min": "Harus lebih besar atau sama dengan {{limit}}",
|
|
220
|
+
"multiple": "Harus kelipatan dari {{multiple}}",
|
|
221
|
+
"negative": "Harus berupa angka negatif",
|
|
222
|
+
"port": "Harus berupa nomor port yang valid",
|
|
223
|
+
"positive": "Harus berupa angka positif",
|
|
224
|
+
"precision": "Harus memiliki tidak lebih dari {{limit}} tempat desimal",
|
|
225
|
+
"unsafe": "Harus berupa nomor yang aman"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -5,11 +5,11 @@ async function copyUploaded (name, id, { req, setField, setFile, mimeType, stats
|
|
|
5
5
|
name = this.attachmentPreCheck(name)
|
|
6
6
|
if (!name) {
|
|
7
7
|
if (silent) return
|
|
8
|
-
throw this.error('
|
|
8
|
+
throw this.error('isMissing%s', this.print.write('field.name'))
|
|
9
9
|
}
|
|
10
10
|
if (!this.bajoWeb) {
|
|
11
11
|
if (silent) return
|
|
12
|
-
throw this.error('
|
|
12
|
+
throw this.error('missingPlugin%s')
|
|
13
13
|
}
|
|
14
14
|
const { dir, files } = await this.bajoWeb.getUploadedFiles(req.id, false, true)
|
|
15
15
|
const result = []
|
|
@@ -5,7 +5,7 @@ async function create (name, id, options = {}) {
|
|
|
5
5
|
name = this.attachmentPreCheck(name)
|
|
6
6
|
if (!name) return
|
|
7
7
|
const { source, field, file } = options
|
|
8
|
-
if (!source) throw this.error('
|
|
8
|
+
if (!source) throw this.error('isMissing%s', this.print.write('field.source'))
|
|
9
9
|
const baseDir = await this.attachmentGetPath(name, id, field, file, { dirOnly: true })
|
|
10
10
|
const { fullPath, stats, mimeType, req } = options
|
|
11
11
|
|
|
@@ -20,7 +20,7 @@ async function create (name, id, options = {}) {
|
|
|
20
20
|
file
|
|
21
21
|
}
|
|
22
22
|
await mergeAttachmentInfo.call(this, rec, dest, { mimeType, fullPath, stats })
|
|
23
|
-
if (req && req.flash) req.flash('notify', req.t('
|
|
23
|
+
if (req && req.flash) req.flash('notify', req.t('attachmentUploaded'))
|
|
24
24
|
return rec
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -5,7 +5,7 @@ async function remove (name, id, field, file, options = {}) {
|
|
|
5
5
|
const path = await this.attachmentGetPath(name, id, field, file)
|
|
6
6
|
const { req } = options
|
|
7
7
|
await fs.remove(path)
|
|
8
|
-
if (req && req.flash) req.flash('notify', req.t('
|
|
8
|
+
if (req && req.flash) req.flash('notify', req.t('attachmentRemoved'))
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export default remove
|
|
@@ -3,7 +3,7 @@ function getSchema (input, cloned = true) {
|
|
|
3
3
|
let name = isPlainObject(input) ? input.name : input
|
|
4
4
|
name = this.app.bajo.pascalCase(name)
|
|
5
5
|
const schema = find(this.schemas, { name })
|
|
6
|
-
if (!schema) throw this.error('
|
|
6
|
+
if (!schema) throw this.error('unknownModelSchema%s', name)
|
|
7
7
|
return cloned ? cloneDeep(schema) : schema
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ async function exists (name, thrown, options = {}) {
|
|
|
16
16
|
await runHook(`${this.name}.${camelCase(name)}:afterModelExists`, exist, options)
|
|
17
17
|
await runHook(`${this.name}:afterModelExists`, schema, exist, options)
|
|
18
18
|
}
|
|
19
|
-
if (!exist && thrown) throw this.error('
|
|
19
|
+
if (!exist && thrown) throw this.error('modelNotExists%s')
|
|
20
20
|
cache[name] = exist
|
|
21
21
|
return exist
|
|
22
22
|
}
|
|
@@ -42,7 +42,7 @@ function buildSort (input, schema, allowSortUnindexed) {
|
|
|
42
42
|
if (schema) {
|
|
43
43
|
const items = keys(sort)
|
|
44
44
|
each(items, i => {
|
|
45
|
-
if (!schema.sortables.includes(i) && !allowSortUnindexed) throw this.error('
|
|
45
|
+
if (!schema.sortables.includes(i) && !allowSortUnindexed) throw this.error('sortOnUnindexedField%s%s', i, schema.name)
|
|
46
46
|
// if (schema.fullText.fields.includes(i)) throw this.error('Can\'t sort on full-text index: \'%s@%s\'', i, schema.name)
|
|
47
47
|
})
|
|
48
48
|
}
|
|
@@ -50,7 +50,7 @@ async function create (name, input, opts = {}) {
|
|
|
50
50
|
record = await handler.call(this.app[driver.ns], { schema, body: nbody, options })
|
|
51
51
|
if (options.req) {
|
|
52
52
|
if (options.req.file) await handleAttachmentUpload.call(this, { name: schema.name, id: body.id, body, options, action: 'create' })
|
|
53
|
-
if (options.req.flash && !options.noFlash) options.req.flash('notify', options.req.t('
|
|
53
|
+
if (options.req.flash && !options.noFlash) options.req.flash('notify', options.req.t('recordCreated'))
|
|
54
54
|
}
|
|
55
55
|
if (!noFeatureHook) await execFeatureHook.call(this, 'afterCreate', { schema, body, record })
|
|
56
56
|
if (!noHook) {
|
|
@@ -20,7 +20,7 @@ async function remove (name, id, opts = {}) {
|
|
|
20
20
|
const record = await handler.call(this.app[driver.ns], { schema, id, options })
|
|
21
21
|
if (options.req) {
|
|
22
22
|
if (options.req.file) await handleAttachmentUpload.call(this, { name: schema.name, id, options, action: 'remove' })
|
|
23
|
-
if (options.req.flash && !options.noFlash) options.req.flash('notify', options.req.t('
|
|
23
|
+
if (options.req.flash && !options.noFlash) options.req.flash('notify', options.req.t('recordRemoved'))
|
|
24
24
|
}
|
|
25
25
|
if (!noHook) {
|
|
26
26
|
await runHook(`${this.name}.${camelCase(name)}:afterRecordRemove`, id, options, record)
|
|
@@ -40,7 +40,7 @@ async function update (name, id, input, opts = {}) {
|
|
|
40
40
|
const record = await handler.call(this.app[driver.ns], { schema, id, body: nbody, options })
|
|
41
41
|
if (options.req) {
|
|
42
42
|
if (options.req.file) await handleAttachmentUpload.call(this, { name: schema.name, id, body, options, action: 'update' })
|
|
43
|
-
if (options.req.flash && !options.noFlash) options.req.flash('notify', options.req.t('
|
|
43
|
+
if (options.req.flash && !options.noFlash) options.req.flash('notify', options.req.t('recordUpdated'))
|
|
44
44
|
}
|
|
45
45
|
if (!noFeatureHook) await execFeatureHook.call(this, 'afterUpdate', { schema, body: nbody, record })
|
|
46
46
|
if (!noHook) {
|
|
@@ -5,7 +5,7 @@ function sanitizeDate (value, { input, output, silent = true } = {}) {
|
|
|
5
5
|
const dt = dayjs(value, input)
|
|
6
6
|
if (!dt.isValid()) {
|
|
7
7
|
if (silent) return -1
|
|
8
|
-
throw this.error('
|
|
8
|
+
throw this.error('invalidDate')
|
|
9
9
|
}
|
|
10
10
|
if (output === 'native' || !output) return dt.toDate()
|
|
11
11
|
return dt.format(output)
|
|
@@ -6,7 +6,7 @@ async function histogram (name, filter = {}, options = {}) {
|
|
|
6
6
|
const { runHook, join } = this.app.bajo
|
|
7
7
|
const { dataOnly = true, noHook, type } = options
|
|
8
8
|
options.dataOnly = false
|
|
9
|
-
if (!types.includes(type)) throw this.error('
|
|
9
|
+
if (!types.includes(type)) throw this.error('histogramTypeMusBe%s', join(types))
|
|
10
10
|
await this.modelExists(name, true)
|
|
11
11
|
const { handler, schema, driver } = await resolveMethod.call(this, name, 'stat-histogram', options)
|
|
12
12
|
filter.query = await this.buildQuery({ filter, schema, options }) ?? {}
|
package/bajo/method/validate.js
CHANGED
|
@@ -150,7 +150,7 @@ async function validate (value, joiSchema, { ns, fields, extFields, params } = {
|
|
|
150
150
|
try {
|
|
151
151
|
return await joiSchema.validateAsync(value, params)
|
|
152
152
|
} catch (err) {
|
|
153
|
-
throw this.error('
|
|
153
|
+
throw this.error('validationError', { details: err.details, values: err.values, ns, statusCode: 422, code: 'DB_VALIDATION' })
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
package/bajo/start.js
CHANGED
|
@@ -12,7 +12,7 @@ async function start (conns = 'all', noRebuild = true) {
|
|
|
12
12
|
const schemas = filter(this.schemas, { connection: c.name })
|
|
13
13
|
const mod = c.type === 'dobo:memory' ? memDbInstantiate : await importModule(`${ns}:/${this.name}/boot/instantiate.js`)
|
|
14
14
|
await mod.call(this.app[ns], { connection: c, noRebuild, schemas })
|
|
15
|
-
this.log.trace('
|
|
15
|
+
this.log.trace('driverInstantiated%s%s', c.driver, c.name)
|
|
16
16
|
}
|
|
17
17
|
await memDbStart.call(this)
|
|
18
18
|
}
|
|
@@ -4,18 +4,18 @@ async function connection (path, ...args) {
|
|
|
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('
|
|
7
|
+
if (isEmpty(this.connections)) return this.print.fail('notFound%s', 'connection', { exit: this.app.bajo.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('
|
|
12
|
+
message: this.print.write('chooseConn'),
|
|
13
13
|
choices
|
|
14
14
|
})
|
|
15
15
|
}
|
|
16
16
|
const result = find(this.connections, { name })
|
|
17
|
-
if (!result) return this.print.fail('
|
|
18
|
-
this.print.info('
|
|
17
|
+
if (!result) return this.print.fail('cantFind%s%s', this.print.write('connection'), name, { exit: this.app.bajo.applet })
|
|
18
|
+
this.print.info('done')
|
|
19
19
|
await writeOutput(result, path, format)
|
|
20
20
|
}
|
|
21
21
|
|