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
@@ -1,35 +1,45 @@
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/tools.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_tools.js</h1></header><article><pre class="prettyprint source lang-js"><code>/**
4
- * Tools class.
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_tools.js</h1></header><article><pre class="prettyprint source lang-js"><code>/**
4
+ * Tools class. Basic utility class that provides common functionalities for other classes to extend.
5
+ * It serves as a base class for error handling, printing, and other utility operations.
5
6
  *
6
7
  * @class
7
8
  */
8
9
  class Tools {
9
10
  constructor (plugin) {
10
11
  /**
11
- * Attached plugin
12
+ * Reference to the plugin instance that this Tools class is associated with
12
13
  * @type {Plugin}
13
14
  */
14
15
  this.plugin = plugin
15
16
 
16
17
  /**
17
- * The app instance
18
+ * Reference to the app instance
18
19
  * @type {App}
19
20
  */
20
21
  this.app = plugin.app
21
22
  }
22
23
 
23
24
  /**
24
- * Force bind methods to self (`this`).
25
+ * Force bind methods to `this` context.
25
26
  *
27
+ * Since JavaScript's `this` is dynamic, this method is useful to ensure
28
+ * that the methods always refer to the correct instance of the class.
29
+ *
30
+ * Typically, you would call this method in the constructor of your plugin class,
31
+ * passing an array of method names or imported functions that you want to bind.
26
32
  * @method
27
- * @param {string[]} names - Method's names
33
+ * @param {...(string|function)} names - Method's names or function references to bind to `this` context
28
34
  * @returns {void}
29
35
  */
30
- selfBind (names) {
36
+ bindThis (...names) {
31
37
  for (const name of names) {
32
- this[name] = this[name].bind(this)
38
+ if (typeof name === 'string') this[name] = this[name].bind(this)
39
+ else if (typeof name === 'function') {
40
+ const methodName = name.name
41
+ this[methodName] = name.bind(this)
42
+ }
33
43
  }
34
44
  }
35
45
 
@@ -47,4 +57,4 @@ class Tools {
47
57
  }
48
58
 
49
59
  export default Tools
50
- </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>
60
+ </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>
@@ -1 +1 @@
1
- {"list":[{"title":"App","link":"<a href=\"App.html\">App</a>","description":"<p>Constructor.</p>"},{"title":"App#addPlugin","link":"<a href=\"App.html#addPlugin\">addPlugin</a>","description":"<p>Add and save plugin and it's base class definition (if provided).</p>"},{"title":"App#applet","link":"<a href=\"App.html#applet\">applet</a>","description":"<p>If app runs in applet mode, this will be the applet's name.</p>"},{"title":"App#applets","link":"<a href=\"App.html#applets\">applets</a>","description":"<p>Applets container.</p>"},{"title":"App#args","link":"<a href=\"App.html#args\">args</a>","description":"<p>Parsed program arguments.</p>"},{"title":"App#argv","link":"<a href=\"App.html#argv\">argv</a>","description":"<p>Parsed program options.</p>\n<ul>\n<li>Dash (<code>-</code>) breaks the string into object keys</li>\n<li>While colon (<code>:</code>) is used as namespace separator. If no namespace found, it is saved under <code>_</code> key.</li>\n</ul>\n<p>Values are parsed automatically. See {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}\nfor details.</p>"},{"title":"App#baseClass","link":"<a href=\"App.html#baseClass\">baseClass</a>","description":"<p>All plugin's base class are saved here as key-value pairs with plugin name as its key.\nThe special key <code>Base</code> &amp;&amp; <code>Tools</code> is for {@link Base} &amp; {@link Tools} class so that anytime you want to\ncreate your own plugin, you can just write something like this:</p>\n<p>`javascript\nclass MyPlugin extends this.app.baseClass.Base {\n... your class\n}</p>"},{"title":"App#boxen","link":"<a href=\"App.html#boxen\">boxen</a>","description":"<p>Placeholder for boxen that will get imported from <code>bajoCli</code> later during boot process.</p>"},{"title":"App#cache","link":"<a href=\"App.html#cache\">cache</a>","description":"<p>Cache instance. This is used to store temporary data in memory for faster access.</p>"},{"title":"App#configHandlers","link":"<a href=\"App.html#configHandlers\">configHandlers</a>","description":"<p>Config handlers.</p>\n<p>By default, there are three built-in handlers: <code>.js</code>, <code>.json</code>\nand <code>.yml/.yaml</code>. Use plugins to add more, e.g {@link https://github.com/ardhi/bajo-config|bajo-config}\nlets you to use <code>.toml</code>.</p>"},{"title":"App#dump","link":"<a href=\"App.html#dump\">dump</a>","description":"<p>Dumping variable on screen. Like <code>console.log</code> 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.</p>\n<p>Any argument passed to this method will be displayed on screen.\nIf the last argument is a boolean <code>true</code>, app will quit rightaway after dumping.</p>\n<p>If you have <code>bajoCli</code> plugin installed, variables will be displayed in a nice box using <code>boxen</code> package.\nOtherwise, it will fallback to <code>console.log</code> with util's inspect result.</p>\n<p>To have more control on how the variable is displayed, you can set options in Bajo's config under <code>dump</code> key.\nSee {@link Bajo#config} for details.</p>"},{"title":"App#envVars","link":"<a href=\"App.html#envVars\">envVars</a>","description":"<p>Environment variables. Support dotenv (<code>.env</code>) file too!</p>\n<ul>\n<li>Underscore (<code>_</code>) translates key to camel-cased one</li>\n<li>Double underscores (<code>__</code>) breaks the key into object keys</li>\n<li>While dot (<code>.</code>) is used as namespace separator. If no namespace found, it is saved under <code>_</code> key.</li>\n</ul>\n<p>Values are also parsed automatically using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}.</p>\n<p>E.g.:</p>\n<ul>\n<li><code>MY_KEY=secret</code> → <code>{ _: { myKey: 'secret' } }</code></li>\n<li><code>MY_KEY__SUB_KEY=supersecret</code> → <code>{ _: { myKey: { subKey: 'supersecret' } } }</code></li>\n<li><code>MY_NS.MY_NAME=John</code> → <code>{ myNs: { myName: 'John' } }</code></li>\n</ul>"},{"title":"App#envs","link":"<a href=\"App.html#envs\">envs</a>","description":"<p>App environments.</p>"},{"title":"App#exit","link":"<a href=\"App.html#exit\">exit</a>","description":"<p>Terminate the app and back to console.</p>"},{"title":"App#getAllNs","link":"<a href=\"App.html#getAllNs\">getAllNs</a>","description":"<p>Get all loaded plugin namespaces.</p>"},{"title":"App#getAllPlugins","link":"<a href=\"App.html#getAllPlugins\">getAllPlugins</a>","description":"<p>Get all plugins loaded plugins.</p>"},{"title":"App#getConfigFormats","link":"<a href=\"App.html#getConfigFormats\">getConfigFormats</a>","description":"<p>Helper method to list all supported config formats.</p>"},{"title":"App#getPlugin","link":"<a href=\"App.html#getPlugin\">getPlugin</a>","description":"<p>Get plugin by its namespace.</p>"},{"title":"App#getPluginDataDir","link":"<a href=\"App.html#getPluginDataDir\">getPluginDataDir</a>","description":"<p>Get plugin data directory</p>"},{"title":"App#getPluginFile","link":"<a href=\"App.html#getPluginFile\">getPluginFile</a>","description":"<p>Resolve file path from:</p>\n<ul>\n<li>local/absolute file</li>\n<li>TNsPath (<code>myPlugin:/path/to/file.txt</code>)</li>\n<li>file under node_modules, e.g. <code>myPlugin:node_modules/some-package/file.txt</code></li>\n</ul>"},{"title":"App#getPlugins","link":"<a href=\"App.html#getPlugins\">getPlugins</a>","description":"<p>Get loaded plugins.</p>"},{"title":"App#lib","link":"<a href=\"App.html#lib\">lib</a>","description":"<p>Gives you direct access to the most commonly used 3rd party library in a Bajo based app.\nNo manual import necessary, always available, anywhere, anytime!</p>"},{"title":"App#loadIntl","link":"<a href=\"App.html#loadIntl\">loadIntl</a>","description":"<p>Load internationalization &amp; languages files for particular plugin.</p>"},{"title":"App#log","link":"<a href=\"App.html#log\">log</a>","description":"<p>Instance of system log.</p>"},{"title":"App#mainNs","link":"<a href=\"App.html#mainNs\">mainNs</a>","description":"<p>Main namespace.</p>"},{"title":"App#options","link":"<a href=\"App.html#options\">options</a>","description":"<p>Copy of provided options.</p>"},{"title":"App#pluginPkgs","link":"<a href=\"App.html#pluginPkgs\">pluginPkgs</a>","description":"<p>Plugin's package names container. This is the list of plugins to load.</p>"},{"title":"App#run","link":"<a href=\"App.html#run\">run</a>","description":"<p>Run application:</p>\n<ul>\n<li>Parsing {@link module:Helper.parseArgsArgv|program arguments, options} and {@link module:Helper.parseEnv|environment values}</li>\n<li>Create {@link Bajo|Bajo} instance &amp; initialize it</li>\n<li>{@link module:Helper/Bajo.runAsApplet|Run in applet mode} if <code>-a</code> or <code>--applet</code> is given</li>\n</ul>\n<p>After boot process is completed, event <code>bajo:afterBootCompleted</code> is emitted.</p>\n<p>If app mode is <code>applet</code>, it runs your choosen applet instead.</p>"},{"title":"App#runAt","link":"<a href=\"App.html#runAt\">runAt</a>","description":"<p>Date/time when your app start.</p>"},{"title":"App#startPlugin","link":"<a href=\"App.html#startPlugin\">startPlugin</a>","description":"<p>Start a plugin.</p>"},{"title":"App#stopPlugin","link":"<a href=\"App.html#stopPlugin\">stopPlugin</a>","description":"<p>Stop a plugin.</p>"},{"title":"App#t","link":"<a href=\"App.html#t\">t</a>","description":"<p>Translate text and interpolate with given <code>params</code>.</p>\n<p>If the last parameter is an object with <code>lang</code> key, it will use that language instead of the default one.</p>\n<p>There is a shortcut to this method attached on all plugins. You'll normally call that shorcut\ninstead of this method, because it is bound to plugin's namespace already</p>"},{"title":"App#te","link":"<a href=\"App.html#te\">te</a>","description":"<p>Check whether translation text/key exists.</p>"},{"title":"App.TConfigHandler","link":"<a href=\"App.html#.TConfigHandler\">TConfigHandler</a>"},{"title":"App.TEnv","link":"<a href=\"App.html#.TEnv\">TEnv</a>"},{"title":"App.TLib","link":"<a href=\"App.html#.TLib\">TLib</a>"},{"title":"App.TOptions","link":"<a href=\"App.html#.TOptions\">TOptions</a>"},{"title":"App.readHandler","link":"<a href=\"App.html#.readHandler\">readHandler</a>"},{"title":"App.writeHandler","link":"<a href=\"App.html#.writeHandler\">writeHandler</a>"},{"title":"Bajo","link":"<a href=\"Bajo.html\">Bajo</a>","description":"<p>Constructor.</p>"},{"title":"Bajo#alias","link":"<a href=\"Bajo.html#alias\">alias</a>","description":"<p>Alias</p>"},{"title":"Bajo#breakNsPath","link":"<a href=\"Bajo.html#breakNsPath\">breakNsPath</a>","description":"<p>Break name to its namespace &amp; path infos</p>"},{"title":"Bajo#breakNsPathFromFile","link":"<a href=\"Bajo.html#breakNsPathFromFile\">breakNsPathFromFile</a>","description":"<p>Break file path to its namespace &amp; path infos.</p>"},{"title":"Bajo#buildCollections","link":"<a href=\"Bajo.html#buildCollections\">buildCollections</a>","description":"<p>Method to transform config's array or object into an array of collection.</p>"},{"title":"Bajo#buildNsPath","link":"<a href=\"Bajo.html#buildNsPath\">buildNsPath</a>","description":"<p>Build ns/path pairs.</p>"},{"title":"Bajo#callHandler","link":"<a href=\"Bajo.html#callHandler\">callHandler</a>","description":"<p>Calling any plugin's method by its name:</p>\n<ul>\n<li>If name is a string, the corresponding plugin's method will be called with passed args as its parameters</li>\n<li>If name is a plugin instance, this will be used as the scope instead. The first args is now the handler name and the rest are its parameters</li>\n<li>If name is a function, this function will be run under scope with the remaining args</li>\n<li>If name is an object and has <code>handler</code> key in it, this function handler will be instead</li>\n</ul>"},{"title":"Bajo#config","link":"<a href=\"Bajo.html#config\">config</a>","description":"<p>Config object.</p>"},{"title":"Bajo#eachPlugins","link":"<a href=\"Bajo.html#eachPlugins\">eachPlugins</a>","description":"<p>This function iterates through all loaded plugins and call the provided handler scoped as the running plugin.\nAnd an object with the following key serves as its parameter:</p>\n<ul>\n<li><code>file</code>: file matched the glob pattern</li>\n<li><code>dir</code>: plugin's base directory</li>\n</ul>"},{"title":"Bajo#format","link":"<a href=\"Bajo.html#format\">format</a>","description":"<p>Format value.</p>"},{"title":"Bajo#formatByType","link":"<a href=\"Bajo.html#formatByType\">formatByType</a>","description":"<p>Format value by type.</p>"},{"title":"Bajo#fromJs","link":"<a href=\"Bajo.html#fromJs\">fromJs</a>","description":"<p>Read and parse JavaScript file.</p>"},{"title":"Bajo#fromJson","link":"<a href=\"Bajo.html#fromJson\">fromJson</a>","description":"<p>Read and parse JSON string or object.</p>"},{"title":"Bajo#fromYaml","link":"<a href=\"Bajo.html#fromYaml\">fromYaml</a>","description":"<p>Parse YAML text</p>"},{"title":"Bajo#fromYml","link":"<a href=\"Bajo.html#fromYml\">fromYml</a>","description":"<p>Parse YML text. Alias for fromYaml.</p>"},{"title":"Bajo#getMethod","link":"<a href=\"Bajo.html#getMethod\">getMethod</a>","description":"<p>Get class method by name.</p>"},{"title":"Bajo#getModuleDir","link":"<a href=\"Bajo.html#getModuleDir\">getModuleDir</a>","description":"<p>Get module directory.</p>"},{"title":"Bajo#getUnitFormat","link":"<a href=\"Bajo.html#getUnitFormat\">getUnitFormat</a>","description":"<p>Get unit format.</p>"},{"title":"Bajo#hooks","link":"<a href=\"Bajo.html#hooks\">hooks</a>","description":"<p>Hooks container.</p>"},{"title":"Bajo#importModule","link":"<a href=\"Bajo.html#importModule\">importModule</a>","description":"<p>Import file/module from any loaded plugins.</p>\n<p>Method proxy from {@link module:Helper.importModule}</p>"},{"title":"Bajo#importPkg","link":"<a href=\"Bajo.html#importPkg\">importPkg</a>","description":"<p>Import one or more packages belongs to a plugin.</p>\n<p>If the last arguments passed is an object, this object serves as options object:</p>\n<ul>\n<li><code>returnDefault</code>: should return package's default export. Defaults to <code>true</code></li>\n<li><code>throwNotFound</code>: should throw if package is not found. Defaults to <code>false</code></li>\n<li><code>noCache</code>: always use fresh import. Defaults to <code>false</code></li>\n<li><code>asObject</code>: see below. Defaults to <code>false</code></li>\n</ul>\n<p>Return value:</p>\n<ul>\n<li>if <code>options.asObject</code> is <code>true</code> (default <code>false</code>), return as object with package's names as it's keys</li>\n<li>Otherwise depends on how many parameters are provided, it should return the named package or an array of packages</li>\n</ul>\n<p>Example: you want to import <code>delay</code> and <code>chalk</code> from <code>bajo</code> plugin because you want to use it in your code\n`javascript\nconst { importPkg } from this.app.bajo\nconst [delay, chalk] = await importPkg('bajo:delay', 'bajo:chalk')</p>\n<p>await delay(1000)\n...\n`</p>"},{"title":"Bajo#init","link":"<a href=\"Bajo.html#init\">init</a>","description":"<p>Initialization:</p>\n<ol>\n<li>Building {@link module:Helper/Bajo.buildBaseConfig|base config}</li>\n<li>{@link module:Helper/Bajo.buildPlugins|Building plugins}</li>\n<li>Collect all {@link module:Helper/Bajo.collectConfigHandlers|config handler}</li>\n<li>Building {@link module:Helper/Bajo.buildExtConfig|extra config}</li>\n<li>Setup {@link module:Helper/Bajo.bootOrder|boot order}</li>\n<li>{@link module:Helper/Bajo.bootPlugins|Boot loaded plugins}</li>\n<li>Attach {@link module:Helper/Bajo.exitHandler|exit handlers}</li>\n</ol>"},{"title":"Bajo#isLogInRange","link":"<a href=\"Bajo.html#isLogInRange\">isLogInRange</a>","description":"<p>Check whether log level is within log's app current level.</p>"},{"title":"Bajo#isValidApp","link":"<a href=\"Bajo.html#isValidApp\">isValidApp</a>","description":"<p>Check whether directory is a valid Bajo app.</p>"},{"title":"Bajo#isValidPlugin","link":"<a href=\"Bajo.html#isValidPlugin\">isValidPlugin</a>","description":"<p>Check whether directory is a valid Bajo plugin.</p>"},{"title":"Bajo#join","link":"<a href=\"Bajo.html#join\">join</a>","description":"<p>Human friendly join array of items.</p>"},{"title":"Bajo#numUnit","link":"<a href=\"Bajo.html#numUnit\">numUnit</a>","description":"<p>Return its numeric portion of a value.</p>"},{"title":"Bajo#readAllConfigs","link":"<a href=\"Bajo.html#readAllConfigs\">readAllConfigs</a>","description":"<p>Read all config files from path.</p>"},{"title":"Bajo#readAsConfig","link":"<a href=\"Bajo.html#readAsConfig\">readAsConfig</a>","description":"<p>Read config using all registered config handlers. The first handler that returns a\nvalid object or array will be used.</p>"},{"title":"Bajo#readConfig","link":"<a href=\"Bajo.html#readConfig\">readConfig</a>","description":"<p>Read and parse file as config object. Supported types: <code>.js</code>, <code>.json</code> and <code>.yml/.yaml</code>.\nMore supports can be added using plugin. {@link https://github.com/ardhi/bajo-config|bajo-config} gives you additional supports for <code>.yml</code>, <code>.yaml</code> and <code>.toml</code> file.</p>\n<p>If file extension is <code>.*</code>, it will be auto detected and parsed accordingly</p>"},{"title":"Bajo#readJson","link":"<a href=\"Bajo.html#readJson\">readJson</a>","description":"<p>Read and parse json file.</p>"},{"title":"Bajo#runHook","link":"<a href=\"Bajo.html#runHook\">runHook</a>","description":"<p>Run named hook/event.</p>"},{"title":"Bajo#saveAsDownload","link":"<a href=\"Bajo.html#saveAsDownload\">saveAsDownload</a>","description":"<p>Save item as file in Bajo's download directory. That is a directory inside your\nBajo plugin's data directory.</p>\n<p>If file exists already, file will automatically be\nrenamed incrementally.</p>"},{"title":"Bajo#toJson","link":"<a href=\"Bajo.html#toJson\">toJson</a>","description":"<p>Convert data to JSON string.</p>"},{"title":"Bajo#toYaml","link":"<a href=\"Bajo.html#toYaml\">toYaml</a>","description":"<p>Convert object to YAML string</p>"},{"title":"Bajo#toYml","link":"<a href=\"Bajo.html#toYml\">toYml</a>","description":"<p>Convert object to YML string. Alias for toYaml.</p>"},{"title":"Bajo#whiteSpace","link":"<a href=\"Bajo.html#whiteSpace\">whiteSpace</a>","description":"<p>White space characters</p>"},{"title":"Bajo.TDataType","link":"<a href=\"Bajo.html#.TDataType\">TDataType</a>","description":"<p>Supported data types.</p>"},{"title":"Bajo.TFormatResult","link":"<a href=\"Bajo.html#.TFormatResult\">TFormatResult</a>","description":"<p>Object returned by {@link Bajo#getUnitFormat|bajo:getUnitFormat}.</p>"},{"title":"Bajo.TFormatType","link":"<a href=\"Bajo.html#.TFormatType\">TFormatType</a>","description":"<p>General format types,</p>"},{"title":"Bajo.TNsPathPairs","link":"<a href=\"Bajo.html#.TNsPathPairs\">TNsPathPairs</a>","description":"<p>Name based <code>{ns}:{path}</code> format.</p>"},{"title":"Bajo.TNsPathResult","link":"<a href=\"Bajo.html#.TNsPathResult\">TNsPathResult</a>","description":"<p>Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath}.</p>"},{"title":"Base","link":"<a href=\"Base.html\">Base</a>","description":"<p>Constructor.</p>"},{"title":"Base#dependencies","link":"<a href=\"Base.html#dependencies\">dependencies</a>","description":"<p>Dependencies to other plugins. Enter all plugin's package name your plugin dependent from.</p>\n<p>Semver is also supported.</p>"},{"title":"Base#dispose","link":"<a href=\"Base.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Base#exit","link":"<a href=\"Base.html#exit\">exit</a>","description":"<p>Upon app termination, this method will be called first. Mostly useful for system cleanup,\ndelete temporary files, freeing resources etc.</p>"},{"title":"Base#init","link":"<a href=\"Base.html#init\">init</a>","description":"<p>After config is read, plugin will be initialized.</p>"},{"title":"Base#loadConfig","link":"<a href=\"Base.html#loadConfig\">loadConfig</a>","description":"<p>Load config from file in data directory, program arguments and environment variables. Level of importance:\n<code>Env Variables &gt; Program Arguments &gt; Config File</code></p>"},{"title":"Base#start","link":"<a href=\"Base.html#start\">start</a>","description":"<p>This method will be called after plugin's init. You can still change your config here,\nbecause after plugin is started, config will be deep frozen</p>"},{"title":"Base#stop","link":"<a href=\"Base.html#stop\">stop</a>","description":"<p>Reserved for future use. This method will be called before plugin is stopped.</p>"},{"title":"Cache","link":"<a href=\"Cache.html\">Cache</a>","description":"<p>Constructor.</p>"},{"title":"Cache#_purgeItem","link":"<a href=\"Cache.html#_purgeItem\">_purgeItem</a>","description":"<p>Remove a specific cache namespace or all first-level namespaces.</p>"},{"title":"Cache#dispose","link":"<a href=\"Cache.html#dispose\">dispose</a>","description":"<p>Dispose internal reference.</p>"},{"title":"Cache#getRootDir","link":"<a href=\"Cache.html#getRootDir\">getRootDir</a>","description":"<p>Get root directory for this class. It will be used to store all cache files, organized by namespace and TTL.</p>"},{"title":"Cache#load","link":"<a href=\"Cache.html#load\">load</a>","description":"<p>Load cached content when available and not expired.</p>"},{"title":"Cache#prep","link":"<a href=\"Cache.html#prep\">prep</a>","description":"<p>Prepare cache paths for a namespaced key and TTL.</p>"},{"title":"Cache#purge","link":"<a href=\"Cache.html#purge\">purge</a>","description":"<p>Purge cache by namespace or remove expired TTL directories.</p>"},{"title":"Cache#save","link":"<a href=\"Cache.html#save\">save</a>","description":"<p>Save a value into cache for the given key and TTL directory.</p>"},{"title":"Cache#sync","link":"<a href=\"Cache.html#sync\">sync</a>","description":"<p>Return cached content, and store the fallback value if cache is empty.</p>"},{"title":"Err","link":"<a href=\"Err.html\">Err</a>","description":"<p>Constructor.</p>"},{"title":"Err#fatal","link":"<a href=\"Err.html#fatal\">fatal</a>","description":"<p>Print instance on console and terminate process.</p>"},{"title":"Err#formatErrorDetails","link":"<a href=\"Err.html#formatErrorDetails\">formatErrorDetails</a>","description":"<p>Pretty format error details.</p>\n<p>Formatted error will be applied directly to the value parameter, and a detailsMessage\nwill be returned for display purpose.</p>"},{"title":"Err#message","link":"<a href=\"Err.html#message\">message</a>","description":"<p>Translated message.</p>"},{"title":"Err#orgMessage","link":"<a href=\"Err.html#orgMessage\">orgMessage</a>","description":"<p>Original message before translation.</p>"},{"title":"Err#payload","link":"<a href=\"Err.html#payload\">payload</a>","description":"<p>Error payload extracted from the last arguments.</p>"},{"title":"Err#write","link":"<a href=\"Err.html#write\">write</a>","description":"<p>Write message to the console.</p>"},{"title":"Log","link":"<a href=\"Log.html\">Log</a>","description":"<p>Constructor.</p>"},{"title":"Log#_lastDelta","link":"<a href=\"Log.html#_lastDelta\">_lastDelta</a>","description":"<p>Last delta time in millisecond since app started. Used for log's time taken feature.</p>"},{"title":"Log#app","link":"<a href=\"Log.html#app\">app</a>","description":"<p>The app instance.</p>"},{"title":"Log#debug","link":"<a href=\"Log.html#debug\">debug</a>","description":"<p>Display &amp; format message in <code>debug</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#dispose","link":"<a href=\"Log.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Log#error","link":"<a href=\"Log.html#error\">error</a>","description":"<p>Display &amp; format message in <code>error</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#fatal","link":"<a href=\"Log.html#fatal\">fatal</a>","description":"<p>Display &amp; format message in <code>fatal</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#formatMsg","link":"<a href=\"Log.html#formatMsg\">formatMsg</a>","description":"<p>Display &amp; format message according to one of these rules:</p>\n<ol>\n<li><code>level</code> <code>prefix</code> <code>text</code> <code>var 1</code> <code>var 2</code> <code>...var n</code> - Translate <code>text</code> and interpolate with <code>vars</code> for level <code>level</code></li>\n<li><code>level</code> <code>prefix</code> <code>data</code> <code>text</code> <code>var 1</code> <code>var 2</code> <code>...var n</code> - As above, and append stringified <code>data</code></li>\n<li><code>level</code> <code>prefix</code> <code>error</code> - Format as {@link Err} object. If current log level is <em>trace</em>, dump it on screen</li>\n</ol>\n<p>In <code>prod</code> environment, log will be delivered as JSON stringified object. See {@link Log.TJsonOutput} for more info</p>"},{"title":"Log#getErrorMessage","link":"<a href=\"Log.html#getErrorMessage\">getErrorMessage</a>","description":"<p>Get error message from an Error object. If the message is empty, return the code or statusCode instead.</p>"},{"title":"Log#getRotationPattern","link":"<a href=\"Log.html#getRotationPattern\">getRotationPattern</a>","description":"<p>Calculate pattern used for log rotation. Used by {@link Log#save|save} method to determine the log file name.</p>"},{"title":"Log#info","link":"<a href=\"Log.html#info\">info</a>","description":"<p>Display &amp; format message in <code>info</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#save","link":"<a href=\"Log.html#save\">save</a>","description":"<p>Save log to file in <code>{dataDir}/log</code>.</p>"},{"title":"Log#silent","link":"<a href=\"Log.html#silent\">silent</a>","description":"<p>Display &amp; format message in <code>silent</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#trace","link":"<a href=\"Log.html#trace\">trace</a>","description":"<p>Display &amp; format message in <code>trace</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#warn","link":"<a href=\"Log.html#warn\">warn</a>","description":"<p>Display &amp; format message in <code>warn</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log.TJsonOutput","link":"<a href=\"Log.html#.TJsonOutput\">TJsonOutput</a>","description":"<p>Log output in stringified JSON format. Returned when app run in <code>prod</code> environment.</p>"},{"title":"Log.TLevels","link":"<a href=\"Log.html#.TLevels\">TLevels</a>"},{"title":"Plugin","link":"<a href=\"Plugin.html\">Plugin</a>","description":"<p>Constructor.</p>"},{"title":"Plugin#alias","link":"<a href=\"Plugin.html#alias\">alias</a>","description":"<p>Plugin alias. Derived plugin must provide its own, unique alias. If it left blank,\nBajo will provide this automatically (by using the kebab-cased version of plugin name).</p>"},{"title":"Plugin#app","link":"<a href=\"Plugin.html#app\">app</a>","description":"<p>Reference to the app instance</p>"},{"title":"Plugin#config","link":"<a href=\"Plugin.html#config\">config</a>","description":"<p>Configuration object.</p>"},{"title":"Plugin#dispose","link":"<a href=\"Plugin.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Plugin#dump","link":"<a href=\"Plugin.html#dump\">dump</a>","description":"<p>Alias to <code>this.app.dump()</code>.</p>"},{"title":"Plugin#error","link":"<a href=\"Plugin.html#error\">error</a>","description":"<p>Create an instance of {@link Err} object.</p>"},{"title":"Plugin#fatal","link":"<a href=\"Plugin.html#fatal\">fatal</a>","description":"<p>Create an instance of Err object, display it on screen and then force\nterminate the app.</p>"},{"title":"Plugin#getConfig","link":"<a href=\"Plugin.html#getConfig\">getConfig</a>","description":"<p>Get plugin's config value.</p>"},{"title":"Plugin#getPkgInfo","link":"<a href=\"Plugin.html#getPkgInfo\">getPkgInfo</a>","description":"<p>Get package info.</p>"},{"title":"Plugin#log","link":"<a href=\"Plugin.html#log\">log</a>","description":"<p>Shortcut to {@link App#log} with prefix parameter set to this plugin namespace.</p>"},{"title":"Plugin#ns","link":"<a href=\"Plugin.html#ns\">ns</a>","description":"<p>Namespace (ns) or plugin's name. It is the camel cased version of plugin's package name.</p>"},{"title":"Plugin#pkgName","link":"<a href=\"Plugin.html#pkgName\">pkgName</a>","description":"<p>Package name, the one from package.json.</p>"},{"title":"Plugin#selfBind","link":"<a href=\"Plugin.html#selfBind\">selfBind</a>","description":"<p>Force bind methods to self (<code>this</code>).</p>"},{"title":"Plugin#t","link":"<a href=\"Plugin.html#t\">t</a>","description":"<p>Translate text and interpolate with given <code>args</code>.</p>\n<p>Shortcut to {@link App#t} with ns parameter set to this plugin namespace.</p>"},{"title":"Plugin#te","link":"<a href=\"Plugin.html#te\">te</a>","description":"<p>Check whether translation text/key exists.</p>\n<p>Shortcut to {@link App#te} with ns parameter set to this plugin namespace.</p>"},{"title":"Print","link":"<a href=\"Print.html\">Print</a>"},{"title":"Print#buildText","link":"<a href=\"Print.html#buildText\">buildText</a>","description":"<p>Translate text, prefixed with counter and/or datetime etc.</p>"},{"title":"Print#clear","link":"<a href=\"Print.html#clear\">clear</a>","description":"<p>Clear spinner text.</p>"},{"title":"Print#fail","link":"<a href=\"Print.html#fail\">fail</a>","description":"<p>Print failed message, prefixed with a cross icon.</p>"},{"title":"Print#fatal","link":"<a href=\"Print.html#fatal\">fatal</a>","description":"<p>Print failed message, prefixed with a cross icon and exit application abruptly.</p>"},{"title":"Print#getElapsed","link":"<a href=\"Print.html#getElapsed\">getElapsed</a>","description":"<p>Get elapsed time since instance is created.</p>"},{"title":"Print#info","link":"<a href=\"Print.html#info\">info</a>","description":"<p>Print information message, prefixed with an info icon.</p>"},{"title":"Print#options","link":"<a href=\"Print.html#options\">options</a>","description":"<p>Options object.</p>"},{"title":"Print#ora","link":"<a href=\"Print.html#ora\">ora</a>","description":"<p>ora instance</p>"},{"title":"Print#render","link":"<a href=\"Print.html#render\">render</a>","description":"<p>Force render spinner.</p>"},{"title":"Print#setOpts","link":"<a href=\"Print.html#setOpts\">setOpts</a>","description":"<p>Setting spinner options; override the one passed at constructor.</p>"},{"title":"Print#setText","link":"<a href=\"Print.html#setText\">setText</a>","description":"<p>Set spinner's text,</p>"},{"title":"Print#spinner","link":"<a href=\"Print.html#spinner\">spinner</a>","description":"<p>Create a new print instance.</p>"},{"title":"Print#start","link":"<a href=\"Print.html#start\">start</a>","description":"<p>Start the spinner.</p>"},{"title":"Print#startTime","link":"<a href=\"Print.html#startTime\">startTime</a>","description":"<p>Start time of the instance, used to calculate elapsed time.</p>"},{"title":"Print#stop","link":"<a href=\"Print.html#stop\">stop</a>","description":"<p>Stop the spinner.</p>"},{"title":"Print#succeed","link":"<a href=\"Print.html#succeed\">succeed</a>","description":"<p>Print success message, prefixed with a check icon</p>"},{"title":"Print#warn","link":"<a href=\"Print.html#warn\">warn</a>","description":"<p>Print warning message, prefixed with a warn icon.</p>"},{"title":"Print.TOptions","link":"<a href=\"Print.html#.TOptions\">TOptions</a>"},{"title":"Tools","link":"<a href=\"Tools.html\">Tools</a>"},{"title":"Tools#app","link":"<a href=\"Tools.html#app\">app</a>","description":"<p>The app instance</p>"},{"title":"Tools#dispose","link":"<a href=\"Tools.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Tools#plugin","link":"<a href=\"Tools.html#plugin\">plugin</a>","description":"<p>Attached plugin</p>"},{"title":"Tools#selfBind","link":"<a href=\"Tools.html#selfBind\">selfBind</a>","description":"<p>Force bind methods to self (<code>this</code>).</p>"},{"title":"bajo.default:afterReadConfig","link":"<a href=\"bajo_.html#.default:afterReadConfig\">default:afterReadConfig</a>","description":"<p>Run after a non override/extended configuration file is read.</p>"},{"title":"bajo.extend:afterReadConfig","link":"<a href=\"bajo_.html#.extend:afterReadConfig\">extend:afterReadConfig</a>","description":"<p>Run after a extended configuration file is read.</p>"},{"title":"bajo.extend:beforeReadConfig","link":"<a href=\"bajo_.html#.extend:beforeReadConfig\">extend:beforeReadConfig</a>","description":"<p>Run before a extended configuration file is read.</p>"},{"title":"bajo.override:afterReadConfig","link":"<a href=\"bajo_.html#.override:afterReadConfig\">override:afterReadConfig</a>","description":"<p>Run after a configuration file override is read.</p>"},{"title":"bajo.override:beforeReadConfig","link":"<a href=\"bajo_.html#.override:beforeReadConfig\">override:beforeReadConfig</a>","description":"<p>Run before a configuration file override is read.</p>"},{"title":"boot","link":"<a href=\"global.html#boot\">boot</a>","description":"<p>Main entry point of a Bajo app. Returned value is the app instance itself.</p>\n<p>While you can code directly around it, you typically write your code the main plugin (<code>{mainNs}</code>) or\nwriting your own custom plugin.</p>\n<p>I recommend the second method for its portability.</p>"},{"title":"module:Helper","link":"<a href=\"module-Helper.html\">Helper</a>","description":"<p>Internal helpers called by Bajo and other classes. It should remains\nhidden and not to be imported by any program.</p>"},{"title":"module:Helper.bootOrder","link":"<a href=\"module-Helper.html#.bootOrder\">bootOrder</a>","description":"<p>Setup plugins boot orders by reading plugin's <code>.bootorder</code> file if provided.</p>"},{"title":"module:Helper.bootPlugins","link":"<a href=\"module-Helper.html#.bootPlugins\">bootPlugins</a>","description":"<p>Iterate through all plugins loaded and do:</p>\n<ol>\n<li>{@link module:Helper/Base.buildConfigs|build configs}</li>\n<li>{@link module:Helper/Base.checkNameAliases|ensure names &amp; aliases uniqueness}</li>\n<li>{@link module:Helper/Base.checkDependencies|ensure dependencies are met}</li>\n<li>{@link module:Helper/Base.collectHooks|collect hooks}</li>\n<li>{@link module:Helper/Base.run|run plugins}</li>\n</ol>"},{"title":"module:Helper.buildBaseConfig","link":"<a href=\"module-Helper.html#.buildBaseConfig\">buildBaseConfig</a>","description":"<p>Building bajo base config. Mostly dealing with directory setups:</p>\n<ul>\n<li>determine base directory</li>\n<li>check whether data directory is valid. If not exist, create one inside app dir</li>\n<li>ensure data config directory is there</li>\n<li>ensure tmp dir is there</li>\n<li>read the list of plugins from <code>.plugins</code> file</li>\n</ul>"},{"title":"module:Helper.buildConfigs","link":"<a href=\"module-Helper.html#.buildConfigs\">buildConfigs</a>","description":"<p>Build configurations</p>"},{"title":"module:Helper.buildExtConfig","link":"<a href=\"module-Helper.html#.buildExtConfig\">buildExtConfig</a>","description":"<p>Bajo extra config:</p>\n<ul>\n<li>reading config file</li>\n<li>merge config with arguments &amp; environments values</li>\n<li>Set environment (<code>dev</code> or <code>prod</code>)</li>\n</ul>"},{"title":"module:Helper.buildPlugins","link":"<a href=\"module-Helper.html#.buildPlugins\">buildPlugins</a>","description":"<p>Building all plugins:</p>\n<ul>\n<li>load from app's pluginPkgs</li>\n<li>iterate through the list and build related plugins</li>\n<li>making sure main plugin is there. If not, create from template</li>\n<li>attach these plugins to the app instance</li>\n</ul>"},{"title":"module:Helper.checkDependencies","link":"<a href=\"module-Helper.html#.checkDependencies\">checkDependencies</a>","description":"<p>Ensure dependencies are met</p>"},{"title":"module:Helper.checkNameAliases","link":"<a href=\"module-Helper.html#.checkNameAliases\">checkNameAliases</a>","description":"<p>Ensure for names and aliases to be unique and no clashes with other plugins</p>"},{"title":"module:Helper.collectConfigHandlers","link":"<a href=\"module-Helper.html#.collectConfigHandlers\">collectConfigHandlers</a>","description":"<p>Collect all config handlers, including the one provided by plugins</p>"},{"title":"module:Helper.collectHooks","link":"<a href=\"module-Helper.html#.collectHooks\">collectHooks</a>","description":"<p>Collect and build hooks and push them to the bajo's hook system</p>"},{"title":"module:Helper.exitHandler","link":"<a href=\"module-Helper.html#.exitHandler\">exitHandler</a>","description":"<p>Attach plugins exit handlers and make sure the app shutdowns gracefully</p>"},{"title":"module:Helper.findDeep","link":"<a href=\"module-Helper.html#.findDeep\">findDeep</a>","description":"<p>Find item deep in paths.</p>"},{"title":"module:Helper.freeze","link":"<a href=\"module-Helper.html#.freeze\">freeze</a>","description":"<p>Freeze object.</p>"},{"title":"module:Helper.importModule","link":"<a href=\"module-Helper.html#.importModule\">importModule</a>","description":"<p>Import file/module from any loaded plugins.</p>\n<p>E.g. your plugin structure looks like this:</p>\n<pre class=\"prettyprint source\"><code>|- src\n| |- lib\n| | |- my-module.js\n|- index.js\n|- package.json\n</code></pre>\n<p>And this is how to import <code>my-module.js</code>:</p>\n<pre class=\"prettyprint source lang-javascript\"><code>const { importModule } = this.app.bajo\nconst myModule = await importModule('myPlugin:/src/lib/my-module.js')\n</code></pre>"},{"title":"module:Helper.run","link":"<a href=\"module-Helper.html#.run\">run</a>","description":"<p>Finally, run all plugins</p>"},{"title":"module:Helper.runAsApplet","link":"<a href=\"module-Helper.html#.runAsApplet\">runAsApplet</a>","description":"<p>If app is in <code>applet</code> mode, this little helper should take care plugin's applet boot process</p>"},{"title":"module:Hook","link":"<a href=\"module-Hook.html\">Hook</a>"},{"title":"module:Hook~THook","link":"<a href=\"module-Hook.html#~THook\">THook</a>"},{"title":"module:Hook~bajo:afterAllInit","link":"<a href=\"module-Hook.html#~bajo:afterAllInit\">bajo:afterAllInit</a>","description":"<p>Run after all plugins are initialized. You can use this hook to do some post-initialization process.</p>"},{"title":"module:Hook~bajo:afterAllStart","link":"<a href=\"module-Hook.html#~bajo:afterAllStart\">bajo:afterAllStart</a>","description":"<p>Run after all plugins are started. You can use this hook to do some post-start process.</p>"},{"title":"module:Hook~bajo:afterBoot","link":"<a href=\"module-Hook.html#~bajo:afterBoot\">bajo:afterBoot</a>","description":"<p>Run after boot process. You can use this hook to do some post-boot process.</p>"},{"title":"module:Hook~bajo:afterBuildCollection","link":"<a href=\"module-Hook.html#~bajo:afterBuildCollection\">bajo:afterBuildCollection</a>","description":"<p>Run after collection is built.</p>"},{"title":"module:Hook~bajo:afterCollectHooks","link":"<a href=\"module-Hook.html#~bajo:afterCollectHooks\">bajo:afterCollectHooks</a>","description":"<p>Run after hooks are collected. You can use this hook to modify the collected hooks before\nthey are recognized as application hooks.</p>"},{"title":"module:Hook~bajo:afterReadConfig","link":"<a href=\"module-Hook.html#~bajo:afterReadConfig\">bajo:afterReadConfig</a>","description":"<p>Run after all read processes of a configuration file are completed.</p>"},{"title":"module:Hook~bajo:beforeAllInit","link":"<a href=\"module-Hook.html#~bajo:beforeAllInit\">bajo:beforeAllInit</a>","description":"<p>Run before all plugins are initialized. You can use this hook to do some pre-initialization process.</p>"},{"title":"module:Hook~bajo:beforeAllStart","link":"<a href=\"module-Hook.html#~bajo:beforeAllStart\">bajo:beforeAllStart</a>","description":"<p>Run before all plugins are started. You can use this hook to do some pre-start process.</p>"},{"title":"module:Hook~bajo:beforeBoot","link":"<a href=\"module-Hook.html#~bajo:beforeBoot\">bajo:beforeBoot</a>","description":"<p>Run before boot process. You can use this hook to do some pre-boot process.</p>"},{"title":"module:Hook~bajo:beforeBuildCollection","link":"<a href=\"module-Hook.html#~bajo:beforeBuildCollection\">bajo:beforeBuildCollection</a>","description":"<p>Run before collection is built.</p>"},{"title":"module:Hook~bajo:beforeReadConfig","link":"<a href=\"module-Hook.html#~bajo:beforeReadConfig\">bajo:beforeReadConfig</a>","description":"<p>Run before a configuration file is read.</p>"},{"title":"module:Hook~{ns}:afterAppletRun","link":"<a href=\"module-Hook.html#~%257Bns%257D:afterAppletRun\">{ns}:afterAppletRun</a>","description":"<p>Run after applet is run. <code>{ns}</code> is the applet's namespace</p>"},{"title":"module:Hook~{ns}:afterInit","link":"<a href=\"module-Hook.html#~%257Bns%257D:afterInit\">{ns}:afterInit</a>","description":"<p>Run after <code>{ns}</code> plugins are initialized. You can use this hook to do some post-initialization process.</p>"},{"title":"module:Hook~{ns}:afterStart","link":"<a href=\"module-Hook.html#~%257Bns%257D:afterStart\">{ns}:afterStart</a>","description":"<p>Run after <code>{ns}</code> plugins are started. You can use this hook to do some post-start process.</p>"},{"title":"module:Hook~{ns}:beforeAppletRun","link":"<a href=\"module-Hook.html#~%257Bns%257D:beforeAppletRun\">{ns}:beforeAppletRun</a>","description":"<p>Run before applet is run. <code>{ns}</code> is the applet's namespace</p>"},{"title":"module:Hook~{ns}:beforeInit","link":"<a href=\"module-Hook.html#~%257Bns%257D:beforeInit\">{ns}:beforeInit</a>","description":"<p>Run before <code>{ns}</code> plugins are initialized. You can use this hook to do some pre-initialization process.</p>"},{"title":"module:Hook~{ns}:beforeStart","link":"<a href=\"module-Hook.html#~%257Bns%257D:beforeStart\">{ns}:beforeStart</a>","description":"<p>Run after <code>{ns}</code> plugins are initialized. You can use this hook to do some pre-start process.</p>"}]}
1
+ {"list":[{"title":"App","link":"<a href=\"App.html\">App</a>","description":"<p>Constructor. See {@link App.TOptions} if you want to write custom boot process for your app without using the default boot module.</p>"},{"title":"App#addPlugin","link":"<a href=\"App.html#addPlugin\">addPlugin</a>","description":"<p>Add and save plugin and its base class definition (if provided) to the app instance. You can then reference\nthe plugin using its namespace, e.g. <code>this.myPlugin</code> or <code>this['myPlugin']</code>.</p>"},{"title":"App#applet","link":"<a href=\"App.html#applet\">applet</a>","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 {@link module:Applet|applet} for details.</p>"},{"title":"App#applets","link":"<a href=\"App.html#applets\">applets</a>","description":"<p>Applets container. Usefull to get all available applets in your app. See {@link module:Applet|applet} for details.</p>"},{"title":"App#args","link":"<a href=\"App.html#args\">args</a>","description":"<p>Parsed program arguments.</p>\n<p>Example:</p>\n<pre class=\"prettyprint source lang-js\"><code>$ node index.js arg1 arg2\n...\nconsole.log(this.args) // it should print: ['arg1', 'arg2']\n</code></pre>"},{"title":"App#argv","link":"<a href=\"App.html#argv\">argv</a>","description":"<p>Parsed program options:</p>\n<ul>\n<li>Dash (<code>-</code>) breaks the string into object keys</li>\n<li>While colon (<code>:</code>) is used as namespace - object separator. If no such namespace found, it is saved under <code>_</code>.</li>\n</ul>\n<p>Parsed object values are normalized to its primitives using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}</p>\n<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\n...\n// {\n// _: {\n// my: {\n// name: { first: 'John', last: 'Doe' },\n// birthDay: 'secret'\n// }\n// },\n// nameSpace: { path: { subPath: true } }\n// }</code></pre>"},{"title":"App#baseClass","link":"<a href=\"App.html#baseClass\">baseClass</a>","description":"<p>All plugin's base classes are saved here for reference so that you can extend them in your own plugins.</p>\n<p>Two basic classes from Bajo package are also provided: {@link Base} and {@link Tools}. These are the most\nused classes in Bajo plugin development. You can extend them to create your own plugin's base class:</p>\n<pre class=\"prettyprint source lang-javascript\"><code>// factory function to create your own plugin's base class\nasync function () {\n const { Base } = this.app.baseClass\n class MyBase extends Base {\n constructor(pkgName, app) {\n super(pkgName, app)\n this.myProperty = 'myValue' // your class property\n }\n\n async myMethod() {\n // your class method\n }\n }\n}\n</code></pre>"},{"title":"App#cache","link":"<a href=\"App.html#cache\">cache</a>","description":"<p>Internal cache instance. This is used to store temporary data in memory for faster access.</p>"},{"title":"App#configHandlers","link":"<a href=\"App.html#configHandlers\">configHandlers</a>","description":"<p>Config handlers container. This is where all config handlers are stored. Each handler\nis responsible to read and write config file in a particular format. Bajo uses this heavily to read/write config\nfiles and/or anything that needs to be parsed/stringified from string to object and vice versa.</p>\n<p>By default, there are three built-in handlers: <code>.js</code>, <code>.json</code>\nand <code>.yml/.yaml</code>. Use plugins to add more, e.g {@link https://github.com/ardhi/bajo-config|bajo-config}\nlets you to use <code>.toml</code>.</p>\n<blockquote>\n<p><em>Note</em>: <code>.js</code> is for reading only, it cannot be used to write config file.</p>\n</blockquote>"},{"title":"App#dump","link":"<a href=\"App.html#dump\">dump</a>","description":"<p>Dumping variable on screen. Like <code>console.log</code> 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.</p>\n<p>Any argument passed to this method will be displayed on screen.\nIf the last argument is a string <code>\\q</code> or <code>.q</code>, app will quit rightaway after dumping.</p>\n<p>If you have <code>bajoCli</code> plugin installed, variables will be displayed in a nice box using <code>boxen</code> package.\nOtherwise, it will fallback to <code>console.log</code> with util's inspect result.</p>\n<p>To have more control on how the variable is displayed, you can set options in Bajo's config under <code>dump</code> key.\nSee {@link Bajo.TConfig} for details.</p>"},{"title":"App#envVars","link":"<a href=\"App.html#envVars\">envVars</a>","description":"<p>Parsed environment variables. Support dotenv (<code>.env</code>) file too!</p>\n<ul>\n<li>Underscore (<code>_</code>) between keys merge those keys into a single camel-cased key</li>\n<li>Double underscores (<code>__</code>) between keys breaks the key into nested objects</li>\n<li>Meanwhile a dot (<code>.</code>) between keys breaks the key into nested, name-spaced objects</li>\n</ul>\n<p>Parsed object values are normalized to its primitives using {@link https://github.com/ladjs/dotenv-parse-variables|dotenv-parse-variables}</p>\n<p>Example:</p>\n<ul>\n<li><code>MY_KEY=secret</code> → <code>{ _: { myKey: 'secret' } }</code></li>\n<li><code>MY_KEY__SUB_KEY=supersecret</code> → <code>{ _: { myKey: { subKey: 'supersecret' } } }</code></li>\n<li><code>MY_NS.MY_NAME=John</code> → <code>{ myNs: { myName: 'John' } }</code></li>\n</ul>\n<blockquote>\n<p><strong>Tips</strong>: During boot process, Bajo will add <code>APPDIR</code> environment variable which points to your app's root directory.</p>\n</blockquote>"},{"title":"App#envs","link":"<a href=\"App.html#envs\">envs</a>","description":"<p>Supported environments. Read-only</p>"},{"title":"App#exit","link":"<a href=\"App.html#exit\">exit</a>","description":"<p>Terminate the app forcefully and back to console.</p>"},{"title":"App#getAllNs","link":"<a href=\"App.html#getAllNs\">getAllNs</a>","description":"<p>Get all loaded <strong>plugin namespaces</strong>.</p>"},{"title":"App#getAllPlugins","link":"<a href=\"App.html#getAllPlugins\">getAllPlugins</a>","description":"<p>Get all loaded plugins. Alias to {@link App#getPlugins|getPlugins()} with no namespace provided.</p>"},{"title":"App#getConfigFormats","link":"<a href=\"App.html#getConfigFormats\">getConfigFormats</a>","description":"<p>Method to list all supported config formats, that is, all file extensions that are supported\nby the app's config handlers.</p>"},{"title":"App#getPlugin","link":"<a href=\"App.html#getPlugin\">getPlugin</a>","description":"<p>Get plugin by its namespace or alias. If the plugin is not loaded, it will throw an error\nunless <code>silent</code> is set to <code>true</code>.</p>"},{"title":"App#getPluginDataDir","link":"<a href=\"App.html#getPluginDataDir\">getPluginDataDir</a>","description":"<p>Get plugin data directory. If the directory does not exist, it will be created automatically\nunless <code>ensureDir</code> is set to <code>false</code>.</p>"},{"title":"App#getPluginFile","link":"<a href=\"App.html#getPluginFile\">getPluginFile</a>","description":"<p>Resolve file path from:</p>\n<ul>\n<li>local/absolute file</li>\n<li>{@link Bajo.TNsPathPairs} e.g. <code>myPlugin:/path/to/file.txt</code></li>\n<li>file under <code>node_modules</code>, e.g. <code>myPlugin:node_modules/some-package/file.txt</code></li>\n</ul>"},{"title":"App#getPlugins","link":"<a href=\"App.html#getPlugins\">getPlugins</a>","description":"<p>Get loaded plugins by their namespaces. If no namespace is provided, it will return all loaded plugins.</p>"},{"title":"App#lib","link":"<a href=\"App.html#lib\">lib</a>","description":"<p>Gives you direct access to the most commonly used 3rd party library in a Bajo based app.\nNo manual import necessary, always available, anywhere, anytime!</p>"},{"title":"App#loadIntl","link":"<a href=\"App.html#loadIntl\">loadIntl</a>","description":"<p>Load internationalization &amp; languages files for particular plugin by its namespace.\nIt will load all supported languages defined in {@link Bajo.TConfig|<code>config.intl.supported</code>}\nand save them in <code>this[ns].intl</code> object.</p>"},{"title":"App#log","link":"<a href=\"App.html#log\">log</a>","description":"<p>Instance of the system log. This will automatically be instantiated early during boot process. See {@link Log} for details.</p>"},{"title":"App#mainNs","link":"<a href=\"App.html#mainNs\">mainNs</a>","description":"<p>App's main plugin namespace (<code>main</code>). Read-only</p>"},{"title":"App#options","link":"<a href=\"App.html#options\">options</a>","description":"<p>Copy of the provided options. See {@link App.TOptions} for details.</p>"},{"title":"App#pluginPkgs","link":"<a href=\"App.html#pluginPkgs\">pluginPkgs</a>","description":"<p>Original plugin's <strong>package names</strong> (not to be confused with plugin namespaces) container. Ypu can use this\ninformation to get the real package name of a plugin.</p>\n<blockquote>\n<p><strong>Reminder</strong>: In Bajo, plugin name/namespace is the camel-cased version of its package name.\nE.g. <code>my-plugin</code> → <code>myPlugin</code>.</p>\n</blockquote>"},{"title":"App#run","link":"<a href=\"App.html#run\">run</a>","description":"<p>Run application and begin the boot process. This method is called automatically by {@link boot|boot} script.</p>\n<p>Boot process includes:</p>\n<ul>\n<li>parsing environment values, program arguments, and options</li>\n<li>create {@link Bajo|Bajo} instance &amp; initialize it</li>\n<li>load all plugins, their hooks, their configs and any other necessary services &amp; resources</li>\n<li>{@link Bajo.runAsApplet|run in applet mode} if <code>-a</code> or <code>--applet</code> is given</li>\n</ul>\n<p>After boot process is completed, hook <code>bajo:afterBoot</code> is triggered.</p>\n<p>If app mode is <code>applet</code>, it runs your choosen applet instead.</p>"},{"title":"App#runAt","link":"<a href=\"App.html#runAt\">runAt</a>","description":"<p>Date/time when your app start. You can use this e.g. to calculate how long your app has been running. Read-only</p>"},{"title":"App#startPlugin","link":"<a href=\"App.html#startPlugin\">startPlugin</a>","description":"<p>Start a plugin by its namespace. It will call the plugin's <code>start</code> method with the provided arguments.</p>"},{"title":"App#stopPlugin","link":"<a href=\"App.html#stopPlugin\">stopPlugin</a>","description":"<p>Stop a plugin by its namespace. It will call the plugin's <code>stop</code> method with the provided arguments.</p>\n<p>Reserved for future use.</p>\n<blockquote>\n<p><strong>Note</strong>: Basically it is not a good idea to stop a plugin because other plugins\nmight be dependent on it. But if we could find a way to safely stop a plugin without breaking things,\nthis will be a cool feature because it allows dynamic management of plugins without restarting the application.</p>\n</blockquote>"},{"title":"App#t","link":"<a href=\"App.html#t\">t</a>","description":"<p>Translate text to the current language.</p>\n<p>It will search for the translation in the plugin's <code>intl</code> object first, interpolating the parameters if found,\nthen fallback to <code>bajo</code> plugin's <code>intl</code> object if not found.</p>\n<p>If the last parameter is an object with <code>lang</code> key, it will use that language instead of the default one.</p>\n<p>There is a shortcut to this method attached on all plugins. You'll normally call that shorcut\ninstead of this method, because that shortcut is bound to plugin's namespace already</p>\n<pre class=\"prettyprint source lang-js\"><code>... within your main plugin\nconst translated = this.app.t('main', 'My cute cat is %s', 'purring')\n// or within your plugin\nconst translated = this.t('My cute cat is %s', 'purring')\n</code></pre>"},{"title":"App#te","link":"<a href=\"App.html#te\">te</a>","description":"<p>Check whether translation text/key exists.</p>"},{"title":"App.TConfigHandler","link":"<a href=\"App.html#.TConfigHandler\">TConfigHandler</a>","description":"<p>Config handler definition. Your own handler must follow this structure.</p>"},{"title":"App.TEnv","link":"<a href=\"App.html#.TEnv\">TEnv</a>","description":"<p>Supported environments.</p>\n<p>Environment is one of the most important aspect of a Bajo app. It is used to determine how your app should behave\nin different environments. It allows you to have different configurations and settings,\nand as a plugin developer, you can also use it to determine how your plugin should behave in different environments.</p>"},{"title":"App.TLib","link":"<a href=\"App.html#.TLib\">TLib</a>","description":"<p>Most commonly used libraries by Bajo and its plugins. They are already imported and ready to use,\nso you don't have to import them again in your plugin.</p>\n<p>Example:</p>\n<pre class=\"prettyprint source lang-javascript\"><code>const { fs, dayjs } = this.app.lib\nfs.ensureDirSync('/path/to/dir')\nconst now = dayjs().format('YYYY-MM-DD HH:mm:ss')\n</code></pre>"},{"title":"App.TOptions","link":"<a href=\"App.html#.TOptions\">TOptions</a>","description":"<p>Options object passed to {@link App} constructor. By default, you don't need to pass any options,\nunless you want to manually override the default behavior.</p>"},{"title":"App.readHandler","link":"<a href=\"App.html#.readHandler\">readHandler</a>","description":"<p>Your read handler must follow this structure. It is used to read and parse config file in a particular format.</p>"},{"title":"App.writeHandler","link":"<a href=\"App.html#.writeHandler\">writeHandler</a>","description":"<p>Your write handler must follow this structure. It is used to write config file in a particular format.</p>"},{"title":"Bajo","link":"<a href=\"Bajo.html\">Bajo</a>","description":"<p>Constructor.</p>"},{"title":"Bajo#alias","link":"<a href=\"Bajo.html#alias\">alias</a>","description":"<p>Alias. Read-only</p>"},{"title":"Bajo#bootApp","link":"<a href=\"Bajo.html#bootApp\">bootApp</a>","description":"<p>Bajo boot process. This method is called by the {@link App} class during the app's boot process:</p>\n<ol>\n<li>Building Bajo's {@link module:Helper.buildBaseConfig|base configuration}</li>\n<li>Collect all {@link module:Helper.collectConfigHandlers|config handlers} from all loaded plugins</li>\n<li>Build {@link module:Helper.buildConfig|configuration} object</li>\n<li>{@link module:Helper.buildPlugins|Building plugins} listed in <code>package.json</code> or <code>.plugins</code> file</li>\n<li>Determining the {@link module:Helper.bootOrder|boot order}</li>\n<li>Ensure the {@link module:Helper.checkNameAliases|uniqueness} of all plugins' name and alias</li>\n<li>Ensure all plugins {@link module:Helper.checkDependencies|dependencies} are met</li>\n<li>Collect all {@link module:Helper.collectHooks|hooks} from all loaded plugins</li>\n<li>{@link module:Helper.runPlugins|Run all plugins} according to the boot order</li>\n<li>And finally attaching all {@link module:Helper.exitHandler|exit handlers} it could find</li>\n</ol>"},{"title":"Bajo#breakNsPath","link":"<a href=\"Bajo.html#breakNsPath\">breakNsPath</a>","description":"<p>Break <code>name</code> to their components.</p>\n<p>If path starts with <code>//</code>, e.g. name is <code>https://example.com</code>, it will be treated as a URL and returned as an\nobject with only <code>path</code> property filled with the original name.</p>\n<p>If query string is present in the path, it will be parsed and returned as an object with <code>qs</code>\nproperty containing the parsed query string.</p>\n<p>If path contains parameters in the format of <code>:key|value</code> or <code>{key|value}</code>, they will be extracted and returned\nas an object with <code>params</code> property containing the extracted parameters.</p>\n<p>This method is one of the most used method in Bajo. It is because every files, names, resources, and even commands\nare all identified by their namespace and path.</p>"},{"title":"Bajo#breakNsPathFromFile","link":"<a href=\"Bajo.html#breakNsPathFromFile\">breakNsPathFromFile</a>","description":"<p>Break file path to its namespace &amp; path infos.</p>"},{"title":"Bajo#buildCollections","link":"<a href=\"Bajo.html#buildCollections\">buildCollections</a>","description":"<p>Method to transform config's array or object into a collection of objects with uniformed structure. This is useful to build a collection of items\nfrom config's array or object, e.g. a collection of commands, routes, etc.</p>\n<p>You typically also provide a <code>handler</code> function to transform each item in the collection. The handler function will be called with an object\ncontaining the following keys:</p>\n<ul>\n<li><code>item</code>: the current item in the collection</li>\n<li><code>index</code>: the index of the current item in the collection</li>\n<li><code>cfg</code>: the entire config object</li>\n</ul>"},{"title":"Bajo#buildNsPath","link":"<a href=\"Bajo.html#buildNsPath\">buildNsPath</a>","description":"<p>Build ns/path pairs.</p>"},{"title":"Bajo#callHandler","link":"<a href=\"Bajo.html#callHandler\">callHandler</a>","description":"<p>Calling a function handler in any plugins:</p>\n<ul>\n<li>If name is a string, the corresponding plugin's method will be called with passed args as its parameters</li>\n<li>If name is a plugin instance, this will be used as the scope instead. The first args is now the handler name and the rest are its parameters</li>\n<li>If name is a function, this function will be run under scope with the remaining args</li>\n<li>If name is an object and has <code>handler</code> key in it, this function handler will be instead</li>\n</ul>"},{"title":"Bajo#config","link":"<a href=\"Bajo.html#config\">config</a>","description":"<p>Configuration object</p>"},{"title":"Bajo#eachPlugins","link":"<a href=\"Bajo.html#eachPlugins\">eachPlugins</a>","description":"<p>This function iterates through all loaded plugins and call the provided handler scoped as the running plugin.\nAnd an object with the following key serves as its parameter:</p>\n<ul>\n<li><code>file</code>: file matched the glob pattern</li>\n<li><code>dir</code>: plugin's base directory</li>\n</ul>"},{"title":"Bajo#format","link":"<a href=\"Bajo.html#format\">format</a>","description":"<p>Format value.</p>"},{"title":"Bajo#formatByType","link":"<a href=\"Bajo.html#formatByType\">formatByType</a>","description":"<p>Format value by type.</p>"},{"title":"Bajo#fromJs","link":"<a href=\"Bajo.html#fromJs\">fromJs</a>","description":"<p>Read and parse JavaScript file.</p>"},{"title":"Bajo#fromJson","link":"<a href=\"Bajo.html#fromJson\">fromJson</a>","description":"<p>Parse JSON string or read and parse JSON file.</p>"},{"title":"Bajo#fromYaml","link":"<a href=\"Bajo.html#fromYaml\">fromYaml</a>","description":"<p>Parse YAML text or read and parse YAML file.</p>"},{"title":"Bajo#fromYml","link":"<a href=\"Bajo.html#fromYml\">fromYml</a>","description":"<p>Parse YML text or read and parse YML file. Alias for {@link Bajo#fromYaml}.</p>"},{"title":"Bajo#getDownloadDir","link":"<a href=\"Bajo.html#getDownloadDir\">getDownloadDir</a>","description":"<p>Get download directory. If doesn't exist, it will be created automatically.</p>"},{"title":"Bajo#getMethod","link":"<a href=\"Bajo.html#getMethod\">getMethod</a>","description":"<p>Get class method by name.</p>"},{"title":"Bajo#getModuleDir","link":"<a href=\"Bajo.html#getModuleDir\">getModuleDir</a>","description":"<p>Get module directory.</p>"},{"title":"Bajo#getUnitFormat","link":"<a href=\"Bajo.html#getUnitFormat\">getUnitFormat</a>","description":"<p>Get unit format.</p>"},{"title":"Bajo#hooks","link":"<a href=\"Bajo.html#hooks\">hooks</a>","description":"<p>Hooks container. This is where all hooks definition are stored.</p>"},{"title":"Bajo#importModule","link":"<a href=\"Bajo.html#importModule\">importModule</a>","description":"<p>Import file/module from any loaded plugins.</p>\n<p>Method proxy from {@link module:Helper.importModule}</p>"},{"title":"Bajo#importPkg","link":"<a href=\"Bajo.html#importPkg\">importPkg</a>","description":"<p>Import one or more packages belongs to a plugin.</p>\n<p>If the last arguments passed is an object, this object serves as options object:</p>\n<ul>\n<li><code>returnDefault</code>: should return package's default export. Defaults to <code>true</code></li>\n<li><code>throwNotFound</code>: should throw if package is not found. Defaults to <code>false</code></li>\n<li><code>noCache</code>: always use fresh import. Defaults to <code>false</code></li>\n<li><code>asObject</code>: see below. Defaults to <code>false</code></li>\n</ul>\n<p>Return value:</p>\n<ul>\n<li>if <code>options.asObject</code> is <code>true</code> (default <code>false</code>), return as object with package's names as it's keys</li>\n<li>Otherwise depends on how many parameters are provided, it should return the named package or an array of packages</li>\n</ul>\n<p>Example: you want to import <code>delay</code> and <code>chalk</code> from <code>bajo</code> plugin because you want to use it in your code\n`javascript\nconst { importPkg } from this.app.bajo\nconst [delay, chalk] = await importPkg('bajo:delay', 'bajo:chalk')</p>\n<p>await delay(1000)\n...\n`</p>"},{"title":"Bajo#isLogInRange","link":"<a href=\"Bajo.html#isLogInRange\">isLogInRange</a>","description":"<p>Check whether log level is within log's app current level.</p>"},{"title":"Bajo#isValidApp","link":"<a href=\"Bajo.html#isValidApp\">isValidApp</a>","description":"<p>Check whether directory is a valid Bajo app.</p>"},{"title":"Bajo#isValidPlugin","link":"<a href=\"Bajo.html#isValidPlugin\">isValidPlugin</a>","description":"<p>Check whether directory is a valid Bajo plugin.</p>"},{"title":"Bajo#join","link":"<a href=\"Bajo.html#join\">join</a>","description":"<p>Return human friendly joined array of items.</p>"},{"title":"Bajo#numUnit","link":"<a href=\"Bajo.html#numUnit\">numUnit</a>","description":"<p>Get numeric portion and its unit from a string.</p>"},{"title":"Bajo#parseWithConfig","link":"<a href=\"Bajo.html#parseWithConfig\">parseWithConfig</a>","description":"<p>Parse <code>input</code> using all registered config handlers. The first handler that returns a\nvalid object or array will be used.</p>\n<p>Use this method if you want to parse a text <code>input</code> that can be in any format supported by the registered config handlers.</p>"},{"title":"Bajo#readAllConfigs","link":"<a href=\"Bajo.html#readAllConfigs\">readAllConfigs</a>","description":"<p>Read all forms of configuration files from file path.</p>\n<p>Internally, it will call {@link Bajo#readConfig} twice, first for the default config file and\nsecond for the environment based config file. Then it will merge both results using <code>defaultsDeep</code>.</p>"},{"title":"Bajo#readConfig","link":"<a href=\"Bajo.html#readConfig\">readConfig</a>","description":"<p>Read and parse file as config object. Supported types: <code>.js</code>, <code>.json</code> and <code>.yml/.yaml</code>.\nMore supports can be added using plugin. {@link https://ardhi.github.io/bajo-config|bajo-config} gives you additional supports for <code>.yml</code>, <code>.yaml</code> and <code>.toml</code> file.</p>\n<p>If file extension is <code>.*</code>, it will be auto detected and parsed accordingly</p>"},{"title":"Bajo#runHook","link":"<a href=\"Bajo.html#runHook\">runHook</a>","description":"<p>Run named {@link module:Hook}.</p>\n<p>If no hook found with the given name, it will return an empty array.\nIf a hook has <code>noWait</code> set to <code>true</code>, it will not wait for the hook to finish and will not return its result.</p>\n<blockquote>\n<p><strong>Note</strong>: Even though this method returns a result, it is not recommended to use the result for any purpose.\nUse the result only for debugging or logging purposes. Hooks are designed to be fast, lightweight and mutate\narguments given to them so that the next hook can benefit from the changes.</p>\n</blockquote>"},{"title":"Bajo#saveAsDownload","link":"<a href=\"Bajo.html#saveAsDownload\">saveAsDownload</a>","description":"<p>Save item as file in Bajo's download directory. That is a directory inside your\nBajo plugin's data directory.</p>\n<p>If file exists already, file will automatically be\nrenamed incrementally.</p>"},{"title":"Bajo#toJson","link":"<a href=\"Bajo.html#toJson\">toJson</a>","description":"<p>Convert data to JSON string, optionally write to file if <code>options.writeToFile</code> is provided.</p>"},{"title":"Bajo#toYaml","link":"<a href=\"Bajo.html#toYaml\">toYaml</a>","description":"<p>Convert object to YAML string, optionally write to file if <code>options.writeToFile</code> is provided.</p>"},{"title":"Bajo#toYml","link":"<a href=\"Bajo.html#toYml\">toYml</a>","description":"<p>Convert object to YML string, optionally write to file if <code>options.writeToFile</code> is provided. Alias for {@link Bajo#toYaml}.</p>"},{"title":"Bajo#whiteSpace","link":"<a href=\"Bajo.html#whiteSpace\">whiteSpace</a>","description":"<p>Array of white space characters. Used to trim strings</p>"},{"title":"Bajo.TConfig","link":"<a href=\"Bajo.html#.TConfig\">TConfig</a>"},{"title":"Bajo.TDataType","link":"<a href=\"Bajo.html#.TDataType\">TDataType</a>","description":"<p>Supported data types.</p>"},{"title":"Bajo.TFormatResult","link":"<a href=\"Bajo.html#.TFormatResult\">TFormatResult</a>","description":"<p>Object returned by {@link Bajo#getUnitFormat|bajo:getUnitFormat}.</p>"},{"title":"Bajo.TFormatType","link":"<a href=\"Bajo.html#.TFormatType\">TFormatType</a>","description":"<p>General format types,</p>"},{"title":"Bajo.TNsPathPairs","link":"<a href=\"Bajo.html#.TNsPathPairs\">TNsPathPairs</a>","description":"<p>Name in <code>{ns}:{path}</code> format.</p>"},{"title":"Bajo.TNsPathResult","link":"<a href=\"Bajo.html#.TNsPathResult\">TNsPathResult</a>","description":"<p>Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath()}.</p>"},{"title":"Base","link":"<a href=\"Base.html\">Base</a>","description":"<p>Constructor.</p>"},{"title":"Base#dependencies","link":"<a href=\"Base.html#dependencies\">dependencies</a>","description":"<p>Array of plugin dependencies. If your plugin depends on other plugins, you can specify their package names here e.g. <code>['bajo-config', 'bajo-cli']</code>, NOT the plugin name/namespace</p>"},{"title":"Base#dispose","link":"<a href=\"Base.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Base#exit","link":"<a href=\"Base.html#exit\">exit</a>","description":"<p>Upon app termination, this method will be called first. Mostly useful for system cleanup,\ndelete temporary files, freeing resources etc.</p>"},{"title":"Base#init","link":"<a href=\"Base.html#init\">init</a>","description":"<p>Plugin initialization. This method will be called by the framework during boot process, after configuration is loaded.</p>"},{"title":"Base#loadConfig","link":"<a href=\"Base.html#loadConfig\">loadConfig</a>","description":"<p>Load plugin configuration. This method will be called by the framework during boot process.</p>"},{"title":"Base#pkg","link":"<a href=\"Base.html#pkg\">pkg</a>","description":"<p>Package information from <code>package.json</code>. It will be automatically loaded by the framework during plugin initialization</p>"},{"title":"Base#start","link":"<a href=\"Base.html#start\">start</a>","description":"<p>Plugin start. This method will be called by the framework during boot process, after initialization. You still can\nmodifiy your plugin's configuration here before it is deep frozen.</p>"},{"title":"Base#stop","link":"<a href=\"Base.html#stop\">stop</a>","description":"<p>Reserved for future use. This method will be called before plugin is stopped.</p>"},{"title":"Base.package·json","link":"<a href=\"Base.html#.package%25C2%25B7json\">package·json</a>","description":"<p>To be recognized as a valid Bajo plugin, your package must be an <code>ES6 module</code> and have a <code>package.json</code> file\nwith the additional <code>bajo</code> property and at least the <code>type</code> property set to <code>plugin</code>.</p>\n<p>Other than <code>type</code>, you might need to specify these additional properties:</p>\n<ul>\n<li><code>type</code>: <code>string</code>, must be set to <code>plugin</code></li>\n<li><code>alias</code>: <code>string</code>, the alias name of your plugin. Must be unique among all plugins. If it is missing, it will be generated by Bajo as camel-cased version of your plugin namespace.</li>\n<li><code>dependencies</code>: <code>array</code>, if your plugin requires one or more other plugins to work, you need to put their <strong>package names</strong> in this array</li>\n</ul>\n<p>Example:</p>\n<pre class=\"prettyprint source lang-json\"><code>{\n &quot;name&quot;: &quot;my-plugin&quot;,\n &quot;version&quot;: &quot;1.0.0&quot;,\n &quot;description&quot;: &quot;My Bajo plugin&quot;,\n &quot;type&quot;: &quot;module&quot;,\n &quot;main&quot;: &quot;index.js&quot;,\n &quot;bajo&quot;: {\n &quot;type&quot;: &quot;plugin&quot;,\n &quot;alias&quot;: &quot;myplugin&quot;,\n &quot;dependencies&quot;: [&quot;bajo-config&quot;, &quot;bajo-cli&quot;]\n }\n}\n...\n</code></pre>\n<blockquote>\n<p><strong>Note</strong>: The dot symbol in <code>package.json</code> has been replaced with <code>·</code> symbol because of JSDoc theme limitation</p>\n</blockquote>\n<blockquote>\n<p><strong>Warning</strong>: Do not confuse with your app's {@link package·json|package.json} specification, since this one is for plugin while the other is for app.</p>\n</blockquote>"},{"title":"Cache","link":"<a href=\"Cache.html\">Cache</a>","description":"<p>Constructor.</p>"},{"title":"Cache#_purgeItem","link":"<a href=\"Cache.html#_purgeItem\">_purgeItem</a>","description":"<p>Remove a specific cache namespace or all first-level namespaces.</p>"},{"title":"Cache#dispose","link":"<a href=\"Cache.html#dispose\">dispose</a>","description":"<p>Dispose internal reference.</p>"},{"title":"Cache#getRootDir","link":"<a href=\"Cache.html#getRootDir\">getRootDir</a>","description":"<p>Get root directory. It will be used to store all cache files, organized by namespace and TTL.</p>"},{"title":"Cache#load","link":"<a href=\"Cache.html#load\">load</a>","description":"<p>Load cached content when available and not expired.</p>"},{"title":"Cache#prep","link":"<a href=\"Cache.html#prep\">prep</a>","description":"<p>Prepare cache paths for a namespaced key and TTL.</p>"},{"title":"Cache#purge","link":"<a href=\"Cache.html#purge\">purge</a>","description":"<p>Purge cache by namespace or remove expired TTL directories.</p>"},{"title":"Cache#save","link":"<a href=\"Cache.html#save\">save</a>","description":"<p>Save a value into cache for the given key and TTL directory.</p>"},{"title":"Cache#sync","link":"<a href=\"Cache.html#sync\">sync</a>","description":"<p>Return cached content, and store the fallback value if cache is empty</p>"},{"title":"Err","link":"<a href=\"Err.html\">Err</a>","description":"<p>Constructor.</p>"},{"title":"Err#fatal","link":"<a href=\"Err.html#fatal\">fatal</a>","description":"<p>Print instance on console and terminate process.</p>"},{"title":"Err#formatErrorDetails","link":"<a href=\"Err.html#formatErrorDetails\">formatErrorDetails</a>","description":"<p>Pretty format error details. Used to format error payloads that contain <code>details</code> property, which is an array of error details.</p>\n<p>Formatted error will be applied directly to the value parameter, and a <code>detailsMessage</code>\nwill be returned for display purpose.</p>"},{"title":"Err#message","link":"<a href=\"Err.html#message\">message</a>","description":"<p>Translated message</p>"},{"title":"Err#orgMessage","link":"<a href=\"Err.html#orgMessage\">orgMessage</a>","description":"<p>Original message before translation</p>"},{"title":"Err#payload","link":"<a href=\"Err.html#payload\">payload</a>","description":"<p>Error payload extracted from the last arguments, if any</p>"},{"title":"Err#write","link":"<a href=\"Err.html#write\">write</a>","description":"<p>Write message to the console. Chainable method, returns the Err instance itself.</p>\n<p>If a payload is provided, it will be merged with the existing payload. If <code>details</code> is provided in the payload,\nit will be formatted and merged to the existing payload and a <code>detailsMessage</code> will be generated for display purpose.</p>\n<p>Original message and translated message will be stored in <code>orgMessage</code> and <code>message</code> properties respectively.</p>\n<p><code>ns</code> property will be set to the plugin's namespace.</p>"},{"title":"Err.TErrDetails","link":"<a href=\"Err.html#.TErrDetails\">TErrDetails</a>","description":"<p>Error details object type definition. This type is used to represent detailed information about an error,\nincluding the field that caused the error, the error message, the value that caused the error, and any additional context.</p>\n<p>This type is particularly useful for validation errors, where you want to provide detailed feedback about what went wrong.</p>"},{"title":"Log","link":"<a href=\"Log.html\">Log</a>","description":"<p>Constructor.</p>"},{"title":"Log#_lastDelta","link":"<a href=\"Log.html#_lastDelta\">_lastDelta</a>","description":"<p>Last delta time in millisecond since app started. Used for log's time taken feature.</p>"},{"title":"Log#app","link":"<a href=\"Log.html#app\">app</a>","description":"<p>Reference to the app instance</p>"},{"title":"Log#debug","link":"<a href=\"Log.html#debug\">debug</a>","description":"<p>Display &amp; format message in <code>debug</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#dispose","link":"<a href=\"Log.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Log#error","link":"<a href=\"Log.html#error\">error</a>","description":"<p>Display &amp; format message in <code>error</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#fatal","link":"<a href=\"Log.html#fatal\">fatal</a>","description":"<p>Display &amp; format message in <code>fatal</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#formatMsg","link":"<a href=\"Log.html#formatMsg\">formatMsg</a>","description":"<p>Format &amp; display log message according to the current log level with the following syntax:</p>\n<ol>\n<li><code>level</code> <code>prefix</code> <code>text</code> <code>param 1</code> <code>param 2</code> <code>...param n</code> - Translate <code>text</code> and interpolate with <code>params</code> for level <code>level</code></li>\n<li><code>level</code> <code>prefix</code> <code>{data}</code> <code>text</code> <code>param 1</code> <code>param 2</code> <code>...param n</code> - Same as above, but with additional stringified <code>data</code> object to be logged</li>\n<li><code>level</code> <code>prefix</code> <code>{error}</code> - Format as {@link Err} object. If current log level is <strong>trace</strong>, dump it on screen</li>\n</ol>\n<p>In <code>prod</code> environment, log will be delivered as JSON stringified object. See {@link Log.TJsonOutput} for more info</p>"},{"title":"Log#getErrorMessage","link":"<a href=\"Log.html#getErrorMessage\">getErrorMessage</a>","description":"<p>Get error message from an Error object. If the error message is empty, return the error code or status code instead.</p>"},{"title":"Log#getRotationPattern","link":"<a href=\"Log.html#getRotationPattern\">getRotationPattern</a>","description":"<p>Calculate pattern used for log rotation. Used by {@link Log#save|save} method to determine the log file name.\nRotation pattern is based on the <code>rotation.cycle</code> configuration. See {@link App#config|app.config.log.rotation.cycle} for more info.</p>"},{"title":"Log#info","link":"<a href=\"Log.html#info\">info</a>","description":"<p>Display &amp; format message in <code>info</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#logDir","link":"<a href=\"Log.html#logDir\">logDir</a>","description":"<p>Directory to save log files. Defaults to <code>{dataDir}/log</code>. If log saving is on (see {@link App#config|app.config.log.save})\nand directory does not exist, this directory will be created automatically.</p>"},{"title":"Log#save","link":"<a href=\"Log.html#save\">save</a>","description":"<p>Save log to file in {@link Log#logDir|logDir}.</p>"},{"title":"Log#silent","link":"<a href=\"Log.html#silent\">silent</a>","description":"<p>Display &amp; format message in <code>silent</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#trace","link":"<a href=\"Log.html#trace\">trace</a>","description":"<p>Display &amp; format message in <code>trace</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log#warn","link":"<a href=\"Log.html#warn\">warn</a>","description":"<p>Display &amp; format message in <code>warn</code> level. See {@link Log#formatMsg|formatMsg} for details.</p>"},{"title":"Log.TJsonOutput","link":"<a href=\"Log.html#.TJsonOutput\">TJsonOutput</a>","description":"<p>Log output in stringified JSON format. Returned when app run in <code>prod</code> environment.</p>"},{"title":"Log.TLevels","link":"<a href=\"Log.html#.TLevels\">TLevels</a>"},{"title":"Main","link":"<a href=\"Main.html\">Main</a>","description":"<p>Main plugin class. This is the special plugin created by Bajo during the boot process, solely made\nfor you to write your own code for your application. It behaves like any other plugin, with a few differences:</p>\n<ul>\n<li>It always there, can't be disabled nor removed, reside in the app's root directory named <code>main</code>.\nIf it's folder is missing, Bajo will create it during the boot process with the default template and settings.</li>\n<li>You don't have to put this plugin in your <code>.plugin</code> file or <code>package.json</code> file,\nit is always present and always loaded as the <strong>last</strong> plugin to load.</li>\n<li>You write your app the same way you would do it with plugin:\n<ul>\n<li>by creating properties &amp; methods within your class</li>\n<li>by extending other plugins inside <code>/main/extend/{pluginNs}</code> folder</li>\n<li>by tapping hooks inside <code>/main/extend/bajo/hook</code> folder or <code>/main/extend/bajo/hook.js</code> file</li>\n<li>you even have your own config file in <code>{dataDir}/config/main.{ext}</code></li>\n</ul>\n</li>\n</ul>\n<p>Why it has to be a plugin? Because Bajo is a plugin-based framework, and everything is a plugin.\nThis brings some flexibilities, e.g. when someday you think your main plugin become too big,\njust turn it into a separate plugin and move it to its own package with almost no code changes at all.</p>\n<p>For more on this, see {@link Plugin} and {@link module:Hook}</p>"},{"title":"Plugin","link":"<a href=\"Plugin.html\">Plugin</a>","description":"<p>Constructor.</p>"},{"title":"Plugin#alias","link":"<a href=\"Plugin.html#alias\">alias</a>","description":"<p>Plugin alias. Derived plugin must provide its own, unique alias. If it left blank,\nBajo will provide this automatically (by using the kebab-cased version of plugin name).</p>\n<p>By convention, plugin alias should be all lower case, alphanumeric, and without any space or special character except <code>-</code>.\nIt should be unique across all plugins in the Bajo framework, as it is used to identify the plugin in the system beside its namespace.</p>"},{"title":"Plugin#app","link":"<a href=\"Plugin.html#app\">app</a>","description":"<p>Reference to the app instance</p>"},{"title":"Plugin#bindThis","link":"<a href=\"Plugin.html#bindThis\">bindThis</a>","description":"<p>Force bind methods to <code>this</code> context.</p>\n<p>Since JavaScript's <code>this</code> is dynamic, this method is useful to ensure\nthat the methods always refer to the correct instance of the class.</p>\n<p>Typically, you would call this method in the constructor of your plugin class,\npassing an array of method names or imported functions that you want to bind.</p>"},{"title":"Plugin#config","link":"<a href=\"Plugin.html#config\">config</a>","description":"<p>Configuration object.</p>"},{"title":"Plugin#dispose","link":"<a href=\"Plugin.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Plugin#dump","link":"<a href=\"Plugin.html#dump\">dump</a>","description":"<p>Shortcut to <code>this.app.dump()</code>.</p>"},{"title":"Plugin#error","link":"<a href=\"Plugin.html#error\">error</a>","description":"<p>Create an instance of {@link Err} object by providing an error message and optional arguments. Error instance will\nthen be displayed on console and returned so you can chain it with other methods if you want.</p>\n<p>Typically, you would use this method to throw an error and the framework will handle it gracefully.</p>\n<p>This method is a shortcut to create a new Err instance.</p>"},{"title":"Plugin#fatal","link":"<a href=\"Plugin.html#fatal\">fatal</a>","description":"<p>Same as {@link Plugin#error} but will <em>forcefully</em> terminate the process after printing the error to console.</p>"},{"title":"Plugin#getConfig","link":"<a href=\"Plugin.html#getConfig\">getConfig</a>","description":"<p>Get plugin's configuration object's value.</p>\n<blockquote>\n<p><strong>Note</strong>: Configuration object is frozen after boot process, so you can't modify it at runtime.\nIf you want to change its values, you need to do it in the config file, program options or via environment variables.\nHooks are also available to modify the configuration before the boot process.</p>\n</blockquote>"},{"title":"Plugin#getPkgInfo","link":"<a href=\"Plugin.html#getPkgInfo\">getPkgInfo</a>","description":"<p>Get package info. Basically it reads the package.json file and returns the requested fields</p>"},{"title":"Plugin#log","link":"<a href=\"Plugin.html#log\">log</a>","description":"<p>Shortcut to {@link App#log} with prefix parameter set to this plugin namespace.</p>"},{"title":"Plugin#ns","link":"<a href=\"Plugin.html#ns\">ns</a>","description":"<p>Namespace (ns) or plugin's name. It is the camel cased version of plugin's package name.</p>"},{"title":"Plugin#pkgName","link":"<a href=\"Plugin.html#pkgName\">pkgName</a>","description":"<p>Package name, the one from package.json.</p>"},{"title":"Plugin#t","link":"<a href=\"Plugin.html#t\">t</a>","description":"<p>Translate text and interpolate with given <code>args</code>.</p>\n<p>Shortcut to {@link App#t} with ns parameter set to this plugin namespace.</p>"},{"title":"Plugin#te","link":"<a href=\"Plugin.html#te\">te</a>","description":"<p>Check whether translation text (key) exists.</p>\n<p>Shortcut to {@link App#te} with ns parameter set to this plugin namespace.</p>"},{"title":"Print","link":"<a href=\"Print.html\">Print</a>","description":"<p>Constructor.</p>"},{"title":"Print#buildText","link":"<a href=\"Print.html#buildText\">buildText</a>","description":"<p>Translate text, prefixed with counter and/or datetime etc.</p>"},{"title":"Print#clear","link":"<a href=\"Print.html#clear\">clear</a>","description":"<p>Clear spinner text.</p>"},{"title":"Print#fail","link":"<a href=\"Print.html#fail\">fail</a>","description":"<p>Print failed message, prefixed with a cross icon.</p>"},{"title":"Print#fatal","link":"<a href=\"Print.html#fatal\">fatal</a>","description":"<p>Print failed message, prefixed with a cross icon and exit application abruptly.</p>"},{"title":"Print#getElapsed","link":"<a href=\"Print.html#getElapsed\">getElapsed</a>","description":"<p>Get elapsed time since instance is created.</p>"},{"title":"Print#info","link":"<a href=\"Print.html#info\">info</a>","description":"<p>Print information message, prefixed with an info icon.</p>"},{"title":"Print#options","link":"<a href=\"Print.html#options\">options</a>","description":"<p>Options object.</p>"},{"title":"Print#ora","link":"<a href=\"Print.html#ora\">ora</a>","description":"<p>ora instance</p>"},{"title":"Print#render","link":"<a href=\"Print.html#render\">render</a>","description":"<p>Force render spinner.</p>"},{"title":"Print#setOpts","link":"<a href=\"Print.html#setOpts\">setOpts</a>","description":"<p>Setting spinner options; override the one passed at constructor.</p>"},{"title":"Print#setText","link":"<a href=\"Print.html#setText\">setText</a>","description":"<p>Set spinner's text,</p>"},{"title":"Print#spinner","link":"<a href=\"Print.html#spinner\">spinner</a>","description":"<p>Create a new Print instance.</p>"},{"title":"Print#start","link":"<a href=\"Print.html#start\">start</a>","description":"<p>Start the spinner.</p>"},{"title":"Print#startTime","link":"<a href=\"Print.html#startTime\">startTime</a>","description":"<p>Start time of the instance, used to calculate elapsed time.</p>"},{"title":"Print#stop","link":"<a href=\"Print.html#stop\">stop</a>","description":"<p>Stop the spinner.</p>"},{"title":"Print#succeed","link":"<a href=\"Print.html#succeed\">succeed</a>","description":"<p>Print success message, prefixed with a check icon</p>"},{"title":"Print#warn","link":"<a href=\"Print.html#warn\">warn</a>","description":"<p>Print warning message, prefixed with a warn icon.</p>"},{"title":"Print.TOptions","link":"<a href=\"Print.html#.TOptions\">TOptions</a>"},{"title":"TConfig","link":"<a href=\"global.html#TConfig\">TConfig</a>","description":"<p>This is the default configuration object for Bajo and its plugins (see note below). It contains various settings that control the behavior of the framework.\nYou can override these settings by providing your own configuration object through the following methods in the order of priority:</p>\n<ol>\n<li>\n<p><strong>Environment variables</strong>:\nYou can set configuration options using environment variables too. <code>dotenv</code> is also supported.\nThe environment variable names should be in uppercase. Use double underscores instead of dots and single underscores\nto form camel cased name. For example, <code>LOG__TIME_TAKEN=true</code> will set <code>log.timeTaken</code> to <code>true</code></p>\n</li>\n<li>\n<p><strong>Command-line arguments</strong>:\nYou can pass configuration options as command-line arguments when starting the application. For example, you can use <code>--env=prod</code> to set the environment to <code>prod</code>.\nFor nested configuration options, use dash notation. For example, <code>--log-timeTaken</code> will set <code>log.timeTaken</code> to <code>true</code>.</p>\n</li>\n<li>\n<p><strong>Configuration files</strong>:\nCreate/open <code>{dataDir}/config/bajo.{ext}</code> file, where <code>{ext}</code> is the file extension of your choice.\nThis file is read during the boot process with app's {@link App#configHandlers} and merged with the default configuration object.</p>\n<p>By default, the supported file extensions are <code>.js</code>, <code>.json</code>, and <code>.yml/.yaml</code>. More extensions can be added by plugins.\nFor example, the {@link https://ardhi.github.io/bajo-config bajo-config} plugin provides support for <code>.toml</code> format.</p>\n<p>If the same filename with different extension exists, the one with higher priority will be used. The priorities are as follows:</p>\n<ol>\n<li><code>.js</code> - use this if you want to use dynamic config file that can be generated programmatically.</li>\n<li><code>.json</code> - use this if you want to use static config file that can be easily edited by humans.</li>\n<li><code>.yml/.yaml</code> - use this if you want to use static config file that can be easily edited by humans and supports comments.</li>\n</ol>\n<p>To have an environment-specific configuration, create a file named <code>bajo-{env}.{ext}</code> where <code>{env}</code> is the environment name (e.g. <code>dev</code>, <code>prod</code>)\nin the same folder.</p>\n</li>\n</ol>\n<blockquote>\n<p><strong>Note</strong>: all plugin's configuration files follow the same rules as above, but with the following differences:</p>\n<ul>\n<li>The configuration file should be named as <code>{pluginName}.{ext}</code> or <code>{pluginName}-{env}.{ext}</code> for environment-specific configuration, where <code>{pluginName}</code> is the name of the plugin.</li>\n<li>Command-line arguments should be prefixed with the plugin name followed by a colon. For example, <code>--{pluginName}:my-configKey</code> will set <code>my.configKey</code> to the value provided for the plugin's configuration.</li>\n<li>Environment variables should be prefixed with the plugin name followed by a dot. For example, <code>{PLUGINNAME}.MY__CONFIG_KEY</code> will set <code>my.configKey</code> to the value provided for the plugin's configuration.</li>\n</ul>\n<p>Plugin's configuration objects are mutable only during the boot process. After a plugin is started, they are frozen and cannot be modified.\nYour only options to do modifications is to use <code>{pluginName}:{before|after}{Init|Start}</code> hooks.</p>\n</blockquote>"},{"title":"Tools","link":"<a href=\"Tools.html\">Tools</a>"},{"title":"Tools#app","link":"<a href=\"Tools.html#app\">app</a>","description":"<p>Reference to the app instance</p>"},{"title":"Tools#bindThis","link":"<a href=\"Tools.html#bindThis\">bindThis</a>","description":"<p>Force bind methods to <code>this</code> context.</p>\n<p>Since JavaScript's <code>this</code> is dynamic, this method is useful to ensure\nthat the methods always refer to the correct instance of the class.</p>\n<p>Typically, you would call this method in the constructor of your plugin class,\npassing an array of method names or imported functions that you want to bind.</p>"},{"title":"Tools#dispose","link":"<a href=\"Tools.html#dispose\">dispose</a>","description":"<p>Dispose internal references.</p>"},{"title":"Tools#plugin","link":"<a href=\"Tools.html#plugin\">plugin</a>","description":"<p>Reference to the plugin instance that this Tools class is associated with</p>"},{"title":"boot","link":"<a href=\"global.html#boot\">boot</a>","description":"<p>Main entry point of a Bajo app. Returned value is the {@link App} instance itself.</p>\n<p>Inside your <code>index.js</code> file in the root folder, write something like this:</p>\n<pre class=\"prettyprint source lang-javascript\"><code>import { boot } from 'bajo'\nconst app = await boot()\n// At this point, your app should be ready to use\n// You can now use `app` to access all plugins and their features\n</code></pre>\n<p>Even though you can write your codes directly after boot as shown above, we strongly suggest writing\nyour code inside the {@link Main} plugin or even writing a custom {@link Plugin}.</p>\n<p>We recommend the second method for its portability.</p>"},{"title":"module:Applet","link":"<a href=\"module-Applet.html\">Applet</a>","description":"<h1 id=\"applet\">Applet</h1>\n<p>Bajo has a built-in applet system that allows you to run your app as an applet.\nAn applet is a small command-line app that can be embedded inside a plugin, purposefully designed\nto run a simple task mostly bound to the plugin itself. It is a convenient way to run a plugin's task\nwithout having to write a separate script.</p>\n<p>Since it is embedded inside a plugin, it behaves like running the whole app but doing only task\nthat you want to run.</p>\n<p>Applet needs {@link https://ardhi.github.io/bajo-cli/|bajo-cli} plugin to be installed and loaded.\nThis is because applet is a command-line app and <code>bajo-cli</code> plugin is specifically designed to provide\nthe necessary command-line interface and function helpers to run command-line based app.</p>\n<p>So please make sure that <code>bajo-cli</code> is in your app's <code>package.json</code> file and in the <code>plugins</code>\narray of your app's config before you run an applet. Otherwise, it will throw an error.</p>\n<p>You can run an applet by using the following command:</p>\n<ul>\n<li><code>node index.js -a</code> or <code>node index.js --applet</code> to list all available applets and choose one to run</li>\n<li><code>node index.js -a &lt;pluginNs&gt;</code> to list all <code>pluginNs</code> only applets and choose one to run</li>\n<li><code>node index.js -a &lt;pluginNs:appletName&gt;</code> to run the specific applet directly</li>\n</ul>\n<p>On all cases, you might require to provide additional arguments and/or options to the applet.</p>\n<p>By default, applet won't show you any log output. This is by design because it could clutter your\nterminal output. If you insist on seeing the log output, you have to add the <code>--log-applet</code> option.</p>\n<blockquote>\n<p><strong>Note</strong>: all standard bajo's command line arguments and options are also available to applet,\ne.g. <code>--env=prod</code>, <code>--lang=id</code>, <code>--log-level=trace</code>, etc.</p>\n</blockquote>\n<blockquote>\n<p><strong>Development</strong> : Please visit {@link https://ardhi.github.io/bajo-cli/module-Applet.html|applet development}\nfor more details on how to create an applet.</p>\n</blockquote>"},{"title":"module:Helper","link":"<a href=\"module-Helper.html\">Helper</a>","description":"<h1 id=\"helper\">Helper</h1>\n<p>Internal helpers called by Bajo and other classes. It should remains\nhidden and not to be imported by any program. It listed here for documentation purpose only.</p>"},{"title":"module:Helper.bootOrder","link":"<a href=\"module-Helper.html#.bootOrder\">bootOrder</a>","description":"<p>Determine the boot order of plugins based on their <code>bajo.bootorder</code> property in their <code>package.json</code> file.\nIf not provided, the plugin will be booted in the order they are listed in the <code>package.json</code> file or <code>.plugins</code> file.</p>"},{"title":"module:Helper.buildBaseConfig","link":"<a href=\"module-Helper.html#.buildBaseConfig\">buildBaseConfig</a>","description":"<p>Build base configuration object for Bajo. This function is called by Bajo during the {@link Bajo#init|initialization process}:</p>\n<ul>\n<li>it sets up the base directory,</li>\n<li>it checks the validity of the data directory,</li>\n<li>it ensures the temporary directory exists,</li>\n<li>it reads the list of used plugins from the <code>package.json</code>, <code>.plugins</code> file or command line options.</li>\n</ul>"},{"title":"module:Helper.buildConfig","link":"<a href=\"module-Helper.html#.buildConfig\">buildConfig</a>","description":"<p>Building Bajo configuration object. Called after all config handlers are collected,\nthis function will read config files written in any of config handlers' supported formats:</p>\n<ul>\n<li>if runtime configuration object is provided (the one passed to the app constructor), it will be\nused as the base. Otherwise, files are read from the <code>{dataDir}/config</code></li>\n<li>then it will be merged with the configuration coming from the command line arguments and environment variables</li>\n<li>doing some normalization and validation works, including setting the language, environment, log level, and cache purge settings</li>\n<li>and setting up the app's log instance with the proper log level</li>\n</ul>"},{"title":"module:Helper.buildPlugins","link":"<a href=\"module-Helper.html#.buildPlugins\">buildPlugins</a>","description":"<p>Load, build and sanitize all plugins defined in <code>package.json</code> or <code>.plugins</code> file, and add them to the app's plugin list.\nIt will also make sure the <code>main</code> plugin is there too, if not, it will be created with the default template and settings.</p>\n<p>Finally, it will loop through all loaded plugins and its config and language files.</p>\n<p>This function is called by Bajo during the {@link Bajo#init|initialization process}.</p>"},{"title":"module:Helper.checkDependencies","link":"<a href=\"module-Helper.html#.checkDependencies\">checkDependencies</a>","description":"<p>Ensure all plugins' dependencies are met. If there is a missing dependency, an error will be thrown.</p>\n<p>Semver is also supported, so if a plugin requires a specific version of another plugin, it will be checked as well.</p>"},{"title":"module:Helper.checkNameAliases","link":"<a href=\"module-Helper.html#.checkNameAliases\">checkNameAliases</a>","description":"<p>Ensure the uniqueness of all plugins' name and alias. If there is a clash, an error will be thrown.</p>"},{"title":"module:Helper.collectConfigHandlers","link":"<a href=\"module-Helper.html#.collectConfigHandlers\">collectConfigHandlers</a>","description":"<p>Collect all plugins' config handlers and push them to the app's {@link App#configHandlers|configHandlers} array.</p>"},{"title":"module:Helper.collectHooks","link":"<a href=\"module-Helper.html#.collectHooks\">collectHooks</a>","description":"<p>Collect all plugins' hooks and push them to the app's {@link App#hooks|hooks} array.</p>"},{"title":"module:Helper.exitHandler","link":"<a href=\"module-Helper.html#.exitHandler\">exitHandler</a>","description":"<p>Attach plugins exit handlers to make sure when the app shuts down, all plugins shut down gracefully first</p>"},{"title":"module:Helper.findDeep","link":"<a href=\"module-Helper.html#.findDeep\">findDeep</a>","description":"<p>Find item deep in paths.</p>"},{"title":"module:Helper.freeze","link":"<a href=\"module-Helper.html#.freeze\">freeze</a>","description":"<p>Freeze object.</p>"},{"title":"module:Helper.importModule","link":"<a href=\"module-Helper.html#.importModule\">importModule</a>","description":"<p>Import file/module from any loaded plugins.</p>\n<p>E.g. your plugin structure looks like this:\n<code>|- src | |- lib | | |- my-module.js |- index.js |- package.json</code></p>\n<p>And this is how to import <code>my-module.js</code>:\n<code>javascript const { importModule } = this.app.bajo const myModule = await importModule('myPlugin:/src/lib/my-module.js') </code></p>"},{"title":"module:Helper.outmatchNs","link":"<a href=\"module-Helper.html#.outmatchNs\">outmatchNs</a>","description":"<p>Outmacth with support for scoped source and pattern. Scoped source/pattern is a source/pattern that has a plugin's namespace prefix,\nseparated by <code>:</code> symbol.</p>\n<p>This function is usefull for matching a source/pattern that is scoped to a specific plugin's namespace.\nFor example, if you have a source <code>myPlugin:foo/bar</code> and a pattern <code>myPlugin:foo/*</code>,\nthis function will return <code>true</code> because the source matches the pattern within the same namespace.</p>"},{"title":"module:Helper.parseObject","link":"<a href=\"module-Helper.html#.parseObject\">parseObject</a>","description":"<p>Parse object and normalize their values.</p>\n<p>Support automatic value translation for keys with <code>t:</code> prefix. The keys are then\nconverted to the one without the <code>t:</code> prefix, and the original key is removed from the object.</p>\n<p>See {@link https://ardhi.github.io/aneka/global.html#parseObject|aneka.parseObject()} for more details.</p>"},{"title":"module:Helper.runAsApplet","link":"<a href=\"module-Helper.html#.runAsApplet\">runAsApplet</a>","description":"<p>If app is in <code>applet</code> mode, this little helper should take care plugin's applet boot process</p>"},{"title":"module:Helper.runPlugins","link":"<a href=\"module-Helper.html#.runPlugins\">runPlugins</a>","description":"<p>Run all loaded plugins' <code>init()</code> and <code>start()</code> methods in the order determined previously during boot process.</p>"},{"title":"module:Hook","link":"<a href=\"module-Hook.html\">Hook</a>","description":"<h1 id=\"hook\">Hook</h1>\n<p>Bajo has a hook system that allows you to run custom code before or after certain events in the framework.\nYou can use hooks to modify the behavior of the framework or to add new functionality.</p>\n<p>Your hook should be put in:</p>\n<ul>\n<li>your plugin's hook folder (also valid for app's <code>main</code> plugin), which is located in <code>{pluginRoot}/extend/bajo/hook</code>. In this case:\n<ul>\n<li>the file should be named as <code>{hookName}.js</code> for hook that listens for one name or <code>{hookName1}${hookName2}${hookName3}.js</code>\nfor hook that listens for many names. It should be exported as default export</li>\n<li>you can use the exact hook name or follow our convention to use kebab case for the file name, e.g. <code>bajo.override:after-read-config.js</code> for <code>bajo.override:afterReadConfig</code> hook</li>\n<li>content should be a single {@link module:Hook.THook} object. If <code>name</code> property is there, it will be used as\nthe hook name, otherwise it will be reconstructed from the file name. Hence the file name is important</li>\n<li>or simply a function that will be used as the hook handler. In this case, all missing properties will be set to their default values</li>\n</ul>\n</li>\n<li>or as array of hook object in <code>{pluginRoot}/extend/bajo/hook.js</code> file that follows the {@link module:Hook.THook} structure</li>\n</ul>\n<blockquote>\n<p><strong>Note</strong>: Hook handlers can have <code>.</code> dot symbol in their name, but in documentation, the dot symbol will be replaced with <code>·</code>\nsymbol because of JSDoc limitation. For example, a hook handler named <code>bajo.override:afterReadConfig</code> will be\ndocumented as <code>bajo·override:afterReadConfig</code>.</p>\n</blockquote>\n<blockquote>\n<p><strong>Warning</strong>: Even though hooks is a powerfull and convenient feature, it should be used with caution. Overusing hooks can lead to code\nthat is difficult to understand and maintain. Use hooks only when necessary and avoid using them for simple tasks\nthat can be accomplished with regular code.</p>\n</blockquote>"},{"title":"module:Hook.THook","link":"<a href=\"module-Hook.html#.THook\">THook</a>","description":"<p>Hook structure definition. Your hook listener should be an object that follows this structure.</p>"},{"title":"module:Hook.bajo.extend:afterReadConfig","link":"<a href=\"module-Hook.bajo.html#.extend:afterReadConfig\">extend:afterReadConfig</a>","description":"<p>Hook handler that runs after a extended configuration file is read.</p>"},{"title":"module:Hook.bajo.extend:beforeReadConfig","link":"<a href=\"module-Hook.bajo.html#.extend:beforeReadConfig\">extend:beforeReadConfig</a>","description":"<p>Hook handler that runs before a extended configuration file is read.</p>"},{"title":"module:Hook.bajo:afterAllInit","link":"<a href=\"module-Hook.html#.bajo:afterAllInit\">bajo:afterAllInit</a>","description":"<p>Hook handler that runs after all plugins are initialized. You can use this hook to do some post-initialization process.</p>"},{"title":"module:Hook.bajo:afterAllStart","link":"<a href=\"module-Hook.html#.bajo:afterAllStart\">bajo:afterAllStart</a>","description":"<p>Hook handler that runs after all plugins are started. You can use this hook to do some post-start process.</p>"},{"title":"module:Hook.bajo:afterBoot","link":"<a href=\"module-Hook.html#.bajo:afterBoot\">bajo:afterBoot</a>","description":"<p>Hook handler that runs after boot process. You can use this hook to do some post-boot process.</p>"},{"title":"module:Hook.bajo:afterCollectHooks","link":"<a href=\"module-Hook.html#.bajo:afterCollectHooks\">bajo:afterCollectHooks</a>","description":"<p>Hook handler that runs after hooks are collected. You can use this hook to modify the collected hooks before\nthey are recognized as application hooks.</p>"},{"title":"module:Hook.bajo:afterReadConfig","link":"<a href=\"module-Hook.html#.bajo:afterReadConfig\">bajo:afterReadConfig</a>","description":"<p>Hook handler that runs after all read processes of a configuration file are completed.</p>"},{"title":"module:Hook.bajo:beforeAllInit","link":"<a href=\"module-Hook.html#.bajo:beforeAllInit\">bajo:beforeAllInit</a>","description":"<p>Hook handler that runs before all plugins are initialized. You can use this hook to do some pre-initialization process.</p>"},{"title":"module:Hook.bajo:beforeAllStart","link":"<a href=\"module-Hook.html#.bajo:beforeAllStart\">bajo:beforeAllStart</a>","description":"<p>Hook handler that runs before all plugins are started. You can use this hook to do some pre-start process.</p>"},{"title":"module:Hook.bajo:beforeBoot","link":"<a href=\"module-Hook.html#.bajo:beforeBoot\">bajo:beforeBoot</a>","description":"<p>Hook handler that runs before boot process. You can use this hook to do some pre-boot process.</p>"},{"title":"module:Hook.bajo:beforeReadConfig","link":"<a href=\"module-Hook.html#.bajo:beforeReadConfig\">bajo:beforeReadConfig</a>","description":"<p>Hook handler that runs before a configuration file is read.</p>"},{"title":"module:Hook.bajo·default:afterReadConfig","link":"<a href=\"module-Hook.html#.bajo%25C2%25B7default:afterReadConfig\">bajo·default:afterReadConfig</a>","description":"<p>Hook handler that runs after a non override/extended configuration file is read.</p>"},{"title":"module:Hook.bajo·override:afterReadConfig","link":"<a href=\"module-Hook.html#.bajo%25C2%25B7override:afterReadConfig\">bajo·override:afterReadConfig</a>","description":"<p>Hook handler that runs after a configuration file override is read.</p>"},{"title":"module:Hook.bajo·override:beforeReadConfig","link":"<a href=\"module-Hook.html#.bajo%25C2%25B7override:beforeReadConfig\">bajo·override:beforeReadConfig</a>","description":"<p>Hook handler that runs before a configuration file override is read.</p>"},{"title":"module:Hook.hookHandler","link":"<a href=\"module-Hook.html#.hookHandler\">hookHandler</a>","description":"<p>This is the hook handler function that will be called when the hook is triggered.\nThis handler is scoped to the owning plugin, so you can use <code>this</code> to access the plugin instance and\nits properties.</p>"},{"title":"module:Hook.{ns}:afterAppletRun","link":"<a href=\"module-Hook.html#.%257Bns%257D:afterAppletRun\">{ns}:afterAppletRun</a>","description":"<p>Hook handler that runs after applet is run. <code>{ns}</code> is the applet's namespace</p>"},{"title":"module:Hook.{ns}:afterBuildCollection","link":"<a href=\"module-Hook.html#.%257Bns%257D:afterBuildCollection\">{ns}:afterBuildCollection</a>","description":"<p>Hook handler that runs after a collection is built. <code>{ns}</code> is the collection's namespace. This hook is useful\nto modify the collection items after they are built.</p>"},{"title":"module:Hook.{ns}:afterInit","link":"<a href=\"module-Hook.html#.%257Bns%257D:afterInit\">{ns}:afterInit</a>","description":"<p>Hook handler that runs after <code>{ns}</code> plugins are initialized. You can use this hook to do some post-initialization process.</p>"},{"title":"module:Hook.{ns}:afterStart","link":"<a href=\"module-Hook.html#.%257Bns%257D:afterStart\">{ns}:afterStart</a>","description":"<p>Hook handler that runs after <code>{ns}</code> plugins are started. You can use this hook to do some post-start process.</p>"},{"title":"module:Hook.{ns}:beforeAppletRun","link":"<a href=\"module-Hook.html#.%257Bns%257D:beforeAppletRun\">{ns}:beforeAppletRun</a>","description":"<p>Hook handler that runs before applet is run. <code>{ns}</code> is the applet's namespace</p>"},{"title":"module:Hook.{ns}:beforeBuildCollection","link":"<a href=\"module-Hook.html#.%257Bns%257D:beforeBuildCollection\">{ns}:beforeBuildCollection</a>","description":"<p>Hook handler that runs before a collection is built. <code>{ns}</code> is the collection's namespace. This hook is useful\nto modify the collection items before they are built.</p>"},{"title":"module:Hook.{ns}:beforeInit","link":"<a href=\"module-Hook.html#.%257Bns%257D:beforeInit\">{ns}:beforeInit</a>","description":"<p>Hook handler that runs before <code>{ns}</code> plugins are initialized. You can use this hook to do some pre-initialization process.</p>"},{"title":"module:Hook.{ns}:beforeStart","link":"<a href=\"module-Hook.html#.%257Bns%257D:beforeStart\">{ns}:beforeStart</a>","description":"<p>Hook handler that runs before <code>{ns}</code> plugins are started. You can use this hook to do some pre-start process.</p>"},{"title":"package·json","link":"<a href=\"global.html#package%25C2%25B7json\">package·json</a>","description":"<p>To be recognized as a valid Bajo app, your package must be an <code>ES6 module</code> and have a <code>package.json</code> file\nwith the additional <code>bajo</code> property and at least the <code>type</code> property set to <code>app</code>.</p>\n<p>You can also add the <code>plugins</code> property to specify which plugins to load. But this will be overridden\nby the <code>{dataDir}/config/.plugins</code> file if it exists.</p>\n<p>Example:</p>\n<pre class=\"prettyprint source lang-json\"><code>{\n &quot;name&quot;: &quot;my-app&quot;,\n &quot;version&quot;: &quot;1.0.0&quot;,\n &quot;description&quot;: &quot;My Bajo app&quot;,\n &quot;type&quot;: &quot;module&quot;,\n &quot;main&quot;: &quot;index.js&quot;,\n &quot;bajo&quot;: {\n &quot;type&quot;: &quot;app&quot;,\n &quot;plugins&quot;: [&quot;bajo-cli&quot;, &quot;bajo-config&quot;]\n },\n &quot;dependencies&quot;: {\n &quot;bajo&quot;: &quot;^2.23.0&quot;,\n &quot;bajo-cli&quot;: &quot;^2.4.0&quot;,\n &quot;bajo-config&quot;: &quot;^2.4.0&quot;\n }\n}\n...\n</code></pre>\n<blockquote>\n<p><strong>Note</strong>: The dot symbol in <code>package.json</code> has been replaced with <code>·</code> symbol because of JSDoc theme limitation</p>\n</blockquote>"}]}