bajo 2.0.1 → 2.0.2

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 (101) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/.github/workflows/repo-lockdown.yml +24 -0
  3. package/.jsdoc.conf.json +7 -6
  4. package/LICENSE +1 -1
  5. package/README.md +50 -18
  6. package/class/app.js +376 -54
  7. package/class/bajo.js +228 -149
  8. package/class/base.js +106 -0
  9. package/class/helper/bajo.js +135 -84
  10. package/class/helper/{plugin.js → base.js} +96 -22
  11. package/class/{base → misc}/err.js +44 -14
  12. package/class/misc/log.js +212 -0
  13. package/class/misc/print.js +264 -0
  14. package/class/plugin.js +120 -68
  15. package/docs/App.html +23 -1
  16. package/docs/Bajo.html +2 -9
  17. package/docs/Base.html +3 -0
  18. package/docs/Err.html +3 -1
  19. package/docs/Log.html +5 -1
  20. package/docs/Plugin.html +1 -1
  21. package/docs/Print.html +1 -1
  22. package/docs/class_app.js.html +378 -56
  23. package/docs/class_bajo.js.html +230 -151
  24. package/docs/class_base.js.html +109 -0
  25. package/docs/class_helper_bajo.js.html +138 -87
  26. package/docs/class_helper_base.js.html +246 -0
  27. package/docs/class_misc_err.js.html +129 -0
  28. package/docs/class_misc_log.js.html +210 -0
  29. package/docs/class_misc_print.js.html +267 -0
  30. package/docs/class_plugin.js.html +122 -70
  31. package/docs/data/search.json +1 -1
  32. package/docs/global.html +4 -1
  33. package/docs/index.html +2 -2
  34. package/docs/index.js.html +35 -0
  35. package/docs/lib_current-loc.js.html +36 -0
  36. package/docs/lib_formats.js.html +8 -8
  37. package/docs/lib_import-module.js.html +59 -0
  38. package/docs/lib_log-levels.js.html +17 -7
  39. package/docs/lib_parse-args-argv.js.html +83 -0
  40. package/docs/lib_parse-env.js.html +53 -0
  41. package/docs/lib_resolve-path.js.html +3 -6
  42. package/docs/lib_shim.js.html +8 -3
  43. package/docs/module-Helper_Bajo.html +3 -0
  44. package/docs/module-Helper_Base.html +3 -0
  45. package/docs/module-Lib.html +15 -0
  46. package/docs/static/home.md +32 -0
  47. package/docs/static/logo-ecosystem.png +0 -0
  48. package/docs/static/logo.png +0 -0
  49. package/extend/bajo/intl/en-US.json +8 -2
  50. package/extend/bajo/intl/id.json +8 -2
  51. package/index.js +22 -2
  52. package/lib/current-loc.js +24 -2
  53. package/lib/formats.js +6 -6
  54. package/lib/import-module.js +29 -0
  55. package/lib/log-levels.js +15 -5
  56. package/lib/parse-args-argv.js +20 -12
  57. package/lib/parse-env.js +18 -7
  58. package/lib/resolve-path.js +1 -4
  59. package/lib/shim.js +6 -1
  60. package/package.json +4 -7
  61. package/wiki/CONFIG.md +30 -0
  62. package/wiki/CONTRIBUTING.md +5 -0
  63. package/wiki/DEV_GUIDE.md +3 -0
  64. package/wiki/ECOSYSTEM.md +93 -0
  65. package/wiki/GETTING-STARTED.md +356 -0
  66. package/wiki/USER-GUIDE.md +256 -0
  67. package/class/base/log.js +0 -205
  68. package/class/base/plugin.js +0 -168
  69. package/class/base/print.js +0 -272
  70. package/docs/BasePlugin.html +0 -5
  71. package/docs/class_base_err.js.html +0 -99
  72. package/docs/class_base_log.js.html +0 -208
  73. package/docs/class_base_plugin.js.html +0 -180
  74. package/docs/class_base_print.js.html +0 -275
  75. package/docs/class_helper_plugin.js.html +0 -172
  76. package/docs/lib_create-method.js.html +0 -42
  77. package/docs/module-class_helper_bajo.html +0 -3
  78. package/docs/module-class_helper_plugin.html +0 -3
  79. package/docs/module-lib_create-method.html +0 -3
  80. package/docs/module-lib_formats.html +0 -3
  81. package/docs/module-lib_log-levels.html +0 -3
  82. package/docs/module-lib_resolve-path.html +0 -3
  83. package/docs/module-lib_shim.html +0 -3
  84. package/docs/tutorial-contribution.html +0 -3
  85. package/docs/tutorial-ecosystem.html +0 -3
  86. package/docs/tutorial-getting-started.html +0 -13
  87. package/docs/tutorial-plugin-dev.html +0 -3
  88. package/docs/tutorial-user-guide.html +0 -3
  89. package/lib/create-method.js +0 -39
  90. package/lib/dayjs.js +0 -8
  91. package/lib/omitted-plugin-keys.js +0 -3
  92. package/lib/read-all-configs.js +0 -19
  93. package/misc-docs/.hook.md +0 -11
  94. package/misc-docs/bitcoin.jpeg +0 -0
  95. package/misc-docs/contribution.md +0 -20
  96. package/misc-docs/ecosystem.md +0 -94
  97. package/misc-docs/getting-started.md +0 -142
  98. package/misc-docs/plugin-dev.md +0 -0
  99. package/misc-docs/toc.json +0 -17
  100. package/misc-docs/user-guide.md +0 -1
  101. /package/docs/{bitcoin.jpeg → static/bitcoin.jpeg} +0 -0
@@ -0,0 +1,93 @@
1
+ # Ecosystem
2
+
3
+ ## Plugins
4
+
5
+ | Package | Docs | NS | Alias | Description |
6
+ | ------- | ---- | -- | ----- | ----------- |
7
+ | [bajo-cache](https://github.com/ardhi/bajo-cache) | [Docs](https://ardhi.github.io/bajo-cache) | bajoCache | cache | Universal Cache |
8
+ | [bajo-cli](https://github.com/ardhi/bajo-cli) | [Docs](https://ardhi.github.io/bajo-cli) | bajoCli | cli | Command Line Tools |
9
+ | [bajo-common-db](https://github.com/ardhi/bajo-common-db) | [Docs](https://ardhi.github.io/bajo-common-db) | bajoCommonDb | cdb | Common Database |
10
+ | [bajo-config](https://github.com/ardhi/bajo-config) | [Docs](https://ardhi.github.io/bajo-config) | bajoConfig | cdb | YAML & TOML Support |
11
+ | [bajo-cron](https://github.com/ardhi/bajo-cron) | [Docs](https://ardhi.github.io/bajo-cron) | bajoCron | cron | Cron Support |
12
+ | [bajo-extra](https://github.com/ardhi/bajo-extra) | [Docs](https://ardhi.github.io/bajo-extra) | bajoExtra | extra | Extra Booster! |
13
+ | [bajo-logger](https://github.com/ardhi/bajo-logger) | [Docs](https://ardhi.github.io/bajo-logger) | bajoLogger | log | Pino Logger |
14
+ | [bajo-markdown](https://github.com/ardhi/bajo-markdown) | [Docs](https://ardhi.github.io/bajo-markdown) | bajoMarkdown | md | Markdown Support |
15
+ | [bajo-queue](https://github.com/ardhi/bajo-queue) | [Docs](https://ardhi.github.io/bajo-queue) | bajoQueue | q | Queue System |
16
+ | [bajo-spatial](https://github.com/ardhi/bajo-spatial) | [Docs](https://ardhi.github.io/bajo-spatial) | bajoSpatial | spatial | Spatial Support |
17
+ | [bajo-sysinfo](https://github.com/ardhi/bajo-sysinfo) | [Docs](https://ardhi.github.io/bajo-sysinfo) | bajoSysinfo | si | System Information |
18
+ | [bajo-template](https://github.com/ardhi/bajo-template) | [Docs](https://ardhi.github.io/bajo-template) | bajoTemplate | tpl | Template System |
19
+
20
+ ## Dobo DBMS Plugins
21
+
22
+ | Package | Docs | NS | Alias | Description |
23
+ | ------- | ---- | -- | ----- | ----------- |
24
+ | [dobo](https://github.com/ardhi/dobo) | [Docs](https://ardhi.github.io/dobo) | dobo | db | Dobo DBMS |
25
+ | [dobo-extra](https://github.com/ardhi/dobo-extra) | [Docs](https://ardhi.github.io/dobo-extra) | doboExtra | dbx | Dobo Extra Tools/Utility |
26
+ | [dobo-couchdb](https://github.com/ardhi/dobo-couchdb) | [Docs](https://ardhi.github.io/dobo-couchdb) | doboCouchdb | dbcouch | CouchDB Driver |
27
+ | [dobo-elasticsearch](https://github.com/ardhi/dobo-elasticsearch) | [Docs](https://ardhi.github.io/dobo-elasticsearch) | doboElasticsearch | dbes | Elasticsearch Driver |
28
+ | [dobo-knex](https://github.com/ardhi/dobo-knex) | [Docs](https://ardhi.github.io/dobo-knex) | doboKnex | dbknex | Knex/SQL Driver |
29
+ | [dobo-mongodb](https://github.com/ardhi/dobo-mongodb) | [Docs](https://ardhi.github.io/dobo-mongodb) | doboMongodb | dbmongo | MongoDB Driver |
30
+ | [dobo-redis](https://github.com/ardhi/dobo-redis) | [Docs](https://ardhi.github.io/dobo-redis) | doboRedis | dbredis | Redis Driver |
31
+ | [dobo-restproxy](https://github.com/ardhi/dobo-restproxy) | [Docs](https://ardhi.github.io/dobo-restproxy) | doboRestproxy | dbrpx | Restproxy Driver |
32
+ | [dobo-restproxy-jsonserver](https://github.com/ardhi/dobo-restproxy-jsonserver) | [Docs](https://ardhi.github.io/dobo-restproxy-jsonserver) | doboResporoxyJsonserver | dbrpxjs |JsonServer Support for doboRestproxy |
33
+ | [dobo-restproxy-ndut](https://github.com/ardhi/dobo-restproxy-ndut) | [Docs](https://ardhi.github.io/dobo-restproxy-ndut) | doboRestproxyNdut | dbrpxndut | NDUT Support for doboRestproxy |
34
+
35
+ ## Waibu Web Framework Plugins
36
+
37
+ | Package | Docs | NS | Alias | Description |
38
+ | ------- | ---- | -- | ----- | ----------- |
39
+ | [waibu](https://github.com/ardhi/waibu) | [Docs](https://ardhi.github.io/waibu) | waibu | w |Waibu Web Framework |
40
+ | [waibu-admin](https://github.com/ardhi/waibu-admin) | [Docs](https://ardhi.github.io/waibu-admin) | waibuAdmin | wa | Waibu Admin |
41
+ | [waibu-alpinejs](https://github.com/ardhi/waibu-alpinejs) | [Docs](https://ardhi.github.io/waibu-alpinejs) | waibuAlpinejs | walp | Alpine.js Support |
42
+ | [waibu-blu](https://github.com/ardhi/waibu-blu) | [Docs](https://ardhi.github.io/waibu-blu) | waibuBlu | wblu | Blu theme |
43
+ | [waibu-bootstrap](https://github.com/ardhi/waibu-bootstrap) | [Docs](https://ardhi.github.io/waibu-bootstrap) | waibuBootstrap | wbs | Bootstrap Support |
44
+ | [waibu-bootstrap-icons](https://github.com/ardhi/waibu-bootstrap-icons) | [Docs](https://ardhi.github.io/waibu-bootstrap-icons) | waibuBootstrapIcons | wbsi | Bootstrap Icons Support |
45
+ | [waibu-bootswatch](https://github.com/ardhi/waibu-bootswatch) | [Docs](https://ardhi.github.io/waibu-bootswatch) | waibuBootswatch | wbw | Bootswatch Support |
46
+ | [waibu-db](https://github.com/ardhi/waibu-db) | [Docs](https://ardhi.github.io/waibu-db) | waibuDb | wdb | Database helper |
47
+ | [waibu-extra](https://github.com/ardhi/waibu-extra) | [Docs](https://ardhi.github.io/waibu-extra) | waibuExtra | wx | Most used 3rd party libs |
48
+ | [waibu-maps](https://github.com/ardhi/waibu-maps) | [Docs](https://ardhi.github.io/waibu-maps) | waibuMaps | wmaps | Maps Support |
49
+ | [waibu-mpa](https://github.com/ardhi/waibu-mpa) | [Docs](https://ardhi.github.io/waibu-mpa) | waibuMpa | wmpa | Multi pages app |
50
+ | [waibu-phosphor](https://github.com/ardhi/waibu-phosphor) | [Docs](https://ardhi.github.io/waibu-phosphor) | waibuPhosphor | wpp | Phosphoricons Support |
51
+ | [waibu-rest-api](https://github.com/ardhi/waibu-rest-api) | [Docs](https://ardhi.github.io/waibu-rest-api) | waibuRestApi | wra | Rest API |
52
+ | [waibu-static](https://github.com/ardhi/waibu-static) | [Docs](https://ardhi.github.io/waibu-static) | waibuStatic | wstatic | Static asset |
53
+ | [waibu-swagger](https://github.com/ardhi/waibu-swagger) | [Docs](https://ardhi.github.io/waibu-swagger) | waibuSwagger | wswagger | Rest API Documentation |
54
+
55
+ ## Masohi Messaging Plugins
56
+
57
+ | Package | Docs | NS | Alias | Description |
58
+ | ------- | ---- | -- | ----- | ----------- |
59
+ | [masohi](https://github.com/ardhi/masohi) | [Docs](https://ardhi.github.io/masohi) | masohi | masohi | Masohi Messaging |
60
+ | [masohi-codec](https://github.com/ardhi/masohi-codec) | [Docs](https://ardhi.github.io/masohi-codec) | masohiCodec | codec | Codec |
61
+ | [masohi-codec-ais](https://github.com/ardhi/masohi-codec-ais) | [Docs](https://ardhi.github.io/masohi-codec-ais) | masohiCodecAis | codec-ais | AIS Codec |
62
+ | [masohi-mail](https://github.com/ardhi/masohi-mail) | [Docs](https://ardhi.github.io/masohi-mail) | masohiMail | mail | Mail Connector |
63
+ | [masohi-mqtt](https://github.com/ardhi/masohi-mqtt) | [Docs](https://ardhi.github.io/masohi-mqtt) | masohiMqtt | mqtt | MQTT Connector |
64
+ | [masohi-serialport](https://github.com/ardhi/masohi-serialport) | [Docs](https://ardhi.github.io/masohi-serialport) | masohiSerialport | sp | Serialport Connector |
65
+ | [masohi-socket.io](https://github.com/ardhi/masohi-socket.io) | [Docs](https://ardhi.github.io/masohi-socket.io) | masohiSocketIo | sio | Socket.io Connector |
66
+
67
+ ## Sumba Biz Suite Plugins
68
+
69
+ | Package | Docs | NS | Alias | Description |
70
+ | ------- | ---- | -- | ----- | ----------- |
71
+ | [sumba](https://github.com/ardhi/sumba) | [Docs](https://ardhi.github.io/sumba) | sumba | sumba | Sumba Biz Suite |
72
+ | [sumba-cms](https://github.com/ardhi/sumba-cms) | [Docs](https://ardhi.github.io/sumba-cms) | sumbaCms | cms | Sumba CMS |
73
+ | [sumba-geonames](https://github.com/ardhi/sumba-geonames) | [Docs](https://ardhi.github.io/sumba-geonames) | sumbaGeonames | geonames | Sumba Geonames |
74
+ | [sumba-nominatim](https://github.com/ardhi/sumba-nominatim) | [Docs](https://ardhi.github.io/sumba-nominatim) | sumbaNominatim | nominatim | Sumba OSM Nominatim |
75
+ | [sumba-oauth](https://github.com/ardhi/sumba-oauth) | [Docs](https://ardhi.github.io/sumba-oauth) | sumbaOauth | oauth | Sumba OAuth Providers |
76
+
77
+ ## Sumba Biz Suite Premium Plugins
78
+
79
+ | Package | Docs | NS | Alias | Description |
80
+ | ------- | ---- | -- | ----- | ----------- |
81
+ | [@sumba/geofence](https://bajo.app/premium-plugins/sumba-geofence) | [Docs](https://ardhi.github.io/sumba-geofence) | sumbaGeofence | geofence | Sumba Geofence |
82
+ | [@sumba/maps](https://bajo.app/premium-plugins/sumba-maps) | [Docs](https://ardhi.github.io/sumba-maps) | sumbaMaps | smaps | Sumba Maps |
83
+ | [@sumba/proxy](https://bajo.app/premium-plugins/sumba-proxy) | [Docs](https://ardhi.github.io/sumba-proxy) | sumbaProxy | proxy | Sumba Proxy: Cache any web resources locally |
84
+ | [@sumba/seatrack](https://bajo.app/premium-plugins/sumba-seatrack) | [Docs](https://ardhi.github.io/sumba-seatrack) | sumbaSeatrack | seatrack | Sumba Seatrack: AIS tracking |
85
+ | [@sumba/seatrack-global](https://bajo.app/premium-plugins/sumba-seatrack-global) | [Docs](https://ardhi.github.io/sumba-seatrack-global) | sumbaSeatrackGlobal | seatrack-global | Sumba Seatrack Global: AIS tracking by Rappid Datahub |
86
+ | [@sumba/seatrack-vts](https://bajo.app/premium-plugins/sumba-seatrack-vts) | [Docs](https://ardhi.github.io/sumba-seatrack-vts) | sumbaSeatrackVts | seatrack-vts | Sumba Seatrack VTS: VTS Support for Sumba Seatrack |
87
+ | [@sumba/seatrack-wpi](https://bajo.app/premium-plugins/sumba-seatrack-wpi) | [Docs](https://ardhi.github.io/sumba-seatrack-wpi) | sumbaSeatrackWpi | seatrack-wpi | Sumba Seatrack WPI: WPI Support for Sumba Seatrack |
88
+ | [@sumba/skytrack](https://bajo.app/premium-plugins/sumba-skytrack) | [Docs](https://ardhi.github.io/sumba-skytrack) | sumbaSkytrack | skytrack | Sumba Skytrack: ADSB tracking |
89
+ | [@sumba/skytrack-global](https://bajo.app/premium-plugins/sumba-skytrack-global) | [Docs](https://ardhi.github.io/sumba-skytrack-global) | sumbaSkytrackGlobal | skytrack-global | Sumba Skytrack: ADSB tracking by Rappid Datahub |
90
+ | [@sumba/store](https://bajo.app/premium-plugins/sumba-store) | [Docs](https://ardhi.github.io/sumba-store) | sumbaStore | store | Sumba Store: E-Commerce & online stores |
91
+ | [@sumba/subscription](https://bajo.app/premium-plugins/sumba-subscription) | [Docs](https://ardhi.github.io/sumba-subscription) | sumbaSubscription | subs | Sumba Subscription: Member subscriptions |
92
+ | [@sumba/weather](https://bajo.app/premium-plugins/sumba-weather) | [Docs](https://ardhi.github.io/sumba-weather) | sumbaWeather | weather | Sumba Weather by Rappid Datahub |
93
+ | [@sumba/webstat](https://bajo.app/premium-plugins/sumba-webstat) | [Docs](https://ardhi.github.io/sumba-webstat) | sumbaWebstat | webstat | Sumba Web Statistic |
@@ -0,0 +1,356 @@
1
+ # Getting Started
2
+
3
+ This is the quickstart guide for getting started with Bajo, a framework for building robust and scalable applications. This section covers essential steps for beginners, including installation, setting up your project structure, and understanding basic configurations. You will be introduced to the core concepts of Bajo's plugin system and lifecycle, learning how to build your first "Hello World!" application and utilize the powerful hook system for custom extensions. This foundation will prepare you to dive into Bajo's specialized sub-frameworks, such as Dobo and Waibu, to further develop your application's capabilities.
4
+
5
+ ## Installation
6
+
7
+ Create a new empty directory named ```my-project```. This will be your app directory throughout this tutorial. Now, ```cd``` into your newly created directory and type:
8
+
9
+ ```bash
10
+ $ npm init
11
+ ```
12
+
13
+ You'll be asked to name your project, provide its description, author info, etc. Please continue until the *package.json* file is created.
14
+
15
+ Then, open it using your favorite editor, edit it, and insert the following lines:
16
+
17
+ ```javascript
18
+ ...
19
+ "type": "module",
20
+ "bajo": {
21
+ "type": "app"
22
+ },
23
+ ...
24
+ ```
25
+
26
+ After completing these steps, install Bajo by running:
27
+
28
+ ```bash
29
+ $ npm install bajo
30
+ ```
31
+
32
+ Now, create your app's bootstrap file, ```index.js```, and add these lines:
33
+
34
+ ```javascript
35
+ // index.js file
36
+ import bajo from 'bajo'
37
+ await bajo()
38
+ ```
39
+
40
+ A Bajo-based app **ALWAYS** needs a data directory for its config files, etc. This directory can be located inside or outside your app directory. If this directory doesn't exist yet, Bajo will create a new one for you, named ```data```, in the same location as your ```index.js``` file. By default, Bajo will set this as your data directory.
41
+
42
+ Bajo will also automatically create the ```main``` directory to serve as your main plugin if it doesn't already exist. A factory file named ```index.js``` will be added inside the ```main``` directory. More on this later in the next chapter.
43
+
44
+ Now, run your app:
45
+
46
+ ```bash
47
+ $ node index.js
48
+ ```
49
+
50
+ Congratulations! Your Bajo-based app is up and running!
51
+
52
+ ## Playing Around
53
+
54
+ By now, your directory structure should look like this:
55
+
56
+ ```
57
+ .
58
+ └── my-project
59
+ ├── data
60
+ │ └── config
61
+ ├── main
62
+ │ └── index.js
63
+ ├── node_modules
64
+ │ └── ...
65
+ ├── index.js
66
+ ├── package.json
67
+ └── package-lock.json
68
+ ```
69
+ Your app runs in the ```dev``` environment by default. In this environment, the log level is set to ```debug```, which can be overridden using program arguments:
70
+
71
+ ```bash
72
+ $ node index.js --log-level=trace --log-timeTaken --log-pretty
73
+ ```
74
+
75
+ Now, Bajo will show you a bunch of pretty, colorful logs, including the time each step took. This is very useful for debugging and for finding out which activity takes the most time.
76
+
77
+ But typing program arguments is tedious and boring. Let's use a config file to do some magic. Please create the JSON file ```data/config/bajo.json``` and add these lines to it:
78
+
79
+ ```json
80
+ {
81
+ "env": "dev",
82
+ "log": {
83
+ "pretty": true,
84
+ "level": "trace",
85
+ "timeTaken": true
86
+ }
87
+ }
88
+ ```
89
+
90
+ Now, try simply running your app without any arguments:
91
+
92
+ ```bash
93
+ $ node index.js
94
+ ```
95
+
96
+ Much better! And hassle-free!
97
+
98
+ You can mix and match config file and program arguments on any key-value pairs anytime you want. You can even utilize environment variables and a dotenv ```.env``` file if you really need to. Please read the *User Guide* for more in-depth information on this.
99
+
100
+ ## Your First Project
101
+
102
+ Let's start with **Hello World!**, the Bajo way.
103
+
104
+ The objectives of this short course are:
105
+ 1. reading values ​​from the configuration
106
+ 2. copying those values ​​into properties in the main plugin during initialization
107
+ 3. displaying values ​​while the program is running
108
+ 4. notifying if the program terminates
109
+
110
+ Let's go!
111
+
112
+ ### Config Object
113
+
114
+ Please open the ```data/config/main.json``` file or create a new one if it doesn't exist. This is the main plugin configuration file.
115
+
116
+ Enter these lines:
117
+
118
+ ```json
119
+ {
120
+ "firstName": "Tanjiro",
121
+ "lastName": "Kamado",
122
+ "age": 15
123
+ }
124
+ ```
125
+
126
+ Each Bajo plugin can be configured through the configuration file located at ```{dataDir}/config/{ns}.json```, where ```{dataDir}``` is the data directory location and ```{ns}``` is the namespace or plugin name. Please visit [User Guide](USER-GUIDE.md) for more info.
127
+
128
+ As you may know now, in Bajo, you create everything through plugins. If your project is small or not very complicated, you can use the main plugin that's always ready and available. But over time, as your app gets bigger and bigger, you'll need to start thinking about breaking things into small pieces through independent plugins.
129
+
130
+ If you intend to create your own customized plugin, refer to the [Developer Guide](DEV-GUIDE.md).
131
+
132
+ ### Plugin Factory
133
+
134
+ Now let's open ```main/index.js``` and update it according to the example below.
135
+
136
+ This file is the main plugin factory. It gets created automatically if it's not there.
137
+
138
+ ```javascript
139
+ async function factory (pkgName) {
140
+ const me = this
141
+
142
+ return class Main extends this.app.pluginClass.base {
143
+ constructor () {
144
+ super(pkgName, me.app)
145
+ this.config = {}
146
+ }
147
+
148
+ init = async () => {
149
+ this.firstName = this.config.firstName
150
+ this.lastName = this.config.lastName
151
+ this.age = this.config.age
152
+ }
153
+
154
+ start = async () => {
155
+ this.log.info('First name: %s, Last name: %s, age: %d', this.firstName, this.lastName, this.age)
156
+ }
157
+
158
+ exit = async () => {
159
+ this.log.warn('Program aborted')
160
+ }
161
+ }
162
+ }
163
+
164
+ export default factory
165
+ ```
166
+
167
+ A couple of things to note:
168
+
169
+ - At boot, the main plugin reads its configuration file main.json and merges it with all program arguments and environment variables it can find which belong to it and builds its config object.
170
+ - Then, plugin initialization happens. In this step, all code inside the asynchronous method ```init``` will be executed. In this example, all object config's key-value pairs will be assigned to the plugin's properties.
171
+ - Then, the plugin will start. All code inside the asynchronous method ```start``` will be invoked. In this example, it simply writes the first name, last name, and age to the logger.
172
+ - At program exit, the asynchronous method ```exit``` will be executed.
173
+
174
+ That's the lifecycle of all Bajo plugins, including the main plugin.
175
+
176
+ But unfortunately, if you run it now, you'll get an error. That's because the root keys of the config object from the configuration file (```firstName```, ```lastName```, and ```age```) aren't defined in ```this.config``` and are ignored during initialization.
177
+
178
+ That's why we need to fix it first:
179
+
180
+ ```
181
+ ...
182
+ constructor () {
183
+ super(pkgName, me.app)
184
+ this.config = {
185
+ firstName: 'John',
186
+ lastName: 'Doe',
187
+ age: 50
188
+ }
189
+ }
190
+ ...
191
+ ```
192
+
193
+ ```this.config``` defined in the constructor serves as the default config object. During initialization, this will be merged with values from the configuration file. If one or more keys are missing from the configuration file, the related default values are used.
194
+
195
+ If you run this now, you'll get a bunch of logs. Let's filter it with:
196
+
197
+ ```bash
198
+ $ node index.js --log-level=info
199
+ 2025-09-12T00:09:38.946Z +97ms INFO: main First name: Tanjiro, Last name: Kamado, age: 15
200
+ 2025-09-12T00:09:38.949Z +3ms WARN: main Program aborted
201
+ ```
202
+
203
+ Sweet!
204
+
205
+ ## The Hook System
206
+
207
+ ### Tapping a Hook
208
+
209
+ Bajo offers you a hook system in which you can tap certain actions anywhere in the system with your own code. Let's go through the simplest one: running your code just after the boot process is completed.
210
+
211
+ First, create ```main/extend/bajo/hook/bajo@after-boot-complete.js```. If you're curious about the reason for the unusual file name, please refer to the [User Guide](USER-GUIDE.md) on Hook's naming rules.
212
+
213
+ ```javascript
214
+ async function afterBootComplete () {
215
+ this.log.info('Hook after boot complete')
216
+ }
217
+
218
+ export default afterBootComplete
219
+ ```
220
+
221
+ Pretty easy, right?
222
+
223
+ ### Your Own Hook
224
+
225
+ Now let's create your own hook. Even though it's silly to use a hook for such a simple program, its purpose is to demonstrate how easy it is to do it in Bajo.
226
+
227
+ This time, we want to change the property ```lastName``` with hook.
228
+
229
+ Open ```index.js``` and update it accordingly:
230
+
231
+ ```javascript
232
+ ...
233
+ init = async () => {
234
+ const { runHook } = this.app.bajo // add this line
235
+ this.firstName = this.config.firstName
236
+ this.lastName = this.config.lastName
237
+ this.age = this.config.age
238
+ await runHook('main:myHook') // and this line
239
+ }
240
+ ...
241
+ ```
242
+
243
+ The above code should add a hook named ```main:myHook``` in the initialization step.
244
+
245
+ Now, create a new file ```main/extend/bajo/hook/main@my-hook.js```:
246
+
247
+ ```javascript
248
+ async function myHook () {
249
+ this.lastName = 'THE Daemon Slayer'
250
+ }
251
+
252
+ export default myHook
253
+ ```
254
+
255
+ As every class method, hook, and function handler in Bajo is called within its own plugin scope, it is sufficient to set ```this.lastName``` directly inside a hook.
256
+
257
+ Now run it. It should show you something like these:
258
+
259
+ ```bash
260
+ 2025-09-12T12:09:09.004Z +115ms INFO: main First name: Tanjiro, Last name: THE Daemon Slayer, age: 15
261
+ 2025-09-12T12:09:09.008Z +4ms INFO: main Hook after boot complete
262
+ 2025-09-12T12:09:09.009Z +1ms WARN: main Program aborted
263
+ ```
264
+
265
+ ## Using Plugins
266
+
267
+ Bajo is designed to be an ecosystem with many small plugins. Think of Lego blocks: you build a structure just by picking up the right ones and sticking them together to create your very own structure.
268
+
269
+ In this series, we'll learn how to use such plugins to extend our app.
270
+
271
+ ### File Format
272
+
273
+ We love YAML format so much so let's use it for our configuration file:
274
+
275
+ 1. YAML support is part of the ```bajo-config``` plugin, so we need to install it first
276
+ ```bash
277
+ $ npm install bajo-config
278
+ ```
279
+ 2. Now, open the ```data/config/.plugins``` file and put ```bajo-config``` in it, line by line. If it doesn't exist yet, create it first. Don't worry about the order; Bajo will figure it out automatically if you have many plugins.
280
+ 3. Delete your old configuration file ```data/config/main.json``` and create a new ```data/config/main.yml```. By the way, it doesn't matter whether you use ```.yml``` or ```.yaml```. Both are supported.
281
+ 4. Enter the following lines, it should be the same object as before, just in YAML format:
282
+ ```yaml
283
+ firstName: Tanjiro
284
+ lastName: Kamado
285
+ age: 15
286
+ ```
287
+ 5. Run and check the output. It should be the exact same output as before, except for the log's timestamps.
288
+
289
+ ### Applet Mode
290
+
291
+ **Applets** are small tools embedded in plugins that can be invoked when Bajo is running in **applet mode**. Their lifecycle is totally independent of the main program, but they can reuse the same resources and config objects.
292
+
293
+ You can run Bajo in applet mode by using the ```--applet``` or ```-a``` switches:
294
+
295
+ ```bash
296
+ $ node index.js -a
297
+ ```
298
+
299
+ But applet mode requires you to install ```bajo-cli``` beforehand. So, please install it first:
300
+
301
+ ```bash
302
+ $ npm install bajo-cli
303
+ ```
304
+
305
+ Don't forget to add ```bajo-cli``` to the ```data/config/.plugins``` file. Again, the order doesn't really matter here.
306
+
307
+ If you run it now, you'll see something like this on your terminal:
308
+
309
+ ```bash
310
+ ℹ App runs in applet mode
311
+ ? Please select: (Use arrow keys)
312
+ ❯ bajoConfig
313
+ bajoCli
314
+ ```
315
+
316
+ The first thing to notice is the information that the app is running in applet mode. It's a normal command-line application with a pretty decent UI, and all the logs are gone!
317
+
318
+ By default, logs are turned off in applet mode to give you a clear and distraction-free console. However, during debugging, you might want to turn them on. How? Simply add the ```--log-applet``` switch to your invocation, and your logs will be printed everywhere again.
319
+
320
+ Applets are a way for a Bajo plugin developer to help you by providing small tools for everyday life. It's up to the plugin developer to provide such applets, so don't be surprised if you don't get any built-in applets with some plugins.
321
+
322
+ ### System Info
323
+
324
+ Let's install one more plugin: ```bajo-sysinfo```. This plugin is a thin wrapper around [systeminformation](https://github.com/sebhildebrandt/systeminformation) with a few twists:
325
+
326
+ - It can be called directly as an applet.
327
+ - It is also exported as Waibu REST API endpoints. We'll cover this later in the tutorial.
328
+
329
+ If you try to run your app as shown below (yes, you can have a value for the applet switch; for more details, please [see here](https://github.com/ardhi/bajo-cli)), you'll see something like this after the loading spinner stops:
330
+
331
+ ```bash
332
+ $ node index.js -a bajoSysinfo:battery
333
+ ℹ App runs in applet mode
334
+ ℹ Done!
335
+ ┌──────────────────┬─────────────────────┐
336
+ │ hasBattery │ true │
337
+ ├──────────────────┼─────────────────────┤
338
+ │ cycleCount │ 0 │
339
+ ├──────────────────┼─────────────────────┤
340
+ │ isCharging │ true │
341
+ ├──────────────────┼─────────────────────┤
342
+ │ designedCapacity │ 61998 │
343
+ ├──────────────────┼─────────────────────┤
344
+ │ maxCapacity │ 51686 │
345
+ ├──────────────────┼─────────────────────┤
346
+ ...
347
+ ```
348
+
349
+ ## More
350
+
351
+ Bajo has a lot more to offer. Get ready to dive deeper by continuing your journey with Bajo's sub-frameworks:
352
+
353
+ - [Dobo Database Management System](https://github.com/ardhi/dobo/wiki/GETTING-STARTED.md)
354
+ - [Waibu Web Framework](https://github.com/ardhi/waibu/wiki/GETTING-STARTED.md)
355
+ - [Sumba Biz Suites](https://github.com/ardhi/sumba/wiki/GETTING-STARTED.md)
356
+ - [Masohi Messaging](https://github.com/ardhi/masohi/wiki/GETTING-STARTED.md)