bajo 2.22.0 → 2.24.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 +258 -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 +6 -5
  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 +8 -7
  30. package/docs/data/search.json +1 -1
  31. package/docs/extend_bajo_hook.js.html +289 -0
  32. package/docs/global.html +22 -1
  33. package/docs/index.html +1 -1
  34. package/docs/index.js.html +53 -16
  35. package/docs/lib_applet-hook.js.html +328 -0
  36. package/docs/lib_config.js.html +167 -0
  37. package/docs/lib_helper.js.html +186 -192
  38. package/docs/module-Applet.html +3 -0
  39. package/docs/module-Helper-Main.html +3 -0
  40. package/docs/module-Helper.html +1 -8
  41. package/docs/module-Hook.html +1 -1
  42. package/docs/tutorial-01_WELCOME.html +3 -0
  43. package/docs/tutorial-02_GETTING_STARTED.html +125 -0
  44. package/docs/tutorial-03_USER_GUIDE.html +54 -0
  45. package/docs/tutorial-04_DEV_GUIDE.html +178 -0
  46. package/docs/tutorial-05_ECOSYSTEM.html +3 -0
  47. package/extend/bajo/intl/en-US.json +2 -1
  48. package/extend/bajo/intl/id.json +2 -1
  49. package/index.js +51 -14
  50. package/lib/applet-hook.js +325 -0
  51. package/lib/config.js +164 -0
  52. package/lib/helper.js +184 -190
  53. package/package.json +6 -2
  54. package/test/00-global-hooks.test.js +44 -0
  55. package/test/e2e/_run.js +19 -0
  56. package/test/e2e/e2e-applet-process.test.js +66 -0
  57. package/test/e2e/e2e-boot-process.test.js +62 -0
  58. package/test/e2e/e2e-hooks-process.test.js +68 -0
  59. package/test/integration/_setup.js +55 -0
  60. package/test/integration/aspect-01-boot-instance.test.js +24 -0
  61. package/test/integration/aspect-02-plugin-loading.test.js +24 -0
  62. package/test/integration/aspect-03-config-merge.test.js +27 -0
  63. package/test/integration/aspect-04-intl-loading.test.js +29 -0
  64. package/test/integration/aspect-05-cache-roundtrip.test.js +26 -0
  65. package/test/integration/aspect-06-log-file-save.test.js +28 -0
  66. package/test/integration/aspect-07-plugin-data-dir.test.js +25 -0
  67. package/test/integration/aspect-08-plugin-lookup.test.js +25 -0
  68. package/test/integration/aspect-09-config-formats.test.js +26 -0
  69. package/test/integration/aspect-10-hooks.test.js +38 -0
  70. package/test/unit/app.test.js +115 -0
  71. package/test/unit/applet-hook.test.js +10 -0
  72. package/test/unit/bajo.test.js +151 -0
  73. package/test/unit/base.test.js +90 -0
  74. package/test/unit/cache.test.js +89 -0
  75. package/test/unit/config.test.js +14 -0
  76. package/test/unit/err.test.js +57 -0
  77. package/test/unit/helper.test.js +116 -0
  78. package/test/unit/index.test.js +40 -0
  79. package/test/unit/log.test.js +84 -0
  80. package/test/unit/plugin.test.js +95 -0
  81. package/test/unit/print.test.js +72 -0
  82. package/test/unit/tools.test.js +29 -0
  83. package/wiki/CHANGES.md +9 -0
  84. package/wiki/tutorials/01_WELCOME.md +18 -0
  85. package/wiki/tutorials/02_GETTING_STARTED.md +366 -0
  86. package/wiki/tutorials/03_USER_GUIDE.md +262 -0
  87. package/wiki/tutorials/04_DEV_GUIDE.md +386 -0
  88. package/wiki/tutorials/05_ECOSYSTEM.md +95 -0
  89. package/wiki/tutorials/tutorials.json +17 -0
  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
@@ -1,6 +1,6 @@
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>Source: class/app.js</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 id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">class_app.js</h1></header><article><pre class="prettyprint source lang-js"><code>import util from 'util'
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 id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">class_app.js</h1></header><article><pre class="prettyprint source lang-js"><code>import util from 'util'
4
4
  import Bajo from './bajo.js'
5
5
  import Base from './base.js'
6
6
  import Cache from './cache.js'
@@ -33,100 +33,186 @@ function getCallerFilename () {
33
33
  }
34
34
 
35
35
  /**
36
+ * Supported environments.
37
+ *
38
+ * Environment is one of the most important aspect of a Bajo app. It is used to determine how your app should behave
39
+ * in different environments. It allows you to have different configurations and settings,
40
+ * and as a plugin developer, you can also use it to determine how your plugin should behave in different environments.
41
+ *
36
42
  * @typedef {Object} TEnv
37
43
  * @memberof App
38
44
  * @property {string} dev=development
45
+ * @property {string} stag=staging
39
46
  * @property {string} prod=production
47
+ * @property {string} test=testing
40
48
  */
41
49
 
42
50
  /**
51
+ * Your read handler must follow this structure. It is used to read and parse config file in a particular format.
52
+ *
43
53
  * @callback readHandler
44
54
  * @memberof App
45
- * @param {string} text - Text to be parsed
46
- * @param {object} options - Options object
55
+ * @async
56
+ * @param {string} text - Text to be parsed or file path to be read if `options.readFromFile` is `true`
57
+ * @param {object|boolean} [options={}] - Options object. If a boolean is provided, it will be treated as `options.readFromFile`
58
+ * @param {boolean} [options.readFromFile=false] - If `true`, `text` is treated as a file path
59
+ * @param {boolean} [options.throwNotFound=false] - If `true`, throw exception if file is not found
60
+ * @param {object} [options.parserOpts={}] - Options to be passed to the parser
47
61
  * @returns {object} Parsed object
48
62
  */
49
63
 
50
64
  /**
65
+ * Your write handler must follow this structure. It is used to write config file in a particular format.
66
+ *
51
67
  * @callback writeHandler
68
+ * @async
52
69
  * @memberof App
53
70
  * @param {Object} data - Data to be stringified
54
- * @param {Object} [options={}] - Options
55
- * @param {boolean} [options.writeToFile=false] - If true, write result to a file
56
- * @param {string} [options.saveAsFile] - The file path to save result if writeToFile is true
71
+ * @param {Object|string} [options={}] - Options object. If a string is provided, it will be treated as `options.writeToFile`
72
+ * @param {string} [options.writeToFile] - If not empty, write result to this file path instead of returning it as string
73
+ * @param {object} [options.parserOpts={}] - Options to be passed to the parser
57
74
  * @returns {string} Stringified result
58
75
  */
59
76
 
60
77
  /**
78
+ * Config handler definition. Your own handler must follow this structure.
79
+ *
61
80
  * @typedef {Object} TConfigHandler
62
81
  * @memberof App
63
- * @property {string} ns - Namespace
64
- * @property {string} ext - File extension
65
- * @property {App.readHandler} [readHandler] - Function to call for reading
66
- * @property {App.writeHandler} [writeHandler] - Function to call for writing
82
+ * @property {string} ns - Owner plugin namespace
83
+ * @property {string} ext - Supported file extension
84
+ * @property {App.readHandler} [readHandler] - Async function to call for reading
85
+ * @property {App.writeHandler} [writeHandler] - Async function to call for writing
86
+ * @see {@link App#configHandlers}
67
87
  */
68
88
 
69
89
  /**
90
+ * Options object passed to {@link App} constructor. By default, you don't need to pass any options,
91
+ * unless you want to manually override the default behavior.
70
92
  * @typedef {Object} TOptions
71
93
  * @memberof App
72
94
  * @property {string} [cwd] - Set current working directory. Defaults to the script directory
73
- * @property {string[]} [plugins] - Array of plugins to load. If provided, it override the list in `package.json` and `.plugins` file
74
- * @property {Object} [config] - Plugin's config object. If provided, plugin configs will no longer be read from its config files
95
+ * @property {string[]} [plugins] - Array of plugins **package names** to load. If provided, it override the list in `package.json` and `.plugins` file
96
+ * @property {Object} [config] - 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
97
+ * @property {module:Hook.THook[]} [hooks] - Array of hooks to be added to the app
98
+ * @example
99
+ * // If you feel adventurous and decide to manually boot your app without the default boot module, here we go,,,
100
+ * import App from 'bajo/class/app.js'
101
+ *
102
+ * const options = {
103
+ * plugins: ['my-plugin', 'my-other-plugin'],
104
+ * config: {
105
+ * myPlugin: {
106
+ * // plugin config here
107
+ * },
108
+ * myOtherPlugin: {
109
+ * // plugin config here
110
+ * }
111
+ * },
112
+ * hooks: [{
113
+ * name: 'myPlugin:myHook',
114
+ * handler: async function (arg1, arg2) {
115
+ * // do something with arg1 and arg2
116
+ * }
117
+ * }]
118
+ * }
119
+ * }
120
+ *
121
+ * const app = new App(options)
75
122
  */
76
123
 
77
124
  /**
78
125
  * App class. This is the root. This is where all plugins call it home.
79
126
  *
127
+ * This class should not be instantiated directly (see example in {@link App.TOptions} if you
128
+ * feel adventurous). Instead, use the default {@link boot|boot} script.
129
+ *
130
+ * Plugins (including special plugins {@link Main} and {@link Bajo}) are loaded and attached as
131
+ * property members of this class. They can be accessed using their name/namespace.
132
+ *
133
+ * In every plugin there is a reference to this class instance, so they can call each other easily,
134
+ * e.g. in your plugin method, you would call other plugin's method like this `this.app.otherPlugin.method()`.
135
+ *
136
+ * A typical Bajo app should follow the following structure:
137
+ * ```
138
+ * my-app
139
+ * |-- package.json
140
+ * |-- index.js
141
+ * |-- main
142
+ * | |-- extend
143
+ * | | |-- bajo
144
+ * | | | |-- hook
145
+ * | | | | | |-- myPlugin:beforeAction.js
146
+ * | | | | | |-- myOtherPlugin:afterAction.js
147
+ * | | | |-- intl
148
+ * | |-- index.js
149
+ * |-- data
150
+ * | |-- config
151
+ * | | |-- .plugins
152
+ * | | |-- bajo.yml
153
+ * | | |-- myPlugin.yml
154
+ * ```
155
+ *
80
156
  * @class
81
157
  */
82
158
  class App {
83
159
  /**
84
- * Constructor.
160
+ * Constructor. See {@link App.TOptions} if you want to write custom boot process for your app without using the default boot module.
85
161
  * @param {App.TOptions} [options={}] - Options object.
86
162
  */
87
163
  constructor (options = {}) {
88
164
  /**
89
- * Copy of provided options.
165
+ * Copy of the provided options. See {@link App.TOptions} for details.
90
166
  * @type {App.TOptions}
91
167
  */
92
168
  this.options = options
93
169
 
94
170
  /**
95
- * Main namespace.
171
+ * App's main plugin namespace (`main`). Read-only
96
172
  * @type {string}
97
173
  */
98
174
  this.mainNs = 'main'
99
175
 
100
176
  /**
101
- * App environments.
177
+ * Supported environments. Read-only
102
178
  * @type {App.TEnv}
103
179
  */
104
- this.envs = { dev: 'development', prod: 'production' }
180
+ this.envs = { dev: 'development', prod: 'production', stag: 'staging', test: 'testing' }
105
181
 
106
182
  /**
107
- * Date/time when your app start.
183
+ * Date/time when your app start. You can use this e.g. to calculate how long your app has been running. Read-only
108
184
  * @type {Date}
109
185
  */
110
186
  this.runAt = new Date()
111
187
 
112
188
  /**
113
- * Applets container.
189
+ * Applets container. Usefull to get all available applets in your app. See {@link module:Applet|applet} for details.
114
190
  * @type {Array}
115
191
  */
116
192
  this.applets = []
117
193
 
118
194
  /**
119
- * Plugin's package names container. This is the list of plugins to load.
195
+ * Original plugin's **package names** (not to be confused with plugin namespaces) container. Ypu can use this
196
+ * information to get the real package name of a plugin.
197
+ *
198
+ * > **Reminder**: In Bajo, plugin name/namespace is the camel-cased version of its package name.
199
+ * E.g. `my-plugin` → `myPlugin`.
200
+ *
120
201
  * @type {string[]}
121
202
  */
122
203
  this.pluginPkgs = options.plugins ?? []
123
204
 
124
205
  /**
125
- * Config handlers.
206
+ * Config handlers container. This is where all config handlers are stored. Each handler
207
+ * is responsible to read and write config file in a particular format. Bajo uses this heavily to read/write config
208
+ * files and/or anything that needs to be parsed/stringified from string to object and vice versa.
126
209
  *
127
210
  * By default, there are three built-in handlers: `.js`, `.json`
128
211
  * and `.yml/.yaml`. Use plugins to add more, e.g {@link https://github.com/ardhi/bajo-config|bajo-config}
129
212
  * lets you to use `.toml`.
213
+ *
214
+ * > *Note*: `.js` is for reading only, it cannot be used to write config file.
215
+
130
216
  * @type {Array&lt;App.TConfigHandler>}
131
217
  */
132
218
  this.configHandlers = []
@@ -145,55 +231,66 @@ class App {
145
231
  this.lib.parseObject = this.lib.parseObject.bind(this)
146
232
 
147
233
  /**
148
- * Instance of system log.
149
- *
234
+ * Instance of the system log. This will automatically be instantiated early during boot process. See {@link Log} for details.
150
235
  * @type {Log}
151
236
  */
152
237
  this.log = {}
153
238
 
154
239
  /**
155
- * All plugin's base class are saved here as key-value pairs with plugin name as its key.
156
- * The special key `Base` &amp;&amp; `Tools` is for {@link Base} &amp; {@link Tools} class so that anytime you want to
157
- * create your own plugin, you can just write something like this:
240
+ * All plugin's base classes are saved here for reference so that you can extend them in your own plugins.
241
+ *
242
+ * Two basic classes from Bajo package are also provided: {@link Base} and {@link Tools}. These are the most
243
+ * used classes in Bajo plugin development. You can extend them to create your own plugin's base class:
244
+ *
245
+ * ```javascript
246
+ * // factory function to create your own plugin's base class
247
+ * async function () {
248
+ * const { Base } = this.app.baseClass
249
+ * class MyBase extends Base {
250
+ * constructor(pkgName, app) {
251
+ * super(pkgName, app)
252
+ * this.myProperty = 'myValue' // your class property
253
+ * }
158
254
  *
159
- * `javascript
160
- * class MyPlugin extends this.app.baseClass.Base {
161
- * ... your class
255
+ * async myMethod() {
256
+ * // your class method
257
+ * }
258
+ * }
162
259
  * }
260
+ * ```
163
261
  *
164
262
  * @type {Object}
165
263
  */
166
264
  this.baseClass = { Base, Tools }
167
265
 
168
266
  /**
169
- * If app runs in applet mode, this will be the applet's name.
267
+ * If app runs in **applet** mode, this will be the current applet's name. Otherwise, it will be `undefined`. See {@link module:Applet|applet} for details.
170
268
  * @type {string}
171
269
  */
172
270
  this.applet = undefined
173
271
 
174
272
  /**
175
273
  * Parsed program arguments.
176
- * @type {string[]}
177
- * @see module:Helper.parseArgsArgv
178
- * @example
274
+ *
275
+ * Example:
276
+ * ```js
179
277
  * $ node index.js arg1 arg2
180
278
  * ...
181
279
  * console.log(this.args) // it should print: ['arg1', 'arg2']
280
+ * ```
281
+ *
282
+ * @type {string[]}
182
283
  */
183
284
  this.args = []
184
285
 
185
286
  /**
186
- * Parsed program options.
187
- *
287
+ * Parsed program options:
188
288
  * - Dash (`-`) breaks the string into object keys
189
- * - While colon (`:`) is used as namespace separator. If no namespace found, it is saved under `_` key.
289
+ * - While colon (`:`) is used as namespace - object separator. If no such namespace found, it is saved under `_`.
190
290
  *
191
- * Values are parsed automatically. See {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}
192
- * for details.
291
+ * Parsed object values are normalized to its primitives using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}
193
292
  *
194
- * @type {Object}
195
- * @see module:Helper.parseArgsArgv
196
- * @example
293
+ * ```js
197
294
  * $ node index.js --my-name-first=John --my-name-last=Doe --my-birthDay=secret --nameSpace:path-subPath=true
198
295
  * ...
199
296
  * // {
@@ -205,37 +302,33 @@ class App {
205
302
  * // },
206
303
  * // nameSpace: { path: { subPath: true } }
207
304
  * // }
305
+ *
306
+ * @type {Object}
208
307
  */
209
308
  this.argv = {}
210
309
 
211
310
  /**
212
- * Environment variables. Support dotenv (`.env`) file too!
213
- *
214
- * - Underscore (`_`) translates key to camel-cased one
215
- * - Double underscores (`__`) breaks the key into object keys
216
- * - While dot (`.`) is used as namespace separator. If no namespace found, it is saved under `_` key.
217
- *
218
- * Values are also parsed automatically using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}.
311
+ * Parsed environment variables. Support dotenv (`.env`) file too!
312
+ * - Underscore (`_`) between keys merge those keys into a single camel-cased key
313
+ * - Double underscores (`__`) between keys breaks the key into nested objects
314
+ * - Meanwhile a dot (`.`) between keys breaks the key into nested, name-spaced objects
219
315
  *
220
- * E.g.:
316
+ * Parsed object values are normalized to its primitives using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}
221
317
  *
318
+ * Example:
222
319
  * - `MY_KEY=secret` → `{ _: { myKey: 'secret' } }`
223
320
  * - `MY_KEY__SUB_KEY=supersecret` → `{ _: { myKey: { subKey: 'supersecret' } } }`
224
321
  * - `MY_NS.MY_NAME=John` → `{ myNs: { myName: 'John' } }`
225
322
  *
323
+ * > **Tips**: During boot process, Bajo will add `APPDIR` environment variable which points to your app's root directory.
324
+ *
226
325
  * @type {Object}
227
- * @see module:Helper.parseEnv
228
326
  */
229
327
  this.envVars = {}
230
-
231
- /**
232
- * Placeholder for boxen that will get imported from `bajoCli` later during boot process.
233
- * @type {Object}
234
- */
235
328
  this.boxen = null
236
329
 
237
330
  /**
238
- * Cache instance. This is used to store temporary data in memory for faster access.
331
+ * Internal cache instance. This is used to store temporary data in memory for faster access.
239
332
  * @type {Cache}
240
333
  */
241
334
  this.cache = new Cache(this)
@@ -251,11 +344,12 @@ class App {
251
344
  }
252
345
 
253
346
  /**
254
- * Add and save plugin and it's base class definition (if provided).
347
+ * Add and save plugin and its base class definition (if provided) to the app instance. You can then reference
348
+ * the plugin using its namespace, e.g. `this.myPlugin` or `this['myPlugin']`.
255
349
  *
256
350
  * @method
257
- * @param {TPlugin} plugin - A valid bajo plugin.
258
- * @param {Object} [baseClass] - Base class definition.
351
+ * @param {Base} plugin - A valid Bajo plugin.
352
+ * @param {class} [baseClass] - Base class definition.
259
353
  */
260
354
  addPlugin = (plugin, baseClass) => {
261
355
  if (this[plugin.ns]) throw new Error(`Plugin '${plugin.ns}' added already`)
@@ -264,7 +358,7 @@ class App {
264
358
  }
265
359
 
266
360
  /**
267
- * Get all loaded plugin namespaces.
361
+ * Get all loaded **plugin namespaces**.
268
362
  *
269
363
  * @method
270
364
  * @returns {string[]}
@@ -274,34 +368,36 @@ class App {
274
368
  }
275
369
 
276
370
  /**
277
- * Get loaded plugins.
371
+ * Get loaded plugins by their namespaces. If no namespace is provided, it will return all loaded plugins.
278
372
  *
279
373
  * @method
280
- * @param {string[]} [nss] - Array of namespaces. If empty, it returns all loaded plugins.
281
- * @returns {TPlugin[]}
374
+ * @param {string[]} [nss] - Array of namespaces. If empty, it returns all loaded plugins
375
+ * @param {boolean} [nameOnly=false] - If `true`, it will return only the plugin namespaces instead of the plugin instances
376
+ * @returns {Array&lt;Base>} Array of plugin instances
282
377
  */
283
- getPlugins = (nss) => {
378
+ getPlugins = (nss, nameOnly = false) => {
284
379
  const allNs = nss ?? this.getAllNs()
285
- return allNs.map(ns => this[ns])
380
+ return allNs.map(ns => nameOnly ? ns : this[ns])
286
381
  }
287
382
 
288
383
  /**
289
- * Get all plugins loaded plugins.
384
+ * Get all loaded plugins. Alias to {@link App#getPlugins|getPlugins()} with no namespace provided.
290
385
  *
291
386
  * @method
292
- * @returns {TPlugin[]}
387
+ * @returns {Array&lt;Base>} Array of all loaded plugin instances
293
388
  */
294
389
  getAllPlugins = () => {
295
390
  return this.getPlugins()
296
391
  }
297
392
 
298
393
  /**
299
- * Get plugin by its namespace.
394
+ * Get plugin by its namespace or alias. If the plugin is not loaded, it will throw an error
395
+ * unless `silent` is set to `true`.
300
396
  *
301
397
  * @method
302
- * @param {string} name - Plugin name/namespace or alias.
303
- * @param {boolean} [silent] - If `true`, silently return undefined even on error.
304
- * @returns {Object} Plugin object.
398
+ * @param {string} name - Namespace or alias.
399
+ * @param {boolean} [silent] - If `true`, silently return undefined even on error
400
+ * @returns {Base} Plugin object.
305
401
  */
306
402
  getPlugin = (name, silent) => {
307
403
  if (!this[name]) {
@@ -315,7 +411,7 @@ class App {
315
411
  }
316
412
  }
317
413
  if (!plugin) {
318
- if (silent) return false
414
+ if (silent) return undefined
319
415
  throw this.bajo.error('pluginWithNameAliasNotLoaded%s', name)
320
416
  }
321
417
  name = plugin.ns
@@ -324,11 +420,12 @@ class App {
324
420
  }
325
421
 
326
422
  /**
327
- * Get plugin data directory
423
+ * Get plugin data directory. If the directory does not exist, it will be created automatically
424
+ * unless `ensureDir` is set to `false`.
328
425
  *
329
426
  * @method
330
- * @param {string} name - Plugin name (namespace) or alias.
331
- * @param {boolean} [ensureDir=true] - Set `true` (default) to ensure directory is existed.
427
+ * @param {string} name - Namespace or alias.
428
+ * @param {boolean} [ensureDir=true] - Set `true` (default) to ensure directory exists
332
429
  * @returns {string}
333
430
  */
334
431
  getPluginDataDir = (name, ensureDir = true) => {
@@ -341,14 +438,13 @@ class App {
341
438
 
342
439
  /**
343
440
  * Resolve file path from:
344
- *
345
441
  * - local/absolute file
346
- * - TNsPath (`myPlugin:/path/to/file.txt`)
347
- * - file under node_modules, e.g. `myPlugin:node_modules/some-package/file.txt`
442
+ * - {@link Bajo.TNsPathPairs} e.g. `myPlugin:/path/to/file.txt`
443
+ * - file under `node_modules`, e.g. `myPlugin:node_modules/some-package/file.txt`
348
444
  *
349
445
  * @method
350
- * @param {string} file - File path, see above for supported types.
351
- * @returns {string} Resolved file path.
446
+ * @param {string} file - File path, see above for supported types
447
+ * @returns {string} Resolved file path
352
448
  */
353
449
  getPluginFile = (file) => {
354
450
  const { currentLoc } = this.lib.aneka
@@ -374,13 +470,13 @@ class App {
374
470
  * Dumping variable on screen. Like `console.log` with configurable options. Useful for quick debugging and testing. You can also use it to dump variables in production without worrying about performance because it is using Bajo's built-in cache to store the result of util's inspect, so it will only be processed once for each unique variable.
375
471
  *
376
472
  * Any argument passed to this method will be displayed on screen.
377
- * If the last argument is a boolean `true`, app will quit rightaway after dumping.
473
+ * If the last argument is a string `\q` or `.q`, app will quit rightaway after dumping.
378
474
  *
379
475
  * If you have `bajoCli` plugin installed, variables will be displayed in a nice box using `boxen` package.
380
476
  * Otherwise, it will fallback to `console.log` with util's inspect result.
381
477
  *
382
478
  * To have more control on how the variable is displayed, you can set options in Bajo's config under `dump` key.
383
- * See {@link Bajo#config} for details.
479
+ * See {@link Bajo.TConfig} for details.
384
480
  *
385
481
  * @method
386
482
  * @param {...any} args - Variables to dump.
@@ -388,8 +484,7 @@ class App {
388
484
  dump = (...args) => {
389
485
  let caller = getCallerFilename()
390
486
  caller = caller ? fileURLToPath(caller) : 'Unavailable'
391
- const opts = last(args)
392
- const terminate = isPlainObject(opts) &amp;&amp; opts.abort
487
+ const terminate = ['\\q', '.q'].includes(last(args))
393
488
  if (terminate) args.pop()
394
489
  const value = args.length === 1 ? args[0] : args
395
490
  const options = { ...this.bajo.config.dump }
@@ -406,13 +501,15 @@ class App {
406
501
  }
407
502
 
408
503
  /**
409
- * Run application:
504
+ * Run application and begin the boot process. This method is called automatically by {@link boot|boot} script.
410
505
  *
411
- * - Parsing {@link module:Helper.parseArgsArgv|program arguments, options} and {@link module:Helper.parseEnv|environment values}
412
- * - Create {@link Bajo|Bajo} instance &amp; initialize it
413
- * - {@link module:Helper/Bajo.runAsApplet|Run in applet mode} if `-a` or `--applet` is given
506
+ * Boot process includes:
507
+ * - parsing environment values, program arguments, and options
508
+ * - create {@link Bajo|Bajo} instance &amp; initialize it
509
+ * - load all plugins, their hooks, their configs and any other necessary services &amp; resources
510
+ * - {@link Bajo.runAsApplet|run in applet mode} if `-a` or `--applet` is given
414
511
  *
415
- * After boot process is completed, event `bajo:afterBootCompleted` is emitted.
512
+ * After boot process is completed, hook `bajo:afterBoot` is triggered.
416
513
  *
417
514
  * If app mode is `applet`, it runs your choosen applet instead.
418
515
  *
@@ -443,10 +540,10 @@ class App {
443
540
  this.args = args
444
541
  this.argv = parseObject(argv, { parseValue: true })
445
542
  this.envVars = parseObject(parseEnv(), { parseValue: true })
446
- if (get(this, 'envVars._.env') === '[object Object]') set(this, 'envVars._.env', 'dev')
543
+ if (get(this, 'envVars._.env') === '[object Object]') set(this, 'envVars._.env', 'dev') // hack for some env vars that are not parsed correctly
447
544
  this.applet = this.envVars._.applet ?? this.argv._.applet
448
545
  await this.bajo.runHook('bajo:beforeBoot')
449
- await this.bajo.init()
546
+ await this.bajo.bootApp()
450
547
  if (this.bajoCli) this.boxen = await this.bajo.importPkg('bajoCli:boxen')
451
548
  // cache
452
549
  this.cache.purge()
@@ -460,21 +557,25 @@ class App {
460
557
  }
461
558
 
462
559
  /**
463
- * Terminate the app and back to console.
560
+ * Terminate the app forcefully and back to console.
464
561
  *
465
562
  * @method
466
- * @param {string|boolean} [signal=SIGINT] - Signal to send. Set to `true` to terminate immediately without sending any signal.
563
+ * @param {string|boolean} [signal=SIGINT] - Signal to send. Set to `true` to terminate immediately without sending any signal
564
+ * @param {string} [reason] - Reason to be printed on console before exiting
467
565
  */
468
- exit = (signal = 'SIGINT') => {
566
+ exit = (signal = 'SIGINT', reason) => {
567
+ if (reason) console.error(reason)
469
568
  if (signal === true) process.exit('1')
470
569
  process.kill(process.pid, signal)
471
570
  }
472
571
 
473
572
  /**
474
- * Load internationalization &amp; languages files for particular plugin.
573
+ * Load internationalization &amp; languages files for particular plugin by its namespace.
574
+ * It will load all supported languages defined in {@link Bajo.TConfig|`config.intl.supported`}
575
+ * and save them in `this[ns].intl` object.
475
576
  *
476
577
  * @method
477
- * @param {string} ns - Plugin name (namespace)
578
+ * @param {string} ns - Plugin namespace
478
579
  */
479
580
  loadIntl = (ns) => {
480
581
  const { fs } = this.lib
@@ -538,28 +639,34 @@ class App {
538
639
  }
539
640
 
540
641
  /**
541
- * Translate text and interpolate with given `params`.
642
+ * Translate text to the current language.
643
+ *
644
+ * It will search for the translation in the plugin's `intl` object first, interpolating the parameters if found,
645
+ * then fallback to `bajo` plugin's `intl` object if not found.
542
646
  *
543
647
  * If the last parameter is an object with `lang` key, it will use that language instead of the default one.
544
648
  *
545
649
  * There is a shortcut to this method attached on all plugins. You'll normally call that shorcut
546
- * instead of this method, because it is bound to plugin's namespace already
650
+ * instead of this method, because that shortcut is bound to plugin's namespace already
547
651
  *
548
- * @method
549
- * @param {string} ns - Namespace
550
- * @param {string} text - Text to translate
551
- * @param {...any} params - Arguments
552
- * @returns {string}
553
- * @example
652
+ * ```js
554
653
  * ... within your main plugin
555
654
  * const translated = this.app.t('main', 'My cute cat is %s', 'purring')
556
655
  * // or within your plugin
557
656
  * const translated = this.t('My cute cat is %s', 'purring')
657
+ * ```
658
+ *
659
+ * @method
660
+ * @param {string} ns - Namespace
661
+ * @param {string} text - Text to translate
662
+ * @param {...*} params - Parameters to interpolate into the translation text
663
+ * @returns {string}
558
664
  */
559
665
  t = (ns, text, ...params) => {
560
666
  const { formatText, isSet } = this.lib.aneka
561
- const { isArray, last } = this.lib._
667
+ const { isArray, last, get } = this.lib._
562
668
  const { join } = this.bajo
669
+ if (!get(this, 'bajo.config.intl')) return formatText(text, ...params)
563
670
  let { text: newText, trans, params: args } = this._prepTrans(ns, text, params)
564
671
  if (!isSet(trans)) trans = newText
565
672
  const lang = isPlainObject(last(args)) ? last(args).lang : undefined
@@ -584,7 +691,8 @@ class App {
584
691
  }
585
692
 
586
693
  /**
587
- * Helper method to list all supported config formats.
694
+ * Method to list all supported config formats, that is, all file extensions that are supported
695
+ * by the app's config handlers.
588
696
  *
589
697
  * @method
590
698
  * @param {boolean} [noDot] - If `true`, it will return the list without dot prefix
@@ -596,7 +704,7 @@ class App {
596
704
  }
597
705
 
598
706
  /**
599
- * Start a plugin.
707
+ * Start a plugin by its namespace. It will call the plugin's `start` method with the provided arguments.
600
708
  *
601
709
  * @method
602
710
  * @param {string} ns - Plugin namespace.
@@ -607,8 +715,13 @@ class App {
607
715
  }
608
716
 
609
717
  /**
610
- * Stop a plugin.
718
+ * Stop a plugin by its namespace. It will call the plugin's `stop` method with the provided arguments.
719
+ *
720
+ * Reserved for future use.
611
721
  *
722
+ * > **Note**: Basically it is not a good idea to stop a plugin because other plugins
723
+ * might be dependent on it. But if we could find a way to safely stop a plugin without breaking things,
724
+ * this will be a cool feature because it allows dynamic management of plugins without restarting the application.
612
725
  * @method
613
726
  * @param {string} ns - Plugin namespace.
614
727
  * @param {...any} args - Arguments to pass to the plugin's stop method
@@ -620,4 +733,4 @@ class App {
620
733
  }
621
734
 
622
735
  export default App
623
- </code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">Bajo API</a><div class="mobile-nav-links"><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="mobile-sidebar-items-c"><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 class="mobile-navbar-actions"><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></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
736
+ </code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">Bajo API</a><div class="mobile-nav-links"><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="mobile-sidebar-items-c"><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 class="mobile-navbar-actions"><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></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>