bajo 2.23.0 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.jsdoc.conf.json +2 -1
  2. package/class/app.js +220 -107
  3. package/class/bajo.js +257 -177
  4. package/class/base.js +85 -24
  5. package/class/cache.js +8 -16
  6. package/class/err.js +31 -10
  7. package/class/log.js +46 -38
  8. package/class/plugin.js +53 -30
  9. package/class/print.js +18 -15
  10. package/class/tools.js +17 -7
  11. package/docs/App.html +51 -1
  12. package/docs/Bajo.html +1 -1
  13. package/docs/Base.html +34 -1
  14. package/docs/Cache.html +1 -1
  15. package/docs/Err.html +2 -2
  16. package/docs/Log.html +2 -2
  17. package/docs/Main.html +3 -0
  18. package/docs/Plugin.html +1 -1
  19. package/docs/Print.html +1 -1
  20. package/docs/Tools.html +1 -1
  21. package/docs/class_app.js.html +222 -109
  22. package/docs/class_bajo.js.html +260 -179
  23. package/docs/class_base.js.html +87 -26
  24. package/docs/class_cache.js.html +10 -18
  25. package/docs/class_err.js.html +33 -12
  26. package/docs/class_log.js.html +48 -40
  27. package/docs/class_plugin.js.html +55 -32
  28. package/docs/class_print.js.html +20 -17
  29. package/docs/class_tools.js.html +19 -9
  30. package/docs/data/search.json +1 -1
  31. package/docs/global.html +22 -1
  32. package/docs/index.html +1 -1
  33. package/docs/index.js.html +53 -16
  34. package/docs/lib_applet-hook.js.html +328 -0
  35. package/docs/lib_config.js.html +167 -0
  36. package/docs/lib_helper.js.html +186 -192
  37. package/docs/module-Applet.html +3 -0
  38. package/docs/module-Helper.html +1 -8
  39. package/docs/module-Hook.html +1 -1
  40. package/docs/tutorial-01_WELCOME.html +3 -0
  41. package/docs/tutorial-02_GETTING_STARTED.html +125 -0
  42. package/docs/tutorial-03_USER_GUIDE.html +54 -0
  43. package/docs/tutorial-04_DEV_GUIDE.html +178 -0
  44. package/docs/tutorial-05_ECOSYSTEM.html +3 -0
  45. package/extend/bajo/intl/en-US.json +2 -1
  46. package/extend/bajo/intl/id.json +2 -1
  47. package/index.js +51 -14
  48. package/lib/applet-hook.js +325 -0
  49. package/lib/config.js +164 -0
  50. package/lib/helper.js +185 -191
  51. package/package.json +6 -2
  52. package/test/00-global-hooks.test.js +44 -0
  53. package/test/e2e/_run.js +19 -0
  54. package/test/e2e/e2e-applet-process.test.js +66 -0
  55. package/test/e2e/e2e-boot-process.test.js +62 -0
  56. package/test/e2e/e2e-hooks-process.test.js +68 -0
  57. package/test/integration/_setup.js +55 -0
  58. package/test/integration/aspect-01-boot-instance.test.js +24 -0
  59. package/test/integration/aspect-02-plugin-loading.test.js +24 -0
  60. package/test/integration/aspect-03-config-merge.test.js +27 -0
  61. package/test/integration/aspect-04-intl-loading.test.js +29 -0
  62. package/test/integration/aspect-05-cache-roundtrip.test.js +26 -0
  63. package/test/integration/aspect-06-log-file-save.test.js +28 -0
  64. package/test/integration/aspect-07-plugin-data-dir.test.js +25 -0
  65. package/test/integration/aspect-08-plugin-lookup.test.js +25 -0
  66. package/test/integration/aspect-09-config-formats.test.js +26 -0
  67. package/test/integration/aspect-10-hooks.test.js +38 -0
  68. package/test/unit/app.test.js +115 -0
  69. package/test/unit/applet-hook.test.js +10 -0
  70. package/test/unit/bajo.test.js +151 -0
  71. package/test/unit/base.test.js +90 -0
  72. package/test/unit/cache.test.js +89 -0
  73. package/test/unit/config.test.js +14 -0
  74. package/test/unit/err.test.js +57 -0
  75. package/test/unit/helper.test.js +116 -0
  76. package/test/unit/index.test.js +40 -0
  77. package/test/unit/log.test.js +84 -0
  78. package/test/unit/plugin.test.js +95 -0
  79. package/test/unit/print.test.js +72 -0
  80. package/test/unit/tools.test.js +29 -0
  81. package/wiki/CHANGES.md +10 -0
  82. package/wiki/tutorials/01_WELCOME.md +18 -0
  83. package/wiki/tutorials/02_GETTING_STARTED.md +366 -0
  84. package/wiki/tutorials/03_USER_GUIDE.md +262 -0
  85. package/wiki/tutorials/04_DEV_GUIDE.md +386 -0
  86. package/wiki/tutorials/05_ECOSYSTEM.md +95 -0
  87. package/wiki/tutorials/tutorials.json +17 -0
  88. package/docs/lib_hook.js.html +0 -231
  89. package/docs/module-Lib.html +0 -3
  90. package/lib/hook.js +0 -228
  91. package/test/app.test.js +0 -183
  92. package/test/bajo.test.js +0 -124
  93. package/test/base.test.js +0 -75
  94. package/test/cache.test.js +0 -94
  95. package/test/e2e.test.js +0 -137
  96. package/test/err.test.js +0 -73
  97. package/test/helper.test.js +0 -39
  98. package/test/import-module.test.js +0 -138
  99. package/test/integration.test.js +0 -218
  100. package/test/log.test.js +0 -119
  101. package/test/plugin.test.js +0 -116
  102. package/test/print.test.js +0 -100
  103. package/test/tools.test.js +0 -38
  104. package/wiki/CONFIG.md +0 -36
  105. package/wiki/DEV_GUIDE.md +0 -3
  106. package/wiki/ECOSYSTEM.md +0 -93
  107. package/wiki/GETTING-STARTED.md +0 -356
  108. package/wiki/USER-GUIDE.md +0 -256
package/class/plugin.js CHANGED
@@ -4,12 +4,14 @@ import Err from './err.js'
4
4
  const { get, isEmpty, cloneDeep, omit, isPlainObject, camelCase } = lodash
5
5
 
6
6
  /**
7
- * This is the **mother** of all plugin classes. All Bajo plugin classess inherit from this class
8
- * respectfully.
7
+ * The **root** plugin class. All Bajo plugin classes inherit from this class respectfully.
9
8
  *
10
- * There are currently only two main plugins available:
11
- * - {@link Bajo} - Core plugin class, responsible for system wide setup and boot process. You should not touch this obviously.
12
- * - {@link Base} - Base plugin class your own plugin should inherite from.
9
+ * This class provides the basic structure and functionality for all plugins in the Bajo framework.
10
+ * It includes methods for configuration management, error handling, logging, and more.
11
+ *
12
+ * Only two direct descendants of this class are allowed:
13
+ * - {@link Bajo} - Bajo core plugin class, responsible for system wide setup and boot process. You should not touch this obviously
14
+ * - {@link Base} - Base plugin class **your own plugin should inherit from**
13
15
  *
14
16
  * @class
15
17
  */
@@ -39,7 +41,9 @@ class Plugin {
39
41
  * Plugin alias. Derived plugin must provide its own, unique alias. If it left blank,
40
42
  * Bajo will provide this automatically (by using the kebab-cased version of plugin name).
41
43
  *
42
- * @readonly
44
+ * By convention, plugin alias should be all lower case, alphanumeric, and without any space or special character except `-`.
45
+ * It should be unique across all plugins in the Bajo framework, as it is used to identify the plugin in the system beside its namespace.
46
+ *
43
47
  * @type {string}
44
48
  */
45
49
  this.alias = null
@@ -53,7 +57,7 @@ class Plugin {
53
57
  /**
54
58
  * Configuration object.
55
59
  *
56
- * @type {Object}
60
+ * @type {TConfig}
57
61
  * @see {@tutorial config}
58
62
  */
59
63
  this.config = {}
@@ -75,7 +79,7 @@ class Plugin {
75
79
  }
76
80
 
77
81
  /**
78
- * Get package info.
82
+ * Get package info. Basically it reads the package.json file and returns the requested fields
79
83
  *
80
84
  * @method
81
85
  * @param {string} [dir] - Package directory. Defaults to the current plugin's package dir
@@ -91,14 +95,18 @@ class Plugin {
91
95
  }
92
96
 
93
97
  /**
94
- * Get plugin's config value.
98
+ * Get plugin's configuration object's value.
99
+ *
100
+ * > **Note**: Configuration object is frozen after boot process, so you can't modify it at runtime.
101
+ * If you want to change its values, you need to do it in the config file, program options or via environment variables.
102
+ * Hooks are also available to modify the configuration before the boot process.
95
103
  *
96
104
  * @method
97
105
  * @param {string} [path] - dot separated config path (think of lodash's 'get'). If not provided, the full config will be given
98
106
  * @param {Object} [options={}] - Options object
99
107
  * @param {any} [options.defValue={}] - Default value to use if returned object is undefined
100
108
  * @param {string[]} [options.omit=[]] - Omit these keys from returned object
101
- * @param {boolean} [options.noClone=false] - Set true to NOT clone returned object
109
+ * @param {boolean} [options.noClone=false] - Set true to **NOT clone** returned object
102
110
  * @returns {Object} Returned object. If no path provided, the whole config object is returned
103
111
  */
104
112
  getConfig = (path, options = {}) => {
@@ -110,12 +118,18 @@ class Plugin {
110
118
  }
111
119
 
112
120
  /**
113
- * Create an instance of {@link Err} object.
121
+ * Create an instance of {@link Err} object by providing an error message and optional arguments. Error instance will
122
+ * then be displayed on console and returned so you can chain it with other methods if you want.
123
+ *
124
+ * Typically, you would use this method to throw an error and the framework will handle it gracefully.
125
+ *
126
+ * This method is a shortcut to create a new Err instance.
114
127
  *
115
128
  * @method
116
129
  * @param {string} msg - Error message
117
- * @param {...any} [args] - Argument variables you might want to add to the error object
130
+ * @param {...*} [args] - Argument variables you might want to add to the error object
118
131
  * @returns {Err} Err instance
132
+ * @see {@link Err#write}
119
133
  */
120
134
  error = (msg, ...args) => {
121
135
  if (!this.print) return new Error(msg, ...args)
@@ -124,12 +138,11 @@ class Plugin {
124
138
  }
125
139
 
126
140
  /**
127
- * Create an instance of Err object, display it on screen and then force
128
- * terminate the app.
141
+ * Same as {@link Plugin#error} but will *forcefully* terminate the process after printing the error to console.
129
142
  *
130
143
  * @method
131
144
  * @param {string} msg - Error message
132
- * @param {...any} [args] - Argument variables you might want to add to the error object
145
+ * @param {...*} [args] - Argument variables you might want to add to the error object
133
146
  * @returns {void}
134
147
  */
135
148
  fatal = (msg, ...args) => {
@@ -145,46 +158,56 @@ class Plugin {
145
158
  *
146
159
  * @method
147
160
  * @param {string} text - Text to translate
148
- * @param {...any} params - Variables to interpolate to `text`
161
+ * @param {...*} args - Arguments to interpolate to `text`
149
162
  * @returns {string}
163
+ * @see {@link App#t}
150
164
  */
151
- t = (text, ...params) => {
152
- return this.app.t(this.ns, text, ...params)
165
+ t = (text, ...args) => {
166
+ return this.app.t(this.ns, text, ...args)
153
167
  }
154
168
 
155
169
  /**
156
- * Check whether translation text/key exists.
170
+ * Check whether translation text (key) exists.
157
171
  *
158
172
  * Shortcut to {@link App#te} with ns parameter set to this plugin namespace.
159
173
  *
160
174
  * @method
161
175
  * @param {string} text - Text to translate
162
- * @param {...any} params - Variables to interpolate to `text`
163
- * @returns {string}
176
+ * @param {...*} args - Arguments to interpolate to `text`
177
+ * @returns {boolean}
178
+ * @see {@link App#te}
164
179
  */
165
- te = (text, ...params) => {
166
- return this.app.te(this.ns, text, ...params)
180
+ te = (text, ...args) => {
181
+ return this.app.te(this.ns, text, ...args)
167
182
  }
168
183
 
169
184
  /**
170
- * Force bind methods to self (`this`).
185
+ * Force bind methods to `this` context.
186
+ *
187
+ * Since JavaScript's `this` is dynamic, this method is useful to ensure
188
+ * that the methods always refer to the correct instance of the class.
171
189
  *
190
+ * Typically, you would call this method in the constructor of your plugin class,
191
+ * passing an array of method names or imported functions that you want to bind.
172
192
  * @method
173
- * @param {string[]} names - Method's names
193
+ * @param {...(string|function)} names - Method's names or function references to bind to `this` context
174
194
  * @returns {void}
175
195
  */
176
- selfBind (names) {
177
- if (!Array.isArray(names)) names = [names]
196
+ bindThis (...names) {
178
197
  for (const name of names) {
179
- this[name] = this[name].bind(this)
198
+ if (typeof name === 'string') this[name] = this[name].bind(this)
199
+ else if (typeof name === 'function') {
200
+ const methodName = name.name
201
+ this[methodName] = name.bind(this)
202
+ }
180
203
  }
181
204
  }
182
205
 
183
206
  /**
184
- * Alias to `this.app.dump()`.
207
+ * Shortcut to `this.app.dump()`.
185
208
  *
186
209
  * @method
187
- * @param {...any} args - Arguments
210
+ * @param {...*} args - Arguments
188
211
  * @returns {void}
189
212
  */
190
213
  dump = (...args) => {
package/class/print.js CHANGED
@@ -23,12 +23,14 @@ const { isPlainObject } = lodash
23
23
  * Features many methods to display things on screen/console using {@link https://github.com/sindresorhus/ora|ora}
24
24
  * based spinner.
25
25
  *
26
+ * You don't need to instantiate this class directly, since every plugin instance already has a built-in `print` property you can use
27
+ * to access this class instance.
28
+ *
26
29
  * @class
27
30
  */
28
31
  class Print extends Tools {
29
32
  /**
30
- * @param {Plugin} plugin Plugin instance.
31
- * @param {Print.TOptions} [options={}] Options object.
33
+ * Constructor.
32
34
  */
33
35
  constructor (plugin, options = {}) {
34
36
  super(plugin)
@@ -52,6 +54,7 @@ class Print extends Tools {
52
54
 
53
55
  /**
54
56
  * ora instance
57
+ * @type {object}
55
58
  * @see {@link https://github.com/sindresorhus/ora|ora}
56
59
  */
57
60
  this.ora = ora(this.options.ora)
@@ -62,10 +65,10 @@ class Print extends Tools {
62
65
  * Setting spinner options; override the one passed at constructor.
63
66
  *
64
67
  * @method
65
- * @param {any[]} - [args=[]] Array of options. If the last argument is an object, it will be used to override ora options
68
+ * @param {...*} args - Arguments. If the last argument is an object, it will be used to override the current options.
66
69
  * @returns {void}
67
70
  */
68
- setOpts = (args = []) => {
71
+ setOpts = (...args) => {
69
72
  const { silent } = this.app.bajo.config
70
73
  let opts = {}
71
74
  if (isPlainObject(args.slice(-1)[0])) opts = args.pop()
@@ -77,12 +80,12 @@ class Print extends Tools {
77
80
  * Translate text, prefixed with counter and/or datetime etc.
78
81
  *
79
82
  * @param {string} text - Text to translate
80
- * @param {...any} [args] - Any variable to interpolate text translation. If the last argument is an object, it will be used to override ora's options.
83
+ * @param {...*} [args] - Arguments to interpolate text translation. If the last argument is an object, it will be used to override ora's options.
81
84
  * @returns {string}
82
85
  */
83
86
  buildText = (text, ...args) => {
84
87
  text = this.plugin.t(text, ...args)
85
- this.setOpts(args)
88
+ this.setOpts(...args)
86
89
  const prefixes = []
87
90
  if (this.options.showDatetime) prefixes.push('[' + this.app.lib.dayjs().toISOString() + ']')
88
91
  if (this.options.showCounter) prefixes.push('[' + this.getElapsed() + ']')
@@ -96,7 +99,7 @@ class Print extends Tools {
96
99
  *
97
100
  * @method
98
101
  * @param {string} text - Text to use
99
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora's options
102
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora's options
100
103
  * @returns {Print} Return the instance itself, usefull for method chaining
101
104
  */
102
105
  setText = (text, ...args) => {
@@ -124,11 +127,11 @@ class Print extends Tools {
124
127
  *
125
128
  * @method
126
129
  * @param {string} text - Text to use
127
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora's options
130
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora's options
128
131
  * @returns {Print} Return the instance itself, usefull for method chaining
129
132
  */
130
133
  start = (text, ...args) => {
131
- this.setOpts(args)
134
+ this.setOpts(...args)
132
135
  this.setText(text, ...args)
133
136
  this.ora.start()
134
137
  return this
@@ -150,7 +153,7 @@ class Print extends Tools {
150
153
  *
151
154
  * @method
152
155
  * @param {string} text - Text to use
153
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora options.
156
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora options.
154
157
  * @returns {Print} Return the instance itself, usefull for method chaining
155
158
  */
156
159
  succeed = (text, ...args) => {
@@ -164,7 +167,7 @@ class Print extends Tools {
164
167
  *
165
168
  * @method
166
169
  * @param {string} text - Text to use
167
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora options
170
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora options
168
171
  * @returns {Print} Return the instance itself, usefull for method chaining
169
172
  */
170
173
  fail = (text, ...args) => {
@@ -178,7 +181,7 @@ class Print extends Tools {
178
181
  *
179
182
  * @method
180
183
  * @param {string} text - Text to use
181
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora options
184
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora options
182
185
  * @returns {Print} Return the instance itself, usefull for method chaining
183
186
  */
184
187
  warn = (text, ...args) => {
@@ -192,7 +195,7 @@ class Print extends Tools {
192
195
  *
193
196
  * @method
194
197
  * @param {string} text - Text to use
195
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora options
198
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora options
196
199
  * @returns {Print} Return the instance itself, usefull for method chaining
197
200
  */
198
201
  info = (text, ...args) => {
@@ -228,7 +231,7 @@ class Print extends Tools {
228
231
  *
229
232
  * @method
230
233
  * @param {string} text - Text to use
231
- * @param {...any} [args] - Any variable to interpolate text. If the last argument is an object, it will be used to override ora options
234
+ * @param {...*} [args] - Arguments to interpolate text. If the last argument is an object, it will be used to override ora options
232
235
  * @returns {void}
233
236
  */
234
237
  fatal = (text, ...args) => {
@@ -243,7 +246,7 @@ class Print extends Tools {
243
246
  }
244
247
 
245
248
  /**
246
- * Create a new print instance.
249
+ * Create a new Print instance.
247
250
  *
248
251
  * @method
249
252
  * @param {App.TOptions} [options] Options object. If not provided, defaults to the current options.
package/class/tools.js CHANGED
@@ -1,33 +1,43 @@
1
1
  /**
2
- * Tools class.
2
+ * Tools class. Basic utility class that provides common functionalities for other classes to extend.
3
+ * It serves as a base class for error handling, printing, and other utility operations.
3
4
  *
4
5
  * @class
5
6
  */
6
7
  class Tools {
7
8
  constructor (plugin) {
8
9
  /**
9
- * Attached plugin
10
+ * Reference to the plugin instance that this Tools class is associated with
10
11
  * @type {Plugin}
11
12
  */
12
13
  this.plugin = plugin
13
14
 
14
15
  /**
15
- * The app instance
16
+ * Reference to the app instance
16
17
  * @type {App}
17
18
  */
18
19
  this.app = plugin.app
19
20
  }
20
21
 
21
22
  /**
22
- * Force bind methods to self (`this`).
23
+ * Force bind methods to `this` context.
23
24
  *
25
+ * Since JavaScript's `this` is dynamic, this method is useful to ensure
26
+ * that the methods always refer to the correct instance of the class.
27
+ *
28
+ * Typically, you would call this method in the constructor of your plugin class,
29
+ * passing an array of method names or imported functions that you want to bind.
24
30
  * @method
25
- * @param {string[]} names - Method's names
31
+ * @param {...(string|function)} names - Method's names or function references to bind to `this` context
26
32
  * @returns {void}
27
33
  */
28
- selfBind (names) {
34
+ bindThis (...names) {
29
35
  for (const name of names) {
30
- this[name] = this[name].bind(this)
36
+ if (typeof name === 'string') this[name] = this[name].bind(this)
37
+ else if (typeof name === 'function') {
38
+ const methodName = name.name
39
+ this[methodName] = name.bind(this)
40
+ }
31
41
  }
32
42
  }
33
43
 
package/docs/App.html CHANGED
@@ -1,3 +1,53 @@
1
1
  <!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Class: App</title><!--[if lt IE 9]>
2
2
  <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
3
- <![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="light"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">Bajo API</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="App.html">App</a></div><div class="sidebar-section-children"><a href="Bajo.html">Bajo</a></div><div class="sidebar-section-children"><a href="Base.html">Base</a></div><div class="sidebar-section-children"><a href="Cache.html">Cache</a></div><div class="sidebar-section-children"><a href="Err.html">Err</a></div><div class="sidebar-section-children"><a href="Log.html">Log</a></div><div class="sidebar-section-children"><a href="Plugin.html">Plugin</a></div><div class="sidebar-section-children"><a href="Print.html">Print</a></div><div class="sidebar-section-children"><a href="Tools.html">Tools</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div><div class="sidebar-section-children"><a href="module-Hook.html">Hook</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#boot">boot</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/bajo" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/bajo" target="">Github</a></div><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section><header><h1 id="App-title" class="has-anchor">App</h1><div class="class-description"><p>App class. This is the root. This is where all plugins call it home.</p></div></header><article><div class="container-overview"><h2 id="constructor" class="has-anchor">Constructor</h2><h3 class="name has-anchor" id="App"><span class="type-signature"></span>new App<span class="signature">(options<span class="signature-attributes">opt</span>)</span></h3><div class="description"><p>Constructor.</p></div><div class="method-member-container flex flex-col w-100 overflow-auto mt-20"><strong>Parameters:</strong><table class="params"><thead><tr><th>Name</th><th>Type</th><th>Attributes</th><th>Default</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>options</code></td><td class="type"><span class="param-type"><a href="App.html#.TOptions">App.<wbr>TOptions</a></span></td><td class="attributes">&lt;optional><br></td><td class="default">{}</td><td class="description last"><p>Options object.</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line80">line 80</a></li></ul></dd></div></dl></div><h2 id="members" class="subsection-title has-anchor">Members</h2><h3 class="name has-anchor" id="applet"><span class="type-signature"></span>applet<span class="type-signature"> :string</span></h3><div class="description"><p>If app runs in applet mode, this will be the applet's name.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">string</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line170">line 170</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="applets"><span class="type-signature"></span>applets<span class="type-signature"> :Array</span></h3><div class="description"><p>Applets container.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Array</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line114">line 114</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="args"><span class="type-signature"></span>args<span class="type-signature"> :Array.&lt;string></span></h3><div class="description"><p>Parsed program arguments.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Array.&lt;string></span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line181">line 181</a></li></ul></dd></div><div class="details-item-container"><dt class="tag-see bold">See</dt><dd class="tag-see"><ul><li>module:Helper.parseArgsArgv</li></ul></dd></div></dl><b>Example</b><div class="rel"><pre class="prettyprint"><code>$ node index.js arg1 arg2
3
+ <![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="light"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">Bajo API</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-01_WELCOME.html">Welcome</a></div><div class="sidebar-section-children"><a href="tutorial-02_GETTING_STARTED.html">Getting Started</a></div><div class="sidebar-section-children"><a href="tutorial-03_USER_GUIDE.html">User Guide</a></div><div class="sidebar-section-children"><a href="tutorial-04_DEV_GUIDE.html">Developer Guide</a></div><div class="sidebar-section-children"><a href="tutorial-05_ECOSYSTEM.html">Ecosystem</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="App.html">App</a></div><div class="sidebar-section-children"><a href="Bajo.html">Bajo</a></div><div class="sidebar-section-children"><a href="Base.html">Base</a></div><div class="sidebar-section-children"><a href="Cache.html">Cache</a></div><div class="sidebar-section-children"><a href="Err.html">Err</a></div><div class="sidebar-section-children"><a href="Log.html">Log</a></div><div class="sidebar-section-children"><a href="Main.html">Main</a></div><div class="sidebar-section-children"><a href="Plugin.html">Plugin</a></div><div class="sidebar-section-children"><a href="Print.html">Print</a></div><div class="sidebar-section-children"><a href="Tools.html">Tools</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-Applet.html">Applet</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div><div class="sidebar-section-children"><a href="module-Hook.html">Hook</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#boot">boot</a></div><div class="sidebar-section-children"><a href="global.html#package%25C2%25B7json">package·json</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/bajo" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/bajo" target="">Github</a></div><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section><header><h1 id="App-title" class="has-anchor">App</h1><div class="class-description"><p>App class. This is the root. This is where all plugins call it home.</p><p>This class should not be instantiated directly (see example in <a href="App.html#.TOptions">App.TOptions</a> if you feel adventurous). Instead, use the default <a href="global.html#boot">boot</a> script.</p><p>Plugins (including special plugins <a href="Main.html">Main</a> and <a href="Bajo.html">Bajo</a>) are loaded and attached as property members of this class. They can be accessed using their name/namespace.</p><p>In every plugin there is a reference to this class instance, so they can call each other easily, e.g. in your plugin method, you would call other plugin's method like this <code>this.app.otherPlugin.method()</code>.</p><p>A typical Bajo app should follow the following structure:</p><pre class="prettyprint source"><code>my-app
4
+ |-- package.json
5
+ |-- index.js
6
+ |-- main
7
+ | |-- extend
8
+ | | |-- bajo
9
+ | | | |-- hook
10
+ | | | | | |-- myPlugin:beforeAction.js
11
+ | | | | | |-- myOtherPlugin:afterAction.js
12
+ | | | |-- intl
13
+ | |-- index.js
14
+ |-- data
15
+ | |-- config
16
+ | | |-- .plugins
17
+ | | |-- bajo.yml
18
+ | | |-- myPlugin.yml
19
+ </code></pre></div></header><article><div class="container-overview"><h2 id="constructor" class="has-anchor">Constructor</h2><h3 class="name has-anchor" id="App"><span class="type-signature"></span>new App<span class="signature">(options<span class="signature-attributes">opt</span>)</span></h3><div class="description"><p>Constructor. See <a href="App.html#.TOptions">App.TOptions</a> if you want to write custom boot process for your app without using the default boot module.</p></div><div class="method-member-container flex flex-col w-100 overflow-auto mt-20"><strong>Parameters:</strong><table class="params"><thead><tr><th>Name</th><th>Type</th><th>Attributes</th><th>Default</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>options</code></td><td class="type"><span class="param-type"><a href="App.html#.TOptions">App.<wbr>TOptions</a></span></td><td class="attributes">&lt;optional><br></td><td class="default">{}</td><td class="description last"><p>Options object.</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line156">line 156</a></li></ul></dd></div></dl></div><h2 id="members" class="subsection-title has-anchor">Members</h2><h3 class="name has-anchor" id="applet"><span class="type-signature"></span>applet<span class="type-signature"> :string</span></h3><div class="description"><p>If app runs in <strong>applet</strong> mode, this will be the current applet's name. Otherwise, it will be <code>undefined</code>. See <a href="module-Applet.html">applet</a> for details.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">string</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line268">line 268</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="applets"><span class="type-signature"></span>applets<span class="type-signature"> :Array</span></h3><div class="description"><p>Applets container. Usefull to get all available applets in your app. See <a href="module-Applet.html">applet</a> for details.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Array</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line190">line 190</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="args"><span class="type-signature"></span>args<span class="type-signature"> :Array.&lt;string></span></h3><div class="description"><p>Parsed program arguments.</p><p>Example:</p><pre class="prettyprint source lang-js"><code>$ node index.js arg1 arg2
20
+ ...
21
+ console.log(this.args) // it should print: ['arg1', 'arg2']
22
+ </code></pre></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Array.&lt;string></span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line282">line 282</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="argv"><span class="type-signature"></span>argv<span class="type-signature"> :Object</span></h3><div class="description"><p>Parsed program options:</p><ul><li>Dash (<code>-</code>) breaks the string into object keys</li><li>While colon (<code>:</code>) is used as namespace - object separator. If no such namespace found, it is saved under <code>_</code>.</li></ul><p>Parsed object values are normalized to its primitives using <a href="https://github.com/ladjs/dotenv-parse-variables">dotenv-parse-variables</a></p><pre class="prettyprint source lang-js"><code>$ node index.js --my-name-first=John --my-name-last=Doe --my-birthDay=secret --nameSpace:path-subPath=true
23
+ ...
24
+ // {
25
+ // _: {
26
+ // my: {
27
+ // name: { first: 'John', last: 'Doe' },
28
+ // birthDay: 'secret'
29
+ // }
30
+ // },
31
+ // nameSpace: { path: { subPath: true } }
32
+ // }</code></pre></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line306">line 306</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="baseClass"><span class="type-signature"></span>baseClass<span class="type-signature"> :Object</span></h3><div class="description"><p>All plugin's base classes are saved here for reference so that you can extend them in your own plugins.</p><p>Two basic classes from Bajo package are also provided: <a href="Base.html">Base</a> and <a href="Tools.html">Tools</a>. These are the most used classes in Bajo plugin development. You can extend them to create your own plugin's base class:</p><pre class="prettyprint source lang-javascript"><code>// factory function to create your own plugin's base class
33
+ async function () {
34
+ const { Base } = this.app.baseClass
35
+ class MyBase extends Base {
36
+ constructor(pkgName, app) {
37
+ super(pkgName, app)
38
+ this.myProperty = 'myValue' // your class property
39
+ }
40
+
41
+ async myMethod() {
42
+ // your class method
43
+ }
44
+ }
45
+ }
46
+ </code></pre></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line262">line 262</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="cache"><span class="type-signature"></span>cache<span class="type-signature"> :<a href="Cache.html">Cache</a></span></h3><div class="description"><p>Internal cache instance. This is used to store temporary data in memory for faster access.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type"><a href="Cache.html">Cache</a></span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line332">line 332</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="configHandlers"><span class="type-signature"></span>configHandlers<span class="type-signature"> :Array.&lt;<a href="App.html#.TConfigHandler">App.TConfigHandler</a>></span></h3><div class="description"><p>Config handlers container. This is where all config handlers are stored. Each handler is responsible to read and write config file in a particular format. Bajo uses this heavily to read/write config files and/or anything that needs to be parsed/stringified from string to object and vice versa.</p><p>By default, there are three built-in handlers: <code>.js</code>, <code>.json</code> and <code>.yml/.yaml</code>. Use plugins to add more, e.g <a href="https://github.com/ardhi/bajo-config">bajo-config</a> lets you to use <code>.toml</code>.</p><blockquote><p><em>Note</em>: <code>.js</code> is for reading only, it cannot be used to write config file.</p></blockquote></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Array.&lt;<a href="App.html#.TConfigHandler">App.TConfigHandler</a>></span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line216">line 216</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="envVars"><span class="type-signature"></span>envVars<span class="type-signature"> :Object</span></h3><div class="description"><p>Parsed environment variables. Support dotenv (<code>.env</code>) file too!</p><ul><li>Underscore (<code>_</code>) between keys merge those keys into a single camel-cased key</li><li>Double underscores (<code>__</code>) between keys breaks the key into nested objects</li><li>Meanwhile a dot (<code>.</code>) between keys breaks the key into nested, name-spaced objects</li></ul><p>Parsed object values are normalized to its primitives using <a href="https://github.com/ladjs/dotenv-parse-variables">dotenv-parse-variables</a></p><p>Example:</p><ul><li><code>MY_KEY=secret</code> → <code>{ _: { myKey: 'secret' } }</code></li><li><code>MY_KEY__SUB_KEY=supersecret</code> → <code>{ _: { myKey: { subKey: 'supersecret' } } }</code></li><li><code>MY_NS.MY_NAME=John</code> → <code>{ myNs: { myName: 'John' } }</code></li></ul><blockquote><p><strong>Tips</strong>: During boot process, Bajo will add <code>APPDIR</code> environment variable which points to your app's root directory.</p></blockquote></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line325">line 325</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="envs"><span class="type-signature"></span>envs<span class="type-signature"> :<a href="App.html#.TEnv">App.TEnv</a></span></h3><div class="description"><p>Supported environments. Read-only</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type"><a href="App.html#.TEnv">App.<wbr>TEnv</a></span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line178">line 178</a></li></ul></dd></div></dl><h3 class="name has-anchor" id="lib"><span class="type-signature"></span>lib<span class="type-signature"> :<a href="App.html#.TLib">App.TLib</a></span></h3><div class="description"><p>Gives you direct access to the most commonly used 3rd party library in a Bajo based app. No manual import necessary, always available, anywhere, anytime!</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type"><a href="App.html#.TLib">App.<wbr>TLib</a></span></li></ul></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line227">line 227</a></li></ul></dd></div></dl><b>Example</b><div class="rel"><pre class="prettyprint"><code>const { camelCase, kebabCase } = this.app.lib._
47
+ const translated = this.app.t('main', 'My cute cat is %s', 'purring')
48
+ // or within your plugin
49
+ const translated = this.t('My cute cat is %s', 'purring')
50
+ </code></pre></div><div class="method-member-container flex flex-col w-100 overflow-auto mt-20"><strong>Parameters:</strong><table class="params"><thead><tr><th>Name</th><th>Type</th><th>Attributes</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>ns</code></td><td class="type"><span class="param-type">string</span></td><td class="attributes"></td><td class="description last"><p>Namespace</p></td></tr><tr><td class="name"><code>text</code></td><td class="type"><span class="param-type">string</span></td><td class="attributes"></td><td class="description last"><p>Text to translate</p></td></tr><tr><td class="name"><code>params</code></td><td class="type"><span class="param-type">*</span></td><td class="attributes">&lt;repeatable><br></td><td class="description last"><p>Parameters to interpolate into the translation text</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line663">line 663</a></li></ul></dd></div></dl><div class="method-member-container mt-20"><strong>Returns:</strong><dl class="param-type"><dt>Type:&nbsp;</dt><dd><span class="param-type">string</span></dd></dl></div><h3 class="name has-anchor" id="te"><span class="type-signature"></span>te<span class="signature">(ns, text)</span><span class="type-signature"> &rarr; {boolean}</span></h3><div class="description"><p>Check whether translation text/key exists.</p></div><div class="method-member-container flex flex-col w-100 overflow-auto mt-20"><strong>Parameters:</strong><table class="params"><thead><tr><th>Name</th><th>Type</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>ns</code></td><td class="type"><span class="param-type">string</span></td><td class="description last"><p>Namespace</p></td></tr><tr><td class="name"><code>text</code></td><td class="type"><span class="param-type">string</span></td><td class="description last"><p>Text to translate</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line686">line 686</a></li></ul></dd></div></dl><div class="method-member-container mt-20"><strong>Returns:</strong><dl class="param-type"><dt>Type:&nbsp;</dt><dd><span class="param-type">boolean</span></dd></dl></div><h2 id="type-definitions" class="subsection-title has-anchor">Type Definitions</h2><h3 class="name has-anchor" id=".TConfigHandler">TConfigHandler</h3><div class="description"><p>Config handler definition. Your own handler must follow this structure.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><b class="subsection-title">Properties</b><div class="allow-overflow"><table class="props"><thead><tr><th>Name</th><th>Type</th><th>Attributes</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>ns</code></td><td class="type"><span class="param-type">string</span></td><td class="attributes"></td><td class="description last"><p>Owner plugin namespace</p></td></tr><tr><td class="name"><code>ext</code></td><td class="type"><span class="param-type">string</span></td><td class="attributes"></td><td class="description last"><p>Supported file extension</p></td></tr><tr><td class="name"><code>readHandler</code></td><td class="type"><span class="param-type"><a href="App.html#.readHandler">App.<wbr>readHandler</a></span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Async function to call for reading</p></td></tr><tr><td class="name"><code>writeHandler</code></td><td class="type"><span class="param-type"><a href="App.html#.writeHandler">App.<wbr>writeHandler</a></span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Async function to call for writing</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line75">line 75</a></li></ul></dd></div><div class="details-item-container"><dt class="tag-see bold">See</dt><dd class="tag-see"><ul><li><a href="App.html#configHandlers">App#configHandlers</a></li></ul></dd></div></dl><h3 class="name has-anchor" id=".TEnv">TEnv</h3><div class="description"><p>Supported environments.</p><p>Environment is one of the most important aspect of a Bajo app. It is used to determine how your app should behave in different environments. It allows you to have different configurations and settings, and as a plugin developer, you can also use it to determine how your plugin should behave in different environments.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><b class="subsection-title">Properties</b><div class="allow-overflow"><table class="props"><thead><tr><th>Name</th><th>Type</th><th>Default</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>dev</code></td><td class="type"><span class="param-type">string</span></td><td class="default">development</td><td class="description last"></td></tr><tr><td class="name"><code>stag</code></td><td class="type"><span class="param-type">string</span></td><td class="default">staging</td><td class="description last"></td></tr><tr><td class="name"><code>prod</code></td><td class="type"><span class="param-type">string</span></td><td class="default">production</td><td class="description last"></td></tr><tr><td class="name"><code>test</code></td><td class="type"><span class="param-type">string</span></td><td class="default">testing</td><td class="description last"></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line33">line 33</a></li></ul></dd></div></dl><h3 class="name has-anchor" id=".TLib">TLib</h3><div class="description"><p>Most commonly used libraries by Bajo and its plugins. They are already imported and ready to use, so you don't have to import them again in your plugin.</p><p>Example:</p><pre class="prettyprint source lang-javascript"><code>const { fs, dayjs } = this.app.lib
51
+ fs.ensureDirSync('/path/to/dir')
52
+ const now = dayjs().format('YYYY-MM-DD HH:mm:ss')
53
+ </code></pre></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><b class="subsection-title">Properties</b><div class="allow-overflow"><table class="props"><thead><tr><th>Name</th><th>Type</th><th>Attributes</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>_</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://lodash.com">lodash</a>.</p></td></tr><tr><td class="name"><code>fs</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://github.com/jprichardson/node-fs-extra">fs-extra</a>.</p></td></tr><tr><td class="name"><code>fastGlob</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://github.com/mrmlnc/fast-glob">fast-glob</a>.</p></td></tr><tr><td class="name"><code>sprintf</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://github.com/alexei/sprintf.js">sprintf</a>.</p></td></tr><tr><td class="name"><code>aneka</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://github.com/ardhi/aneka">aneka</a>.</p></td></tr><tr><td class="name"><code>outmatch</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://github.com/axtgr/outmatch">outmatch</a>.</p></td></tr><tr><td class="name"><code>dayjs</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Access to <a href="https://day.js.org">dayjs</a> with utc &amp; customParseFormat plugin already applied.</p></td></tr><tr><td class="name"><code>freeze</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Freeze object. See <a href="module-Helper.html#.freeze">freeze</a> for more details.</p></td></tr><tr><td class="name"><code>findDeep</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Deep file file in an array of files. See <a href="module-Helper.html#.findDeep">findDeep</a> for more details.</p></td></tr><tr><td class="name"><code>outmatchNs</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Like outmatch, but support scoped source &amp; pattern. See <a href="module-Helper.html#.outmatchNs">outmatchNs</a> for more details.</p></td></tr><tr><td class="name"><code>parseObject</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes"></td><td class="description last"><p>Parse object and normalize their values. Also support translation. See <a href="module-Helper.html#.parseObject">parseObject</a> for more details.</p></td></tr><tr><td class="name"><code>anekaSpatial</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Access to <a href="https://ardhi.github.io/bajo-spatial">aneka-spatial</a> helpers if <code>bajoSpatial</code> plugin is loaded.</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="lib_helper.js.html">lib/helper.js</a>, <a href="lib_helper.js.html#line132">line 132</a></li></ul></dd></div><div class="details-item-container"><dt class="tag-see bold">See</dt><dd class="tag-see"><ul><li><a href="App.html">App</a></li></ul></dd></div></dl><h3 class="name has-anchor" id=".TOptions">TOptions</h3><div class="description"><p>Options object passed to <a href="App.html">App</a> constructor. By default, you don't need to pass any options, unless you want to manually override the default behavior.</p></div><div class="member-item-container flex"><strong>Type:</strong><ul><li><span class="param-type">Object</span></li></ul></div><b class="subsection-title">Properties</b><div class="allow-overflow"><table class="props"><thead><tr><th>Name</th><th>Type</th><th>Attributes</th><th class="last">Description</th></tr></thead><tbody><tr><td class="name"><code>cwd</code></td><td class="type"><span class="param-type">string</span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Set current working directory. Defaults to the script directory</p></td></tr><tr><td class="name"><code>plugins</code></td><td class="type"><span class="param-type">Array.&lt;string></span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Array of plugins <strong>package names</strong> to load. If provided, it override the list in <code>package.json</code> and <code>.plugins</code> file</p></td></tr><tr><td class="name"><code>config</code></td><td class="type"><span class="param-type">Object</span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Plugin config objects, with plugin name as keys and their respective config objects as values. If provided, plugin configs will no longer be read from its config files</p></td></tr><tr><td class="name"><code>hooks</code></td><td class="type"><span class="param-type">Array.&lt;<a href="module-Hook.html#.THook">module:Hook.THook</a>></span></td><td class="attributes">&lt;optional><br></td><td class="description last"><p>Array of hooks to be added to the app</p></td></tr></tbody></table></div><dl class="details"><div class="details-item-container"><dt class="tag-source bold">Source</dt><dd class="tag-source"><ul><li><a href="class_app.js.html">class/app.js</a>, <a href="class_app.js.html#line87">line 87</a></li></ul></dd></div></dl><b>Example</b><div class="rel"><pre class="prettyprint"><code>// If you feel adventurous and decide to manually boot your app without the default boot module, here we go,,,
4
54
  plugins: ['my-plugin', 'my-other-plugin'],
5
55
  config: {
6
56
  myPlugin: {
7
57
  // plugin config here
8
58
  },
9
59
  myOtherPlugin: {
10
60
  // plugin config here
11
61
  }
12
62
  },
13
63
  hooks: [{
14
64
  name: 'myPlugin:myHook',
15
65
  handler: async function (arg1, arg2) {
16
66
  // do something with arg1 and arg2
17
67
  }
18
68
  }]
19
69
  }