bajo 1.0.4 → 1.0.6
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/intl/en-US.json +147 -0
- package/bajo/intl/id.json +147 -0
- package/boot/class/app.js +1 -2
- package/boot/class/bajo-core/helper/attach-method.js +1 -1
- package/boot/class/bajo-core/helper/boot-order.js +3 -3
- package/boot/class/bajo-core/helper/build-config.js +16 -2
- package/boot/class/bajo-core/helper/exit-handler.js +3 -3
- package/boot/class/bajo-core/helper/run-as-applet.js +4 -4
- package/boot/class/bajo-core/method/break-ns-path.js +1 -1
- package/boot/class/bajo-core/method/build-collections.js +4 -4
- package/boot/class/bajo-core/method/envs.js +1 -1
- package/boot/class/bajo-core/method/format.js +36 -0
- package/boot/class/bajo-core/method/get-global-module-dir.js +2 -2
- package/boot/class/bajo-core/method/get-method.js +1 -1
- package/boot/class/bajo-core/method/get-plugin.js +1 -1
- package/boot/class/bajo-core/method/import-pkg.js +1 -1
- package/boot/class/bajo-core/method/parse-object.js +8 -6
- package/boot/class/bajo-core/method/read-config.js +3 -3
- package/boot/class/bajo-core/method/read-json.js +1 -1
- package/boot/class/bajo-core/method/run-hook.js +1 -1
- package/boot/class/bajo-core/method/save-as-download.js +1 -1
- package/boot/class/bajo-plugin/helper/attach-method.js +1 -1
- package/boot/class/bajo-plugin/helper/build-config.js +5 -2
- package/boot/class/bajo-plugin/helper/check-clash.js +3 -3
- package/boot/class/bajo-plugin/helper/check-dependency.js +3 -3
- package/boot/class/bajo-plugin/helper/collect-exit-handlers.js +1 -1
- package/boot/class/bajo-plugin/helper/collect-hooks.js +1 -1
- package/boot/class/bajo-plugin/helper/run.js +1 -1
- package/boot/class/bajo-plugin.js +5 -4
- package/boot/class/error.js +1 -1
- package/boot/class/log.js +2 -3
- package/boot/class/plugin.js +2 -1
- package/boot/class/print.js +51 -6
- package/boot/lib/read-all-configs.js +2 -2
- package/package.json +1 -1
- package/bajoI18N/resource/id.json +0 -31
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packageNotFoundOrNotBajo%s": "Package '%s' not found or isn't a valid Bajo package",
|
|
3
|
+
"unknownPluginOrNotLoaded%s": "Unknown plugin '%s' or plugin isn't loaded yet",
|
|
4
|
+
"collExists%s": "Collection '%s' already exists",
|
|
5
|
+
"cantLocateNpmGlobalDir": "Can't locate npm global module directory",
|
|
6
|
+
"cantLocateGlobalDir%s": "Can't locate '%s' global module directory",
|
|
7
|
+
"cantFindMethod%s": "Can't find method named '%s'",
|
|
8
|
+
"pluginWithALiasNotLoaded%s": "Plugin with alias '%s' is not loaded",
|
|
9
|
+
"cantFind%s": "Can't find %s",
|
|
10
|
+
"dtUnparsable%s": "Date/time unparsable '%s'",
|
|
11
|
+
"cantParse%s": "'Can't parse '%s'",
|
|
12
|
+
"noConfigFileFound": "No config file found",
|
|
13
|
+
"pluginNameClash%s%s%s%s": "Plugin name clash: '%s (%s)' with '%s (%s)'",
|
|
14
|
+
"dependencyUnfulfilled%s%s": "Dependency for '%s' unfulfilled: %s",
|
|
15
|
+
"semverCheckFailed%s%s": "Semver check '%s' against '%s' failed",
|
|
16
|
+
"ddirNotExists%s": "Data directory '%s' doesn't exists!",
|
|
17
|
+
"signalReceived%s": "'%s' signal received",
|
|
18
|
+
"noAppletLoaded": "No applets loaded. Aborted!",
|
|
19
|
+
"oneOrMoreSharedTheSame%s%s": "One or more %s shared the same '%s'",
|
|
20
|
+
"bootCompleted%s": "Boot process completed in %s",
|
|
21
|
+
"runInEnv%s": "Run in '%s' environment",
|
|
22
|
+
"appRunningAsApplet": "App is running as applet...",
|
|
23
|
+
"setupBootOrder": "Setup boot order",
|
|
24
|
+
"configHandlers%s": "Config handlers: %s",
|
|
25
|
+
"exited": "Exited",
|
|
26
|
+
"appShutdown": "App shutdown",
|
|
27
|
+
"appletModeActivated": "Applet mode activated",
|
|
28
|
+
"collected%s%d": "%s collected: %d",
|
|
29
|
+
"attachMethods": "Attach methods",
|
|
30
|
+
"readConfigs": "Read configurations",
|
|
31
|
+
"checkAliasNameClash": "Checking alias & name clashes",
|
|
32
|
+
"checkDeps": "Checking dependencies",
|
|
33
|
+
"collectHooks": "Collect hooks",
|
|
34
|
+
"loadedPlugins%s": "Loaded plugins: %s",
|
|
35
|
+
"collecting%s": "Collecting %s",
|
|
36
|
+
"hookExecuted%s": "Hook '%s' executed",
|
|
37
|
+
"exitHandlers%s": "Exit handlers: %s",
|
|
38
|
+
"savedAs%s": "Saved as '%s'",
|
|
39
|
+
"aborted": "Aborted",
|
|
40
|
+
"done": "Done",
|
|
41
|
+
"error": "Error",
|
|
42
|
+
"language": "Language",
|
|
43
|
+
"langEnUs": "American English",
|
|
44
|
+
"langId": "Indonesian",
|
|
45
|
+
"gotoHome": "Goto Home",
|
|
46
|
+
"copyClipboard": "Copy to Clipboard",
|
|
47
|
+
"clear": "Clear",
|
|
48
|
+
"close": "Close",
|
|
49
|
+
"image": "Image",
|
|
50
|
+
"reset": "Reset",
|
|
51
|
+
"submit": "Submit",
|
|
52
|
+
"upload": "Upload",
|
|
53
|
+
"home": "Home",
|
|
54
|
+
"smallL": "small",
|
|
55
|
+
"mediumL": "medium",
|
|
56
|
+
"largeL": "large",
|
|
57
|
+
"sunday": "Sunday",
|
|
58
|
+
"monday": "Monday",
|
|
59
|
+
"tuesday": "Tuesday",
|
|
60
|
+
"wednesday": "Wednesday",
|
|
61
|
+
"thursday": "Thursday",
|
|
62
|
+
"friday": "Friday",
|
|
63
|
+
"saturday": "Saturday",
|
|
64
|
+
"sun": "Sun",
|
|
65
|
+
"mon": "Mon",
|
|
66
|
+
"tue": "Tue",
|
|
67
|
+
"wed": "Wed",
|
|
68
|
+
"thu": "Thu",
|
|
69
|
+
"fri": "Fri",
|
|
70
|
+
"sat": "Sat",
|
|
71
|
+
"back": "Back",
|
|
72
|
+
"forward": "Forward",
|
|
73
|
+
"weekends": "Weekends",
|
|
74
|
+
"workingDays": "Working Days",
|
|
75
|
+
"search": "Search",
|
|
76
|
+
"prev": "Prev",
|
|
77
|
+
"next": "Next",
|
|
78
|
+
"large": "Large",
|
|
79
|
+
"small": "Small",
|
|
80
|
+
"center": "Center",
|
|
81
|
+
"height": "Height",
|
|
82
|
+
"source": "Source",
|
|
83
|
+
"ok": "OK",
|
|
84
|
+
"cancel": "Cancel",
|
|
85
|
+
"information": "Information",
|
|
86
|
+
"warning": "Warning",
|
|
87
|
+
"danger": "Danger",
|
|
88
|
+
"apply": "Apply",
|
|
89
|
+
"options": "Options",
|
|
90
|
+
"confirmation": "Confirmation",
|
|
91
|
+
"statistics": "Statistics",
|
|
92
|
+
"general": "General",
|
|
93
|
+
"meta": "Meta",
|
|
94
|
+
"copied": "Copied",
|
|
95
|
+
"name": "Name",
|
|
96
|
+
"role": "Role",
|
|
97
|
+
"phone": "Phone",
|
|
98
|
+
"secondL": "second",
|
|
99
|
+
"minuteL": "minute",
|
|
100
|
+
"hourL": "hour",
|
|
101
|
+
"dayL": "day",
|
|
102
|
+
"monthL": "month",
|
|
103
|
+
"yearL": "year",
|
|
104
|
+
"second": "Second",
|
|
105
|
+
"minute": "Minute",
|
|
106
|
+
"hour": "Hour",
|
|
107
|
+
"day": "Day",
|
|
108
|
+
"month": "Month",
|
|
109
|
+
"year": "Year",
|
|
110
|
+
"description": "Description",
|
|
111
|
+
"dashboard": "Dashboard",
|
|
112
|
+
"task": "Task",
|
|
113
|
+
"allRightsReserved": "All rights reserved",
|
|
114
|
+
"date": "Date",
|
|
115
|
+
"status": "Status",
|
|
116
|
+
"missingPlugin%s": "Plugin '%s' is missing",
|
|
117
|
+
"unknownParser%s": "Unknown parser '%s'",
|
|
118
|
+
"unknownConn%s": "Unknown connection %s",
|
|
119
|
+
"connIs%s%s": "Connection '%s' is %s",
|
|
120
|
+
"connError%s%s": "Connection '%s' error: %s",
|
|
121
|
+
"closedL": "closed",
|
|
122
|
+
"openedL": "opened",
|
|
123
|
+
"connectedL": "connected",
|
|
124
|
+
"disconnectedL": "disconnected",
|
|
125
|
+
"endedL": "ended",
|
|
126
|
+
"offlineL": "offline",
|
|
127
|
+
"reconnectingL": "reconnecting",
|
|
128
|
+
"connMustHave%s": "Connection must have '%s'",
|
|
129
|
+
"notFound%s%s": "%s '%s' not found",
|
|
130
|
+
"connection": "Connection",
|
|
131
|
+
"file": "File",
|
|
132
|
+
"applet": "Applet",
|
|
133
|
+
"unsupported%s%s": "Unsupported %s '%s'",
|
|
134
|
+
"error%": "Error: %s",
|
|
135
|
+
"savedAs%%": "%s saved as '%s'",
|
|
136
|
+
"loaded%s": "Loaded %s",
|
|
137
|
+
"production": "production",
|
|
138
|
+
"staging": "staging",
|
|
139
|
+
"development": "development",
|
|
140
|
+
"unsupportedLangFallbackTo%s": "Unsupported language, fallback to '%s'",
|
|
141
|
+
"plugin%s": "%s plugin...",
|
|
142
|
+
"init": "Init",
|
|
143
|
+
"start": "Start",
|
|
144
|
+
"stop": "Stop",
|
|
145
|
+
"supportDisabled%s": "%s support is disabled",
|
|
146
|
+
"collect%s": "Collect %s"
|
|
147
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packageNotFoundOrNotBajo%s": "Paket '%s' tidak ditemukan atau bukan sebuah paket Bajo yang valid",
|
|
3
|
+
"unknownPluginOrNotLoaded%s": "Plugin '%s' tidak dikenal atau plugin belum termuat",
|
|
4
|
+
"collExists%s": "Koleksi '%s' sudah ada",
|
|
5
|
+
"cantLocateNpmGlobalDir": "Tidak bisa menentukan direktori global npm",
|
|
6
|
+
"cantLocateGlobalDir%s": "Tidak bisa menentukan direktori global modul '%s'",
|
|
7
|
+
"cantFindMethod%s": "Tidak menemukan metode dengan nama '%s'",
|
|
8
|
+
"pluginWithALiasNotLoaded%s": "Plugin dengan alias '%s' tidak termuat",
|
|
9
|
+
"cantFind%s": "Tidak bisa menemukan %s",
|
|
10
|
+
"dtUnparsable%s": "Tanggal/waktu tidak bisa di parsing '%s'",
|
|
11
|
+
"cantParse%s": "'Tidak bisa memparsing '%s'",
|
|
12
|
+
"noConfigFileFound": "Tidak ditemukan berkas konfigurasi satupun",
|
|
13
|
+
"pluginNameClash%s%s%s%s": "Bentrokan nama plugin: '%s (%s)' dengan '%s (%s)'",
|
|
14
|
+
"dependencyUnfulfilled%s%s": "Ketergantungan untuk '%s' tidak terpenuhi: %s",
|
|
15
|
+
"semverCheckFailed%s%s": "Cek Semver '%s' terhadap '%s' gagal",
|
|
16
|
+
"ddirNotExists%s": "Direktori data '%s' tidak ada!",
|
|
17
|
+
"signalReceived%s": "Sinyal '%s' diterima",
|
|
18
|
+
"noAppletLoaded": "Tidak ada applet yang termuat. Batalkan!",
|
|
19
|
+
"oneOrMoreSharedTheSame%s%s": "Satu atau lebih %s berbagi '%s'",
|
|
20
|
+
"bootCompleted%s": "Proses booting komplit dalam %s",
|
|
21
|
+
"runInEnv%s": "Berjalan di lingkungan '%s'",
|
|
22
|
+
"appRunningAsApplet": "App berjalan sebagai applet...",
|
|
23
|
+
"setupBootOrder": "Atur urutan booting",
|
|
24
|
+
"configHandlers%s": "Pengatur konfigurasi: %s",
|
|
25
|
+
"exited": "Exited",
|
|
26
|
+
"appShutdown": "Aplikasi ditutup",
|
|
27
|
+
"appletModeActivated": "Mode applet diaktifkan",
|
|
28
|
+
"collected%s%d": "%s terkoleksi: %d",
|
|
29
|
+
"attachMethods": "Tempelkan metode",
|
|
30
|
+
"readConfigs": "Baca konfigurasi",
|
|
31
|
+
"checkAliasNameClash": "Cek bentrokan nama dan alias",
|
|
32
|
+
"checkDeps": "Cek ketergantungan",
|
|
33
|
+
"collectHooks": "Kumpulkan Hooks",
|
|
34
|
+
"loadedPlugins%s": "Plugin termuat: %s",
|
|
35
|
+
"collecting%s": "Mengumpulkan %s",
|
|
36
|
+
"hookExecuted%s": "Hook '%s' dieksekusi",
|
|
37
|
+
"exitHandlers%s": "Penanganan keluar: %s",
|
|
38
|
+
"savedAs%s": "Simpan sbg '%s'",
|
|
39
|
+
"aborted": "Dibatalkan",
|
|
40
|
+
"done": "Selesai",
|
|
41
|
+
"error": "Kesalahan",
|
|
42
|
+
"language": "Bahasa",
|
|
43
|
+
"langEnUs": "Bahasa Inggris Amerika",
|
|
44
|
+
"langId": "Bahasa Indonesia",
|
|
45
|
+
"gotoHome": "Ke Beranda",
|
|
46
|
+
"copyClipboard": "Kopi ke Papan Tempel",
|
|
47
|
+
"clear": "Bersihkan",
|
|
48
|
+
"close": "Tutup",
|
|
49
|
+
"image": "Gambar",
|
|
50
|
+
"reset": "Reset",
|
|
51
|
+
"submit": "Kirim",
|
|
52
|
+
"upload": "Unggah",
|
|
53
|
+
"home": "Beranda",
|
|
54
|
+
"smallL": "kecil",
|
|
55
|
+
"mediumL": "menengah",
|
|
56
|
+
"largeL": "besar",
|
|
57
|
+
"sunday": "Minggu",
|
|
58
|
+
"monday": "Senin",
|
|
59
|
+
"tuesday": "Selasa",
|
|
60
|
+
"wednesday": "Rabu",
|
|
61
|
+
"thursday": "Kamis",
|
|
62
|
+
"friday": "Jumat",
|
|
63
|
+
"saturday": "Sabtu",
|
|
64
|
+
"sun": "Min",
|
|
65
|
+
"mon": "Sen",
|
|
66
|
+
"tue": "Sel",
|
|
67
|
+
"wed": "Rab",
|
|
68
|
+
"thu": "Kam",
|
|
69
|
+
"fri": "Jum",
|
|
70
|
+
"sat": "Sab",
|
|
71
|
+
"back": "Kembali",
|
|
72
|
+
"forward": "Maju",
|
|
73
|
+
"weekends": "Akhir Minggu",
|
|
74
|
+
"workingDays": "Hari Kerja",
|
|
75
|
+
"search": "Cari",
|
|
76
|
+
"prev": "Sebelumnya",
|
|
77
|
+
"next": "Berikutnya",
|
|
78
|
+
"large": "Besar",
|
|
79
|
+
"small": "Kecil",
|
|
80
|
+
"center": "Tengah",
|
|
81
|
+
"height": "Tinggi",
|
|
82
|
+
"source": "Sumber",
|
|
83
|
+
"ok": "Oke",
|
|
84
|
+
"cancel": "Batal",
|
|
85
|
+
"information": "Informasi",
|
|
86
|
+
"warning": "Perhatian",
|
|
87
|
+
"danger": "Bahaya",
|
|
88
|
+
"apply": "Terapkan",
|
|
89
|
+
"options": "Opsi-opsi",
|
|
90
|
+
"confirmation": "Konfirmasi",
|
|
91
|
+
"statistics": "Statistik",
|
|
92
|
+
"general": "Umum",
|
|
93
|
+
"meta": "Meta",
|
|
94
|
+
"copied": "Tertempel!",
|
|
95
|
+
"name": "Nama",
|
|
96
|
+
"role": "Peran",
|
|
97
|
+
"phone": "Telpon",
|
|
98
|
+
"secondL": "detik",
|
|
99
|
+
"minuteL": "menit",
|
|
100
|
+
"hourL": "jam",
|
|
101
|
+
"dayL": "hari",
|
|
102
|
+
"monthL": "bulan",
|
|
103
|
+
"yearL": "tahun",
|
|
104
|
+
"second": "Detik",
|
|
105
|
+
"minute": "Menit",
|
|
106
|
+
"hour": "Jam",
|
|
107
|
+
"day": "Hari",
|
|
108
|
+
"month": "Bulan",
|
|
109
|
+
"year": "Tahun",
|
|
110
|
+
"description": "Keterangan",
|
|
111
|
+
"dashboard": "Dasbor",
|
|
112
|
+
"task": "Pekerjaan",
|
|
113
|
+
"allRightsReserved": "Hak cipta dilindungi Undang-undang",
|
|
114
|
+
"date": "Tanggal",
|
|
115
|
+
"status": "Status",
|
|
116
|
+
"missingPlugin%s": "Plugin '%s' tidak ditemukan",
|
|
117
|
+
"unknownParser%s": "Parser tak dikenal '%s'",
|
|
118
|
+
"unknownConn%s": "Koneksi tak dikenal '%s'",
|
|
119
|
+
"connIs%s%s": "Koneksi '%s' %s",
|
|
120
|
+
"connError%s%s": "Koneksi '%s' ada kesalahan: %s",
|
|
121
|
+
"closedL": "tertutup",
|
|
122
|
+
"openedL": "terbuka",
|
|
123
|
+
"connectedL": "terhubung",
|
|
124
|
+
"disconnectedL": "terputus",
|
|
125
|
+
"endedL": "berhenti",
|
|
126
|
+
"offlineL": "offline",
|
|
127
|
+
"reconnectingL": "mencoba menghubung kembali",
|
|
128
|
+
"connMustHave%s": "Koneksi harus memiliki '%s'",
|
|
129
|
+
"notFound%s%s": "%s '%s' tidak ditemukan",
|
|
130
|
+
"connection": "Koneksi",
|
|
131
|
+
"file": "Berkas",
|
|
132
|
+
"applet": "Applet",
|
|
133
|
+
"unsupported%s%s": "%s '%s' tidak didukung",
|
|
134
|
+
"error%": "Kesalahan: %s",
|
|
135
|
+
"savedAs%%": "%s disimpan sbg '%s'",
|
|
136
|
+
"loaded%s": "%s termuat",
|
|
137
|
+
"production": "produksi",
|
|
138
|
+
"staging": "pemanggungan",
|
|
139
|
+
"development": "pengembangan",
|
|
140
|
+
"unsupportedLangFallbackTo%s": "Bahasa tidak didukung, gunakan '%s'",
|
|
141
|
+
"plugin%s": "%s plugin...",
|
|
142
|
+
"init": "Inisiasi",
|
|
143
|
+
"start": "Jalankan",
|
|
144
|
+
"stop": "Berhentikan",
|
|
145
|
+
"supportDisabled%s": "Dukungan %s dimatikan",
|
|
146
|
+
"collect%s": "Koleksi %s"
|
|
147
|
+
}
|
package/boot/class/app.js
CHANGED
|
@@ -31,7 +31,6 @@ class App {
|
|
|
31
31
|
addPlugin (plugin) {
|
|
32
32
|
if (this[plugin.name]) throw new Error(`Plugin '${plugin.name}' added already`)
|
|
33
33
|
this[plugin.name] = plugin
|
|
34
|
-
plugin.initPrint()
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
dump (...args) {
|
|
@@ -63,7 +62,7 @@ class App {
|
|
|
63
62
|
// boot complete
|
|
64
63
|
await bajo.runHook('bajo:bootComplete')
|
|
65
64
|
const elapsed = new Date() - bajo.runAt
|
|
66
|
-
bajo.log.info('
|
|
65
|
+
bajo.log.info('bootCompleted%s', bajo.secToHms(elapsed, true))
|
|
67
66
|
if (bajo.applet) await runAsApplet.call(bajo)
|
|
68
67
|
}
|
|
69
68
|
}
|
|
@@ -5,7 +5,7 @@ import getModuleDir from '../method/get-module-dir.js'
|
|
|
5
5
|
const { reduce, map, isNaN, trim, forOwn, orderBy } = lodash
|
|
6
6
|
|
|
7
7
|
async function bootOrder () {
|
|
8
|
-
this.log.debug('
|
|
8
|
+
this.log.debug('setupBootOrder')
|
|
9
9
|
const order = reduce(this.pluginPkgs, (o, k, i) => {
|
|
10
10
|
const key = map(k.split(':'), m => trim(m))
|
|
11
11
|
if (key[1] && !isNaN(Number(key[1]))) o[key[0]] = Number(key[1])
|
|
@@ -16,7 +16,7 @@ async function bootOrder () {
|
|
|
16
16
|
for (let n of this.pluginPkgs) {
|
|
17
17
|
n = map(n.split(':'), m => trim(m))[0]
|
|
18
18
|
const dir = n === this.mainNs ? (`${this.dir.base}/${this.mainNs}`) : getModuleDir(n)
|
|
19
|
-
if (n !== this.mainNs && !fs.existsSync(`${dir}/bajo`)) throw this.error('
|
|
19
|
+
if (n !== this.mainNs && !fs.existsSync(`${dir}/bajo`)) throw this.error('packageNotFoundOrNotBajo%s', n)
|
|
20
20
|
norder[n] = NaN
|
|
21
21
|
try {
|
|
22
22
|
norder[n] = Number(trim(await fs.readFile(`${dir}/bajo/.bootorder`, 'utf8')))
|
|
@@ -28,7 +28,7 @@ async function bootOrder () {
|
|
|
28
28
|
result.push(item)
|
|
29
29
|
})
|
|
30
30
|
this.pluginPkgs = map(orderBy(result, ['v']), 'k')
|
|
31
|
-
this.log.info('
|
|
31
|
+
this.log.info('runInEnv%s', this.print.write(this.envs[this.config.env]))
|
|
32
32
|
// misc
|
|
33
33
|
this.freeze(this.config)
|
|
34
34
|
}
|
|
@@ -21,6 +21,19 @@ const defConfig = {
|
|
|
21
21
|
traceHook: false
|
|
22
22
|
},
|
|
23
23
|
lang: Intl.DateTimeFormat().resolvedOptions().lang ?? 'en-US',
|
|
24
|
+
intl: {
|
|
25
|
+
supported: ['en-US', 'id'],
|
|
26
|
+
fallback: 'en-US',
|
|
27
|
+
lookupOrder: [],
|
|
28
|
+
format: {
|
|
29
|
+
emptyValue: '',
|
|
30
|
+
datetime: { dateStyle: 'medium', 'timeStyle': 'short' },
|
|
31
|
+
date: { dateStyle: 'medium' },
|
|
32
|
+
time: { timeStyle: 'short' },
|
|
33
|
+
float: { maximumFractionDigits: 2 },
|
|
34
|
+
integer: {}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
24
37
|
exitHandler: true
|
|
25
38
|
}
|
|
26
39
|
|
|
@@ -57,6 +70,7 @@ export async function buildExtConfig () {
|
|
|
57
70
|
this.config.exitHandler = false
|
|
58
71
|
}
|
|
59
72
|
const exts = map(this.configHandlers, 'ext')
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
73
|
+
this.initPrint()
|
|
74
|
+
this.initLog()
|
|
75
|
+
this.log.debug('configHandlers%s', join(exts))
|
|
62
76
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
async function exit (signal) {
|
|
2
2
|
const { eachPlugins } = this
|
|
3
|
-
this.log.warn('
|
|
3
|
+
this.log.warn('signalReceived%s', signal)
|
|
4
4
|
await eachPlugins(async function ({ ns }) {
|
|
5
5
|
const handler = this.exitHandler
|
|
6
6
|
if (!handler) return undefined
|
|
7
7
|
try {
|
|
8
8
|
await handler.call(this)
|
|
9
9
|
} catch (err) {}
|
|
10
|
-
this.log.debug('
|
|
10
|
+
this.log.debug('exited')
|
|
11
11
|
})
|
|
12
|
-
this.log.debug('
|
|
12
|
+
this.log.debug('appShutdown')
|
|
13
13
|
process.exit(0)
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -4,9 +4,9 @@ async function runAsApplet () {
|
|
|
4
4
|
this.app.bajo.applets.push({ ns, file, alias })
|
|
5
5
|
}, { glob: 'applet.js', prefix: 'bajoCli' })
|
|
6
6
|
|
|
7
|
-
this.log.debug('
|
|
8
|
-
this.print.info('
|
|
9
|
-
if (this.applets.length === 0) this.print.fatal('
|
|
7
|
+
this.log.debug('appletModeActivated')
|
|
8
|
+
this.print.info('appRunningAsApplet')
|
|
9
|
+
if (this.applets.length === 0) this.print.fatal('noAppletLoaded')
|
|
10
10
|
let name = this.applet
|
|
11
11
|
if (!isString(this.applet)) {
|
|
12
12
|
const select = await this.importPkg('bajoCli:@inquirer/select')
|
|
@@ -17,7 +17,7 @@ async function runAsApplet () {
|
|
|
17
17
|
}
|
|
18
18
|
const [ns, path] = name.split(':')
|
|
19
19
|
const applet = find(this.applets, a => (a.ns === ns || a.alias === ns))
|
|
20
|
-
if (!applet) this.print.fatal('
|
|
20
|
+
if (!applet) this.print.fatal('notFound%s%s', this.print.write('applet'), name)
|
|
21
21
|
await this.runHook(`${this.app[applet.ns]}:beforeAppletRun`)
|
|
22
22
|
await this.app.bajoCli.runApplet(applet, path, ...this.app.args)
|
|
23
23
|
await this.runHook(`${this.app[applet.ns]}:afterAppletRun`)
|
|
@@ -19,7 +19,7 @@ function breakNsPath (item = '', defaultNs = 'bajo', checkNs = true) {
|
|
|
19
19
|
const plugin = this.getPlugin(ns)
|
|
20
20
|
if (plugin) ns = plugin.name
|
|
21
21
|
}
|
|
22
|
-
if (!this.app[ns]) throw this.error('
|
|
22
|
+
if (!this.app[ns]) throw this.error('unknownPluginOrNotLoaded%s')
|
|
23
23
|
}
|
|
24
24
|
const fullPath = path
|
|
25
25
|
let qs
|
|
@@ -10,14 +10,14 @@ async function buildCollections (options = {}) {
|
|
|
10
10
|
const cfg = this.app[ns].getConfig()
|
|
11
11
|
let items = get(cfg, container, [])
|
|
12
12
|
if (!isArray(items)) items = [items]
|
|
13
|
-
this.app[ns].log.trace('
|
|
13
|
+
this.app[ns].log.trace('collecting%s', this.app[ns].print.write(container))
|
|
14
14
|
await runHook(`${ns}:${camelCase('beforeBuildCollection')}`, container)
|
|
15
15
|
const deleted = []
|
|
16
16
|
for (const index in items) {
|
|
17
17
|
const item = items[index]
|
|
18
18
|
if (useDefaultName) {
|
|
19
19
|
if (!has(item, 'name')) {
|
|
20
|
-
if (find(items, { name: 'default' })) throw this.app[ns].error('
|
|
20
|
+
if (find(items, { name: 'default' })) throw this.app[ns].error('collExists%s', 'default')
|
|
21
21
|
else item.name = 'default'
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -36,12 +36,12 @@ async function buildCollections (options = {}) {
|
|
|
36
36
|
else {
|
|
37
37
|
const checker = set({}, d, c[d])
|
|
38
38
|
const match = filter(items, checker)
|
|
39
|
-
if (match.length > 1) this.app[ns].fatal('
|
|
39
|
+
if (match.length > 1) this.app[ns].fatal('oneOrMoreSharedTheSame%s%s', container, join(dupChecks.filter(i => !isFunction(i))))
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
await runHook(`${ns}:${camelCase('afterBuildCollection')}`, container)
|
|
44
|
-
this.app[ns].log.debug('%s
|
|
44
|
+
this.app[ns].log.debug('collected%s%d', this.app[ns].print.write(container), items.length)
|
|
45
45
|
return items
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function format (value, type, options = {}) {
|
|
2
|
+
const { format } = this.config.intl
|
|
3
|
+
const { emptyValue = format.emptyValue } = options
|
|
4
|
+
const lang = options.lang ?? this.config.lang
|
|
5
|
+
if ([undefined, null, ''].includes(value)) return emptyValue
|
|
6
|
+
if (type === 'auto') {
|
|
7
|
+
if (value instanceof Date) type = 'datetime'
|
|
8
|
+
}
|
|
9
|
+
if (['integer', 'smallint'].includes(type)) {
|
|
10
|
+
value = parseInt(value)
|
|
11
|
+
if (isNaN(value)) return emptyValue
|
|
12
|
+
const setting = this.defaultsDeep(options.integer, format.integer)
|
|
13
|
+
return new Intl.NumberFormat(lang, setting).format(value)
|
|
14
|
+
}
|
|
15
|
+
if (['float', 'double'].includes(type)) {
|
|
16
|
+
value = parseFloat(value)
|
|
17
|
+
if (isNaN(value)) return emptyValue
|
|
18
|
+
if (this.app.bajoSpatial && options.latitude) return this.app.bajoSpatial.latToDms(value)
|
|
19
|
+
if (this.app.bajoSpatial && options.longitude) return this.app.bajoSpatial.lngToDms(value)
|
|
20
|
+
const setting = this.defaultsDeep(options.float, format.float)
|
|
21
|
+
return new Intl.NumberFormat(lang, setting).format(value)
|
|
22
|
+
}
|
|
23
|
+
if (['datetime', 'date'].includes(type)) {
|
|
24
|
+
const setting = this.defaultsDeep(options[type], format[type])
|
|
25
|
+
return new Intl.DateTimeFormat(lang, setting).format(new Date(value))
|
|
26
|
+
}
|
|
27
|
+
if (['time'].includes(type)) {
|
|
28
|
+
const setting = this.defaultsDeep(options.time, format.time)
|
|
29
|
+
return new Intl.DateTimeFormat(lang, setting).format(new Date(`1970-01-01T${value}Z`))
|
|
30
|
+
}
|
|
31
|
+
if (['array'].includes(type)) return value.join(', ')
|
|
32
|
+
if (['object'].includes(type)) return JSON.stringify(value)
|
|
33
|
+
return value
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default format
|
|
@@ -11,7 +11,7 @@ function getGlobalModuleDir (pkgName, silent = true) {
|
|
|
11
11
|
const npmPath = getGlobalPath('npm')
|
|
12
12
|
if (!npmPath) {
|
|
13
13
|
if (silent) return
|
|
14
|
-
throw this.error('
|
|
14
|
+
throw this.error('cantLocateNpmGlobalDir', { code: 'BAJO_CANT_LOCATE_NPM_GLOBAL_DIR' })
|
|
15
15
|
}
|
|
16
16
|
nodeModulesDir = dropRight(resolvePath(npmPath).split('/'), 1).join('/')
|
|
17
17
|
process.env.BAJO_GLOBAL_MODULE_DIR = nodeModulesDir
|
|
@@ -20,7 +20,7 @@ function getGlobalModuleDir (pkgName, silent = true) {
|
|
|
20
20
|
const dir = `${nodeModulesDir}/${pkgName}`
|
|
21
21
|
if (!fs.existsSync(dir)) {
|
|
22
22
|
if (silent) return
|
|
23
|
-
throw this.error('
|
|
23
|
+
throw this.error('cantLocateGlobalDir%s', pkgName, { code: 'BAJO_CANT_LOCATE_MODULE_GLOBAL_DIR' })
|
|
24
24
|
}
|
|
25
25
|
return dir
|
|
26
26
|
}
|
|
@@ -6,7 +6,7 @@ function getMethod (name = '', thrown = true) {
|
|
|
6
6
|
const { ns, path } = this.breakNsPath(name)
|
|
7
7
|
const method = get(this.app, `${ns}.${path}`)
|
|
8
8
|
if (method && isFunction(method)) return method
|
|
9
|
-
if (thrown) throw this.error('
|
|
9
|
+
if (thrown) throw this.error('cantFindMethod%s', name)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export default getMethod
|
|
@@ -39,7 +39,7 @@ async function importPkg (...pkgs) {
|
|
|
39
39
|
}
|
|
40
40
|
result[name] = mod
|
|
41
41
|
}
|
|
42
|
-
if (notFound.length > 0) throw this.error('
|
|
42
|
+
if (notFound.length > 0) throw this.error('cantFind%s', this.join(notFound))
|
|
43
43
|
if (pkgs.length === 1) return result[keys(result)[0]]
|
|
44
44
|
if (opts.asObject) return result
|
|
45
45
|
return values(result)
|
|
@@ -3,7 +3,7 @@ import dotenvParseVariables from 'dotenv-parse-variables'
|
|
|
3
3
|
import ms from 'ms'
|
|
4
4
|
import dayjs from '../../../lib/dayjs.js'
|
|
5
5
|
import isSet from './is-set.js'
|
|
6
|
-
import translate from '../../../lib/translate.js'
|
|
6
|
+
// import translate from '../../../lib/translate.js'
|
|
7
7
|
|
|
8
8
|
const { isPlainObject, isArray, isNumber, set, cloneDeep, isString, omit } = lodash
|
|
9
9
|
const statics = ['*']
|
|
@@ -14,11 +14,11 @@ function parseDur (val) {
|
|
|
14
14
|
|
|
15
15
|
function parseDt (val) {
|
|
16
16
|
const dt = dayjs(val)
|
|
17
|
-
if (!dt.isValid()) throw this.error('
|
|
17
|
+
if (!dt.isValid()) throw this.error('dtUnparsable%s', val)
|
|
18
18
|
return dt.toDate()
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function parseObject (input, { silent = true, parseValue = false,
|
|
21
|
+
function parseObject (input, { silent = true, parseValue = false, lang, ns } = {}) {
|
|
22
22
|
let obj = cloneDeep(input)
|
|
23
23
|
const keys = Object.keys(obj)
|
|
24
24
|
const me = this
|
|
@@ -38,14 +38,16 @@ function parseObject (input, { silent = true, parseValue = false, i18n, ns } = {
|
|
|
38
38
|
if (statics.includes(v)) obj[k] = v
|
|
39
39
|
else if (k.startsWith('t:') && isString(v)) {
|
|
40
40
|
const newK = k.slice(2)
|
|
41
|
-
if (
|
|
41
|
+
if (lang) {
|
|
42
42
|
const scope = ns ? me.app[ns] : me
|
|
43
43
|
let [text, ...args] = v.split('|')
|
|
44
44
|
args = args.map(a => {
|
|
45
|
-
if (a.slice(0, 2) === 't:') a = translate.call(scope, i18n, a.slice(2))
|
|
45
|
+
// if (a.slice(0, 2) === 't:') a = translate.call(scope, i18n, a.slice(2))
|
|
46
|
+
if (a.slice(0, 2) === 't:') a = scope.print.write(lang, a.slice(2))
|
|
46
47
|
return a
|
|
47
48
|
})
|
|
48
|
-
obj[newK] = translate.call(scope, i18n, text, ...args)
|
|
49
|
+
// obj[newK] = translate.call(scope, i18n, text, ...args)
|
|
50
|
+
obj[newK] = scope.print.write(text, lang, ...args)
|
|
49
51
|
} else obj[newK] = v
|
|
50
52
|
mutated.push(k)
|
|
51
53
|
} else if (parseValue) {
|
|
@@ -22,7 +22,7 @@ async function readConfig (file, { ns, pattern, globOptions = {}, ignoreError, d
|
|
|
22
22
|
if (!['', '.*'].includes(ext)) {
|
|
23
23
|
const item = find(this.app.bajo.configHandlers, { ext })
|
|
24
24
|
if (!item) {
|
|
25
|
-
if (!ignoreError) throw this.error('
|
|
25
|
+
if (!ignoreError) throw this.error('cantParse%s', file, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
26
26
|
return parseObject(defValue)
|
|
27
27
|
}
|
|
28
28
|
return parseObject(await item.readHandler.call(this.app[ns], file, opts))
|
|
@@ -30,7 +30,7 @@ async function readConfig (file, { ns, pattern, globOptions = {}, ignoreError, d
|
|
|
30
30
|
const item = pattern ?? `${fname}.{${map(map(this.app.bajo.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
|
|
31
31
|
const files = await fg(item, globOptions)
|
|
32
32
|
if (files.length === 0) {
|
|
33
|
-
if (!ignoreError) throw this.error('
|
|
33
|
+
if (!ignoreError) throw this.error('noConfigFileFound', { code: 'BAJO_CONFIG_FILE_NOT_FOUND' })
|
|
34
34
|
return parseObject(defValue)
|
|
35
35
|
}
|
|
36
36
|
let config = defValue
|
|
@@ -38,7 +38,7 @@ async function readConfig (file, { ns, pattern, globOptions = {}, ignoreError, d
|
|
|
38
38
|
const ext = path.extname(f).toLowerCase()
|
|
39
39
|
const item = find(this.app.bajo.configHandlers, { ext })
|
|
40
40
|
if (!item) {
|
|
41
|
-
if (!ignoreError) throw this.error('
|
|
41
|
+
if (!ignoreError) throw this.error('cantParse%s', f, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
42
42
|
continue
|
|
43
43
|
}
|
|
44
44
|
config = await item.readHandler.call(this.app[ns], f, opts)
|
|
@@ -5,7 +5,7 @@ import parseObject from './parse-object.js'
|
|
|
5
5
|
const { isEmpty } = lodash
|
|
6
6
|
|
|
7
7
|
function readJson (file, thrownNotFound) {
|
|
8
|
-
if (!fs.existsSync(file) && thrownNotFound) throw this.error('
|
|
8
|
+
if (!fs.existsSync(file) && thrownNotFound) throw this.error('notFound%s%s', this.print.write('file'), file)
|
|
9
9
|
let resp = fs.readFileSync(file, 'utf8')
|
|
10
10
|
if (isEmpty(resp)) resp = '{}'
|
|
11
11
|
return parseObject(JSON.parse(resp))
|
|
@@ -18,7 +18,7 @@ async function runHook (hookName, ...args) {
|
|
|
18
18
|
resp: res
|
|
19
19
|
})
|
|
20
20
|
if (path.startsWith('once')) removed.push(i)
|
|
21
|
-
if (this.config.log.traceHook) scope.log.trace('
|
|
21
|
+
if (this.config.log.traceHook) scope.log.trace('hookExecuted%s', hookName)
|
|
22
22
|
}
|
|
23
23
|
if (removed.length > 0) pullAt(this.app.bajo.hooks, removed)
|
|
24
24
|
|
|
@@ -12,7 +12,7 @@ async function saveAsDownload (file, obj, printSaved = true) {
|
|
|
12
12
|
const dir = path.dirname(fname)
|
|
13
13
|
if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
|
|
14
14
|
await fs.writeFile(fname, obj, 'utf8')
|
|
15
|
-
if (printSaved) print.succeed('
|
|
15
|
+
if (printSaved) print.succeed('savedAs%s', path.resolve(fname), { skipSilence: true })
|
|
16
16
|
return fname
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -3,7 +3,7 @@ import createMethod from '../../../lib/create-method.js'
|
|
|
3
3
|
async function attachMethod () {
|
|
4
4
|
const { eachPlugins } = this.bajo
|
|
5
5
|
const me = this
|
|
6
|
-
me.bajo.log.debug('
|
|
6
|
+
me.bajo.log.debug('attachMethods')
|
|
7
7
|
await eachPlugins(async function ({ ns, pkgName }) {
|
|
8
8
|
const dir = ns === me.bajo.mainNs ? (`${me.bajo.dir.base}/${me.bajo.mainNs}`) : me.bajo.getModuleDir(pkgName)
|
|
9
9
|
const num = await createMethod.call(me[ns], `${dir}/bajo/method`, pkgName)
|
|
@@ -3,9 +3,12 @@ import lodash from 'lodash'
|
|
|
3
3
|
const { camelCase } = lodash
|
|
4
4
|
|
|
5
5
|
async function buildConfig () {
|
|
6
|
-
this.bajo.log.debug('
|
|
6
|
+
this.bajo.log.debug('readConfigs')
|
|
7
7
|
for (const pkg of this.bajo.pluginPkgs) {
|
|
8
|
-
|
|
8
|
+
const plugin = this[camelCase(pkg)]
|
|
9
|
+
await plugin.loadConfig()
|
|
10
|
+
plugin.initPrint()
|
|
11
|
+
plugin.initLog()
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
|
|
@@ -4,13 +4,13 @@ const { find } = lodash
|
|
|
4
4
|
|
|
5
5
|
async function checkAlias () {
|
|
6
6
|
const { eachPlugins } = this.bajo
|
|
7
|
-
this.bajo.log.debug('
|
|
7
|
+
this.bajo.log.debug('checkAliasNameClash')
|
|
8
8
|
const refs = []
|
|
9
9
|
await eachPlugins(async function ({ ns, pkgName, alias }) {
|
|
10
10
|
let item = find(refs, { ns })
|
|
11
|
-
if (item) throw this.error('
|
|
11
|
+
if (item) throw this.error('pluginNameClash%s%s%s%s', ns, pkgName, item.ns, item.pkgName, { code: 'BAJO_NAME_CLASH' })
|
|
12
12
|
item = find(refs, { alias })
|
|
13
|
-
if (item) throw this.error('
|
|
13
|
+
if (item) throw this.error('pluginNameClash%s%s%s%s', alias, pkgName, item.alias, item.pkgName, { code: 'BAJO_ALIAS_CLASH' })
|
|
14
14
|
refs.push({ ns, alias, pkgName })
|
|
15
15
|
})
|
|
16
16
|
}
|
|
@@ -15,14 +15,14 @@ async function runner ({ ns, pkgName }) {
|
|
|
15
15
|
const deps = keys(odep)
|
|
16
16
|
if (deps.length > 0) {
|
|
17
17
|
if (intersection(this.app.bajo.pluginPkgs, deps).length !== deps.length) {
|
|
18
|
-
throw this.error('
|
|
18
|
+
throw this.error('dependencyUnfulfilled%s%s', pkgName, join(deps), { code: 'BAJO_DEPENDENCY' })
|
|
19
19
|
}
|
|
20
20
|
each(deps, d => {
|
|
21
21
|
if (!odep[d]) return
|
|
22
22
|
const ver = get(this.app[camelCase(d)], 'config.pkg.version')
|
|
23
23
|
if (!ver) return
|
|
24
24
|
if (!semver.satisfies(ver, odep[d])) {
|
|
25
|
-
throw this.error('
|
|
25
|
+
throw this.error('semverCheckFailed%s%s', pkgName, `${d}@${odep[d]}`, { code: 'BAJO_DEPENDENCY_SEMVER' })
|
|
26
26
|
}
|
|
27
27
|
})
|
|
28
28
|
}
|
|
@@ -30,7 +30,7 @@ async function runner ({ ns, pkgName }) {
|
|
|
30
30
|
|
|
31
31
|
async function checkDependency () {
|
|
32
32
|
const { eachPlugins } = this.bajo
|
|
33
|
-
this.bajo.log.debug('
|
|
33
|
+
this.bajo.log.debug('checkDeps')
|
|
34
34
|
await eachPlugins(async function ({ ns, pkgName, config }) {
|
|
35
35
|
await runner.call(this, { ns, pkgName, config })
|
|
36
36
|
})
|
|
@@ -8,7 +8,7 @@ async function collectExitHandlers () {
|
|
|
8
8
|
this.app[ns].exitHandler = mod
|
|
9
9
|
nss.push(ns)
|
|
10
10
|
})
|
|
11
|
-
this.bajo.log.trace('
|
|
11
|
+
this.bajo.log.trace('exitHandlers%s', nss.length === 0 ? print.write('none') : join(nss))
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export default collectExitHandlers
|
|
@@ -6,7 +6,7 @@ async function collectHooks () {
|
|
|
6
6
|
const { eachPlugins, runHook, isLogInRange, importModule, breakNsPathFromFile } = this.bajo
|
|
7
7
|
const me = this
|
|
8
8
|
me.bajo.hooks = this.bajo.hooks ?? []
|
|
9
|
-
me.bajo.log.debug('
|
|
9
|
+
me.bajo.log.debug('collectHooks')
|
|
10
10
|
// collects
|
|
11
11
|
await eachPlugins(async function ({ ns, dir, file }) {
|
|
12
12
|
const { fullNs, path } = breakNsPathFromFile({ file, dir, baseNs: ns, suffix: '/hook/' })
|
|
@@ -15,7 +15,7 @@ async function run () {
|
|
|
15
15
|
})
|
|
16
16
|
await runHook(`bajo:${camelCase(`after ${method} all plugins`)}`)
|
|
17
17
|
}
|
|
18
|
-
me.bajo.log.debug('
|
|
18
|
+
me.bajo.log.debug('loadedPlugins%s', join(map(me.bajo.pluginPkgs, b => camelCase(b))))
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export default run
|
|
@@ -50,11 +50,12 @@ class BajoPlugin extends Plugin {
|
|
|
50
50
|
this.config = omit(cfg, ['title', 'dependencies'])
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
async _onoff (item,
|
|
53
|
+
async _onoff (item, ...args) {
|
|
54
54
|
this.state[item] = false
|
|
55
55
|
const { runHook, importModule } = this.app.bajo
|
|
56
56
|
const mod = await importModule(`${this.dir.pkg}/bajo/${item}.js`)
|
|
57
57
|
if (mod) {
|
|
58
|
+
const text = this.print.write('plugin%s', this.print.write(item))
|
|
58
59
|
this.log.trace(text)
|
|
59
60
|
await runHook(`${this.name}:${camelCase(`before ${item}`)}`)
|
|
60
61
|
await mod.call(this, ...args)
|
|
@@ -64,17 +65,17 @@ class BajoPlugin extends Plugin {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
async init () {
|
|
67
|
-
await this._onoff('init'
|
|
68
|
+
await this._onoff('init')
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
async start (...args) {
|
|
71
72
|
const { freeze } = this.app.bajo
|
|
72
73
|
freeze(this.config)
|
|
73
|
-
await this._onoff('start',
|
|
74
|
+
await this._onoff('start', ...args)
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
async stop () {
|
|
77
|
-
await this._onoff('stop'
|
|
78
|
+
await this._onoff('stop')
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
package/boot/class/error.js
CHANGED
|
@@ -8,7 +8,7 @@ class BajoError {
|
|
|
8
8
|
this.plugin = plugin
|
|
9
9
|
this.payload = args.length > 0 && isPlainObject(args[args.length - 1]) ? args[args.length - 1] : {}
|
|
10
10
|
this.orgMessage = msg
|
|
11
|
-
this.message =
|
|
11
|
+
this.message = plugin.print.write(msg, ...args)
|
|
12
12
|
this.write()
|
|
13
13
|
}
|
|
14
14
|
|
package/boot/class/log.js
CHANGED
|
@@ -2,7 +2,6 @@ import os from 'os'
|
|
|
2
2
|
import lodash from 'lodash'
|
|
3
3
|
import levels from './bajo-core/method/log-levels.js'
|
|
4
4
|
import isLogInRange from './bajo-core/method/is-log-in-range.js'
|
|
5
|
-
import translate from '../lib/translate.js'
|
|
6
5
|
import dayjs from 'dayjs'
|
|
7
6
|
|
|
8
7
|
const { isEmpty, without, merge, upperFirst } = lodash
|
|
@@ -18,7 +17,7 @@ class Log {
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
write (text, ...args) {
|
|
21
|
-
return
|
|
20
|
+
return this.plugin.print.write(text, ...args)
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
isExtLogger () {
|
|
@@ -40,7 +39,7 @@ class Log {
|
|
|
40
39
|
data = null
|
|
41
40
|
}
|
|
42
41
|
args = without(args, undefined)
|
|
43
|
-
msg =
|
|
42
|
+
msg = `[${this.plugin.name}] ${this.write(msg, ...args)}`
|
|
44
43
|
if (this.plugin.app[this.bajoLog] && this.plugin.app[this.bajoLog].logger) {
|
|
45
44
|
this.plugin.app[this.bajoLog].logger[level](data, msg, ...args)
|
|
46
45
|
} else {
|
package/boot/class/plugin.js
CHANGED
|
@@ -14,7 +14,6 @@ class Plugin {
|
|
|
14
14
|
this.config = {}
|
|
15
15
|
this.lib = {}
|
|
16
16
|
this.exitHandler = undefined
|
|
17
|
-
this.initLog()
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
getConfig (path, options = {}) {
|
|
@@ -27,10 +26,12 @@ class Plugin {
|
|
|
27
26
|
|
|
28
27
|
initLog () {
|
|
29
28
|
this.log = new Log(this)
|
|
29
|
+
this.log.init()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
initPrint (opts) {
|
|
33
33
|
this.print = new Print(this, opts)
|
|
34
|
+
this.print.init()
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
error (msg, ...args) {
|
package/boot/class/print.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import ora from 'ora'
|
|
2
2
|
import lodash from 'lodash'
|
|
3
3
|
import defaultsDeep from './bajo-core/method/defaults-deep.js'
|
|
4
|
-
import
|
|
4
|
+
import fs from 'fs-extra'
|
|
5
|
+
import Sprintf from 'sprintf-js'
|
|
6
|
+
const { sprintf } = Sprintf
|
|
7
|
+
let unknownLangWarning = false
|
|
5
8
|
|
|
6
|
-
const { isPlainObject } = lodash
|
|
9
|
+
const { last, isPlainObject, get, without, reverse } = lodash
|
|
7
10
|
|
|
8
11
|
class Print {
|
|
9
12
|
constructor (plugin, opts = {}) {
|
|
@@ -12,6 +15,52 @@ class Print {
|
|
|
12
15
|
this.startTime = this.plugin.app.bajo.lib.dayjs()
|
|
13
16
|
this.setOpts()
|
|
14
17
|
this.ora = ora(this.opts)
|
|
18
|
+
this.intl = {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
init () {
|
|
22
|
+
for (const l of this.plugin.app.bajo.config.intl.supported) {
|
|
23
|
+
this.intl[l] = {}
|
|
24
|
+
const path = `${this.plugin.dir.pkg}/bajo/intl/${l}.json`
|
|
25
|
+
if (!fs.existsSync(path)) continue
|
|
26
|
+
const trans = fs.readFileSync(path, 'utf8')
|
|
27
|
+
try {
|
|
28
|
+
this.intl[l] = JSON.parse(trans)
|
|
29
|
+
} catch (err) {}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
write (text, ...args) {
|
|
34
|
+
const opts = last(args)
|
|
35
|
+
let lang = this.plugin.app.bajo.config.lang
|
|
36
|
+
if (isPlainObject(opts)) {
|
|
37
|
+
args.pop()
|
|
38
|
+
lang = opts.lang
|
|
39
|
+
}
|
|
40
|
+
const { fallback, supported } = this.plugin.app.bajo.config.intl
|
|
41
|
+
if (!unknownLangWarning && !supported.includes(lang)) {
|
|
42
|
+
unknownLangWarning = true
|
|
43
|
+
this.plugin.app.bajo.log.warn('unsupportedLangFallbackTo%s', fallback)
|
|
44
|
+
}
|
|
45
|
+
const plugins = reverse(without([...this.plugin.app.bajo.pluginNames], this.plugin.name))
|
|
46
|
+
plugins.unshift(this.plugin.name)
|
|
47
|
+
plugins.push('bajo')
|
|
48
|
+
|
|
49
|
+
let trans
|
|
50
|
+
for (const p of plugins) {
|
|
51
|
+
const root = get(this, `plugin.app.${p}.print.intl.${lang}`, {})
|
|
52
|
+
trans = get(root, text)
|
|
53
|
+
if (trans) break
|
|
54
|
+
}
|
|
55
|
+
if (!trans) {
|
|
56
|
+
for (const p of plugins) {
|
|
57
|
+
const root = get(this, `plugin.app.${p}.print.intl.${fallback}`, {})
|
|
58
|
+
trans = get(root, text)
|
|
59
|
+
if (trans) break
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!trans) trans = text
|
|
63
|
+
return sprintf(trans, ...args)
|
|
15
64
|
}
|
|
16
65
|
|
|
17
66
|
setOpts (args = []) {
|
|
@@ -35,10 +84,6 @@ class Print {
|
|
|
35
84
|
return this
|
|
36
85
|
}
|
|
37
86
|
|
|
38
|
-
write (text, ...args) {
|
|
39
|
-
return translate.call(this.plugin, null, text, ...args)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
87
|
getElapsed (unit = 'hms') {
|
|
43
88
|
const u = unit === 'hms' ? 'second' : unit
|
|
44
89
|
const elapsed = this.plugin.app.bajo.lib.dayjs().diff(this.startTime, u)
|
|
@@ -6,13 +6,13 @@ async function readAllConfigs (base) {
|
|
|
6
6
|
let ext = {}
|
|
7
7
|
// default config file
|
|
8
8
|
try {
|
|
9
|
-
cfg = await readConfig.call(this.bajo, `${base}
|
|
9
|
+
cfg = await readConfig.call(this.bajo, `${base}.*`, { ignoreError: true })
|
|
10
10
|
} catch (err) {
|
|
11
11
|
if (['BAJO_CONFIG_NO_PARSER'].includes(err.code)) throw err
|
|
12
12
|
}
|
|
13
13
|
// env based config file
|
|
14
14
|
try {
|
|
15
|
-
ext = await readConfig.call(this.bajo, `${base}-${this.bajo.config.env}
|
|
15
|
+
ext = await readConfig.call(this.bajo, `${base}-${this.bajo.config.env}.*`, { ignoreError: true })
|
|
16
16
|
} catch (err) {
|
|
17
17
|
if (!['BAJO_CONFIG_FILE_NOT_FOUND'].includes(err.code)) throw err
|
|
18
18
|
}
|
package/package.json
CHANGED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"[%s] '%s' signal received": "[%s] Diterima signal '%s'",
|
|
3
|
-
"[%s] Exited: %s": "[%s] Keluar: %s",
|
|
4
|
-
"[%s] Program shutdown": "[%s] Program berakhir",
|
|
5
|
-
"[%s] Exit handlings": "[%s] Pengaturan keluar",
|
|
6
|
-
"[%s] Boot process completed in %s": "[%s] Proses boot komplit dalam waktu %s",
|
|
7
|
-
"[%s] Run tool": "[%s] Jalankan perkakas",
|
|
8
|
-
"[%s] Loaded plugins: %s": "[%s] Plugin termuat: %s",
|
|
9
|
-
"[%s] Unloaded 'single' plugins: %s": "[%s] 'Single' plugin tak termuat: %s",
|
|
10
|
-
"[%s] No %s found": "[%s] Tidak ditemukan %s",
|
|
11
|
-
"[%s] Init plugin...": "[%s] Init plugin...",
|
|
12
|
-
"[%s] Start plugin...": "[%s] Jalankan plugin...",
|
|
13
|
-
"[%s] Collecting %s": "[%s] Mengumpulkan %s",
|
|
14
|
-
"[%s] %s collected: %d": "[%s] Total %s terkumpul: %d",
|
|
15
|
-
"- All -": "- Semua -",
|
|
16
|
-
"Tool mode activated": "Mode perkakas diaktifkan",
|
|
17
|
-
"App is running in tool mode...": "Aplikasi berjalan dalam mode perkakas",
|
|
18
|
-
"No tool loaded. Aborted!": "Tidak ada perkakas yang termuat. Batalkan!",
|
|
19
|
-
"Please select:": "Silahkan pilih:",
|
|
20
|
-
"Tool '%s' not found. Aborted!": "perkakas '%s' tidak ditemukan. Batalkan!",
|
|
21
|
-
"Please select a method:": "Silahkan pilih metode:",
|
|
22
|
-
"Unknown method '%s'": "Metode '%s' tidak dikenal",
|
|
23
|
-
"and": "dan",
|
|
24
|
-
"or": "atau",
|
|
25
|
-
"Yes": "Ya",
|
|
26
|
-
"No": "Tidak",
|
|
27
|
-
"[%s] Exited": "[%s] Telah keluar",
|
|
28
|
-
"[%s] App shutdown": "[%s] Aplikasi dimatikan",
|
|
29
|
-
"[%s] Collect %s": "",
|
|
30
|
-
"[%s] %s support is disabled": ""
|
|
31
|
-
}
|