bajo 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/.github/workflows/repo-lockdown.yml +24 -0
  3. package/.jsdoc.conf.json +7 -6
  4. package/LICENSE +1 -1
  5. package/README.md +50 -18
  6. package/class/app.js +376 -54
  7. package/class/bajo.js +228 -149
  8. package/class/base.js +106 -0
  9. package/class/helper/bajo.js +135 -84
  10. package/class/helper/{plugin.js → base.js} +96 -22
  11. package/class/{base → misc}/err.js +44 -14
  12. package/class/misc/log.js +212 -0
  13. package/class/misc/print.js +264 -0
  14. package/class/plugin.js +120 -68
  15. package/docs/App.html +23 -1
  16. package/docs/Bajo.html +2 -9
  17. package/docs/Base.html +3 -0
  18. package/docs/Err.html +3 -1
  19. package/docs/Log.html +5 -1
  20. package/docs/Plugin.html +1 -1
  21. package/docs/Print.html +1 -1
  22. package/docs/class_app.js.html +378 -56
  23. package/docs/class_bajo.js.html +230 -151
  24. package/docs/class_base.js.html +109 -0
  25. package/docs/class_helper_bajo.js.html +138 -87
  26. package/docs/class_helper_base.js.html +246 -0
  27. package/docs/class_misc_err.js.html +129 -0
  28. package/docs/class_misc_log.js.html +210 -0
  29. package/docs/class_misc_print.js.html +267 -0
  30. package/docs/class_plugin.js.html +122 -70
  31. package/docs/data/search.json +1 -1
  32. package/docs/global.html +4 -1
  33. package/docs/index.html +2 -2
  34. package/docs/index.js.html +35 -0
  35. package/docs/lib_current-loc.js.html +36 -0
  36. package/docs/lib_formats.js.html +8 -8
  37. package/docs/lib_import-module.js.html +59 -0
  38. package/docs/lib_log-levels.js.html +17 -7
  39. package/docs/lib_parse-args-argv.js.html +83 -0
  40. package/docs/lib_parse-env.js.html +53 -0
  41. package/docs/lib_resolve-path.js.html +3 -6
  42. package/docs/lib_shim.js.html +8 -3
  43. package/docs/module-Helper_Bajo.html +3 -0
  44. package/docs/module-Helper_Base.html +3 -0
  45. package/docs/module-Lib.html +15 -0
  46. package/docs/static/home.md +32 -0
  47. package/docs/static/logo-ecosystem.png +0 -0
  48. package/docs/static/logo.png +0 -0
  49. package/extend/bajo/intl/en-US.json +8 -2
  50. package/extend/bajo/intl/id.json +8 -2
  51. package/index.js +22 -2
  52. package/lib/current-loc.js +24 -2
  53. package/lib/formats.js +6 -6
  54. package/lib/import-module.js +29 -0
  55. package/lib/log-levels.js +15 -5
  56. package/lib/parse-args-argv.js +20 -12
  57. package/lib/parse-env.js +18 -7
  58. package/lib/resolve-path.js +1 -4
  59. package/lib/shim.js +6 -1
  60. package/package.json +4 -7
  61. package/wiki/CONFIG.md +30 -0
  62. package/wiki/CONTRIBUTING.md +5 -0
  63. package/wiki/DEV_GUIDE.md +3 -0
  64. package/wiki/ECOSYSTEM.md +93 -0
  65. package/wiki/GETTING-STARTED.md +356 -0
  66. package/wiki/USER-GUIDE.md +256 -0
  67. package/class/base/log.js +0 -205
  68. package/class/base/plugin.js +0 -168
  69. package/class/base/print.js +0 -272
  70. package/docs/BasePlugin.html +0 -5
  71. package/docs/class_base_err.js.html +0 -99
  72. package/docs/class_base_log.js.html +0 -208
  73. package/docs/class_base_plugin.js.html +0 -180
  74. package/docs/class_base_print.js.html +0 -275
  75. package/docs/class_helper_plugin.js.html +0 -172
  76. package/docs/lib_create-method.js.html +0 -42
  77. package/docs/module-class_helper_bajo.html +0 -3
  78. package/docs/module-class_helper_plugin.html +0 -3
  79. package/docs/module-lib_create-method.html +0 -3
  80. package/docs/module-lib_formats.html +0 -3
  81. package/docs/module-lib_log-levels.html +0 -3
  82. package/docs/module-lib_resolve-path.html +0 -3
  83. package/docs/module-lib_shim.html +0 -3
  84. package/docs/tutorial-contribution.html +0 -3
  85. package/docs/tutorial-ecosystem.html +0 -3
  86. package/docs/tutorial-getting-started.html +0 -13
  87. package/docs/tutorial-plugin-dev.html +0 -3
  88. package/docs/tutorial-user-guide.html +0 -3
  89. package/lib/create-method.js +0 -39
  90. package/lib/dayjs.js +0 -8
  91. package/lib/omitted-plugin-keys.js +0 -3
  92. package/lib/read-all-configs.js +0 -19
  93. package/misc-docs/.hook.md +0 -11
  94. package/misc-docs/bitcoin.jpeg +0 -0
  95. package/misc-docs/contribution.md +0 -20
  96. package/misc-docs/ecosystem.md +0 -94
  97. package/misc-docs/getting-started.md +0 -142
  98. package/misc-docs/plugin-dev.md +0 -0
  99. package/misc-docs/toc.json +0 -17
  100. package/misc-docs/user-guide.md +0 -1
  101. /package/docs/{bitcoin.jpeg → static/bitcoin.jpeg} +0 -0
@@ -1,7 +1,6 @@
1
1
  <!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: class/bajo.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 Framework</a><div class="sidebar-items-container"><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-class_helper_bajo.html">class/helper/bajo</a></div><div class="sidebar-section-children"><a href="module-class_helper_plugin.html">class/helper/plugin</a></div><div class="sidebar-section-children"><a href="module-lib_create-method.html">lib/create-method</a></div><div class="sidebar-section-children"><a href="module-lib_formats.html">lib/formats</a></div><div class="sidebar-section-children"><a href="module-lib_log-levels.html">lib/log-levels</a></div><div class="sidebar-section-children"><a href="module-lib_resolve-path.html">lib/resolve-path</a></div><div class="sidebar-section-children"><a href="module-lib_shim.html">lib/shim</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="BasePlugin.html">BasePlugin</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><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-contribution.html">Contribution</a></div><div class="sidebar-section-children"><a href="tutorial-ecosystem.html">Ecosystem</a></div><div class="sidebar-section-children"><a href="tutorial-getting-started.html">Getting Started</a></div><div class="sidebar-section-children"><a href="tutorial-plugin-dev.html">Plugin Development</a></div><div class="sidebar-section-children"><a href="tutorial-user-guide.html">User Guide</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#NsPathType">NsPathType</a></div><div class="sidebar-section-children"><a href="global.html#ObjectFormatType">ObjectFormatType</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://bajo.app" target="">Bajo.app</a></div><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><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_bajo.js</h1></header><article><pre class="prettyprint source lang-js"><code>import Plugin from './plugin.js'
4
- import BasePlugin from './base/plugin.js'
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="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><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</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#event:bajo:afterAll%257Bmethod%257D">bajo:afterAll{method}</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:afterBootComplete">bajo:afterBootComplete</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:afterBuildCollection">bajo:afterBuildCollection</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:afterCollectHooks">bajo:afterCollectHooks</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:beforeAll%257Bmethod%257D">bajo:beforeAll{method}</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:beforeBuildCollection">bajo:beforeBuildCollection</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:afterAppletRun">{ns}:afterAppletRun</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:after%257Bmethod%257D">{ns}:after{method}</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:beforeAppletRun">{ns}:beforeAppletRun</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:before%257Bmethod%257D">{ns}:before{method}</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_Bajo.html">Helper/Bajo</a></div><div class="sidebar-section-children"><a href="module-Helper_Base.html">Helper/Base</a></div><div class="sidebar-section-children"><a href="module-Lib.html">Lib</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#TAppConfigHandler">TAppConfigHandler</a></div><div class="sidebar-section-children"><a href="global.html#TAppEnv">TAppEnv</a></div><div class="sidebar-section-children"><a href="global.html#TAppLib">TAppLib</a></div><div class="sidebar-section-children"><a href="global.html#TBajoDataType">TBajoDataType</a></div><div class="sidebar-section-children"><a href="global.html#TBajoFormatResult">TBajoFormatResult</a></div><div class="sidebar-section-children"><a href="global.html#TBajoFormatType">TBajoFormatType</a></div><div class="sidebar-section-children"><a href="global.html#TLogJson">TLogJson</a></div><div class="sidebar-section-children"><a href="global.html#TLogLevels">TLogLevels</a></div><div class="sidebar-section-children"><a href="global.html#TNsPathPairs">TNsPathPairs</a></div><div class="sidebar-section-children"><a href="global.html#TNsPathResult">TNsPathResult</a></div><div class="sidebar-section-children"><a href="global.html#TPrintOptions">TPrintOptions</a></div><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_bajo.js</h1></header><article><pre class="prettyprint source lang-js"><code>import Plugin from './plugin.js'
5
4
  import increment from 'add-filename-increment'
6
5
  import fs from 'fs-extra'
7
6
  import path from 'path'
@@ -21,6 +20,15 @@ import resolvePath from '../lib/resolve-path.js'
21
20
  import importModule from '../lib/import-module.js'
22
21
  import logLevels from '../lib/log-levels.js'
23
22
  import { types as formatTypes, formats } from '../lib/formats.js'
23
+ import {
24
+ buildBaseConfig,
25
+ buildExtConfig,
26
+ buildPlugins,
27
+ collectConfigHandlers,
28
+ bootOrder,
29
+ bootPlugins,
30
+ exitHandler
31
+ } from './helper/bajo.js'
24
32
 
25
33
  const require = createRequire(import.meta.url)
26
34
 
@@ -33,67 +41,30 @@ const {
33
41
 
34
42
  /**
35
43
  * The Core. The main engine. The one and only plugin that control app's boot process and
36
- * making sure all other plugins working smoothly.
44
+ * making sure all other plugins working nicely.
37
45
  *
38
46
  * @class
39
47
  */
40
- class Bajo extends BasePlugin {
48
+ class Bajo extends Plugin {
49
+ static alias = 'bajo'
41
50
  /**
42
- * @param {Object} app
43
- * @param {Object} app - App instance reference. Usefull to call app method inside a plugin
51
+ * @param {App} app - App instance. Usefull to call app method inside a plugin
44
52
  */
45
53
  constructor (app) {
46
54
  super('bajo', app)
55
+ this.whiteSpace = [' ', '\t', '\n', '\r']
47
56
  /**
48
- * Date/time when your app start
49
- * @type {Date}
50
- */
51
- this.runAt = new Date()
52
-
53
- /**
54
- * Your main namespace. And yes, you suppose NOT to change this
55
- *
56
- * @type {string}
57
- */
58
- this.mainNs = 'main'
59
-
60
- /**
61
- * Storage for applets
62
- *
63
- * @type {Array}
64
- */
65
- this.applets = []
66
-
67
- /**
68
- * List of all loaded plugin's package names
69
- *
70
- * @type {Array}
71
- */
72
- this.pluginPkgs = []
73
-
74
- /**
75
- * List of all loaded plugin's names
57
+ * Config object
76
58
  *
77
- * @type {Array}
59
+ * @type {Object}
60
+ * @see {@tutorial config}
78
61
  */
79
- this.pluginNames = []
62
+ this.config = {}
80
63
 
81
- /**
82
- * Storage for config handlers. By default there are only two handlers available: ```.js```
83
- * and ```.json```.
84
- *
85
- * Use plugin to add more type - e.g: {@link https://github.com/ardhi/bajo-config|bajo-config}
86
- * lets you to use ```.yaml``` and ```.toml```
87
- *
88
- * @type {Array}
89
- */
90
- this.configHandlers = [
64
+ app.configHandlers = [
91
65
  { ext: '.js', readHandler: this._defConfigHandler },
92
- { ext: '.json', readHandler: this.readJson }
66
+ { ext: '.json', readHandler: this.fromJson, writeHandler: this.toJson }
93
67
  ]
94
- this.whiteSpace = [' ', '\t', '\n', '\r']
95
- this.envs = { dev: 'development', staging: 'staging', prod: 'production' }
96
- this.lib.Plugin = Plugin
97
68
  }
98
69
 
99
70
  async _defConfigHandler (file, opts = {}) {
@@ -102,6 +73,30 @@ class Bajo extends BasePlugin {
102
73
  return mod
103
74
  }
104
75
 
76
+ /**
77
+ * Initialization:
78
+ *
79
+ * 1. Building {@link module:Helper/Bajo.buildBaseConfig|base config}
80
+ * 2. {@link module:Helper/Bajo.buildPlugins|Building plugins}
81
+ * 3. Collect all {@link module:Helper/Bajo.collectConfigHandlers|config handler}
82
+ * 4. Building {@link module:Helper/Bajo.buildExtConfig|extra config}
83
+ * 5. Setup {@link module:Helper/Bajo.bootOrder|boot order}
84
+ * 6. {@link module:Helper/Bajo.bootPlugins|Boot loaded plugins}
85
+ * 7. Attach {@link module:Helper/Bajo.exitHandler|exit handlers}
86
+ *
87
+ * @method
88
+ * @async
89
+ */
90
+ init = async () => {
91
+ await buildBaseConfig.call(this)
92
+ await collectConfigHandlers.call(this)
93
+ await buildExtConfig.call(this)
94
+ await buildPlugins.call(this)
95
+ await bootOrder.call(this)
96
+ await bootPlugins.call(this)
97
+ await exitHandler.call(this)
98
+ }
99
+
105
100
  /**
106
101
  * Resolve file name to filesystem's path. Windows path separator ```\```
107
102
  * is normalized to Unix's ```/```
@@ -119,10 +114,10 @@ class Bajo extends BasePlugin {
119
114
  * Freeze object
120
115
  *
121
116
  * @method
122
- * @param {Object} obj - Object
123
- * @param {boolean} [shallow=false] - If true (default), deep freeze object
117
+ * @param {Object} obj - Object to freeze
118
+ * @param {boolean} [shallow=false] - If ```false``` (default), deep freeze object
124
119
  */
125
- freeze = (obj, shallow) => {
120
+ freeze = (obj, shallow = false) => {
126
121
  if (shallow) Object.freeze(obj)
127
122
  else deepFreeze(obj)
128
123
  }
@@ -153,6 +148,25 @@ class Bajo extends BasePlugin {
153
148
  return { ns, subNs, path: _path, fullNs: names.join('.'), type }
154
149
  }
155
150
 
151
+ /**
152
+ * Name based ```{ns}:{path}``` format
153
+ * @typedef {string} TNsPathPairs
154
+ * @see TNsPathResult
155
+ * @see Bajo#buildNsPath
156
+ * @see Bajo#breakNsPath
157
+ */
158
+
159
+ /**
160
+ * Build ns/path pairs
161
+ *
162
+ * @method
163
+ * @param {object} [options={}] - Options object
164
+ * @param {string} [options.ns=''] - Namespace
165
+ * @param {string} [options.subNs] - Sub namespace
166
+ * @param {string} [options.subSubNs] - Sub sub namespace
167
+ * @param {string} [options.path] - Path
168
+ * @returns {TNsPathPairs} - Ns/path pairs
169
+ */
156
170
  buildNsPath = ({ ns = '', subNs, subSubNs, path } = {}) => {
157
171
  if (subNs) ns += '.' + subNs
158
172
  if (subSubNs) ns += '.' + subSubNs
@@ -160,23 +174,26 @@ class Bajo extends BasePlugin {
160
174
  }
161
175
 
162
176
  /**
163
- * Object returned by {@link BajoCore#breakNsPath|breakNsPath}
177
+ * Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath}
164
178
  *
165
- * @typedef {Object} NsPathType
179
+ * @typedef {Object} TNsPathResult
166
180
  * @property {string} ns - Namespace
167
181
  * @property {string} [subNs] - Sub namespace
168
182
  * @property {string} [subSubNs] - Sub of sub namespace
169
183
  * @property {string} path - Path without query string or hash
170
184
  * @property {string} fullPath - Full path, including query string and hash
185
+ * @see TNsPathPairs
186
+ * @see Bajo#buildNsPath
187
+ * @see Bajo#breakNsPath
171
188
  */
172
189
 
173
190
  /**
174
191
  * Break name to its namespace &amp; path infos
175
192
  *
176
193
  * @method
177
- * @param {string} name - Name to break
178
- * @param {boolean} [checkNs=true] - If true (default), namespace will be checked for its validity
179
- * @returns {NsPathType}
194
+ * @param {(TNsPathPairs|string)} name - Name to break
195
+ * @param {boolean} [checkNs=true] - If ```true``` (default), namespace will be checked for its validity
196
+ * @returns {TNsPathResult}
180
197
  */
181
198
  breakNsPath = (name = '', checkNs = true) => {
182
199
  let [ns, ...path] = name.split(':')
@@ -192,7 +209,7 @@ class Bajo extends BasePlugin {
192
209
  if (checkNs) {
193
210
  if (!this.app[ns]) {
194
211
  const plugin = this.getPlugin(ns)
195
- if (plugin) ns = plugin.name
212
+ if (plugin) ns = plugin.ns
196
213
  }
197
214
  if (!this.app[ns]) throw this.error('unknownPluginOrNotLoaded%s')
198
215
  }
@@ -224,31 +241,39 @@ class Bajo extends BasePlugin {
224
241
  }
225
242
 
226
243
  /**
227
- * Method to transform an array or object from config into an array of collection safely.
228
- *
229
- * Emitted hooks:
230
- * 1. ```{ns}:beforeBuildCollection (container)``` - called before collection is built
231
- * 2. ```{ns}:afterBuildCollection (container, items)``` - called after collection is built
244
+ * Method to transform config's array or object into an array of collection.
232
245
  *
233
246
  * @method
234
247
  * @async
235
248
  * @param {Object} options - Options
236
249
  * @param {string} [options.ns] - Namespace. If not provided, defaults to ```bajo```
237
250
  * @param {function} [options.handler] - Handler to call while building the collection item
238
- * @param {Array} [options.dupChecks=[]] - Array of keys to check for duplicates
251
+ * @param {string[]} [options.dupChecks=[]] - Array of keys to check for duplicates
239
252
  * @param {string} options.container - Key used as container name
240
253
  * @param {boolean} [options.useDefaultName=true] - If true (default) and ```name``` key is not provided, returned collection will be named ```default```
241
- * @returns {Array} The collection
254
+ * @fires bajo:beforeBuildCollection
255
+ * @fires bajo:afterBuildCollection
256
+ * @returns {Object[]} The collection
242
257
  */
243
258
  buildCollections = async (options = {}) => {
244
259
  let { ns, handler, dupChecks = [], container, useDefaultName } = options
245
260
  useDefaultName = useDefaultName ?? true
246
- if (!ns) ns = this.name
261
+ if (!ns) ns = this.ns
247
262
  const cfg = this.app[ns].getConfig()
248
263
  let items = get(cfg, container, [])
249
264
  if (!isArray(items)) items = [items]
250
- this.app[ns].log.trace('collecting%s', this.app[ns].print.write(container))
251
- await this.runHook(`${ns}:${camelCase('beforeBuildCollection')}`, container)
265
+ this.app[ns].log.trace('collecting%s', this.t(container))
266
+
267
+ /**
268
+ * Run before collection is built
269
+ *
270
+ * @global
271
+ * @event bajo:beforeBuildCollection
272
+ * @param {string} container
273
+ * @see {@tutorial hook}
274
+ * @see Bajo#buildCollections
275
+ */
276
+ await this.runHook(`${ns}:beforeBuildCollection`, container)
252
277
  const deleted = []
253
278
  for (const index in items) {
254
279
  const item = items[index]
@@ -262,7 +287,7 @@ class Bajo extends BasePlugin {
262
287
  const result = await handler.call(this.app[ns], { item, index, cfg })
263
288
  if (result) items[index] = result
264
289
  else if (result === false) deleted.push(index)
265
- if (this.app.bajo.applet &amp;&amp; item.skipOnTool &amp;&amp; !deleted.includes(index)) deleted.push(index)
290
+ if (this.app.applet &amp;&amp; item.skipOnApplet &amp;&amp; !deleted.includes(index)) deleted.push(index)
266
291
  }
267
292
  if (deleted.length > 0) pullAt(items, deleted)
268
293
 
@@ -274,13 +299,25 @@ class Bajo extends BasePlugin {
274
299
  if (checkers.includes(checker)) this.app[ns].fatal('oneOrMoreSharedTheSame%s%s', container, this.join(dupChecks.filter(i => !isFunction(i))))
275
300
  }
276
301
  }
277
- await this.runHook(`${ns}:${camelCase('afterBuildCollection')}`, container, items)
278
- this.app[ns].log.debug('collected%s%d', this.app[ns].print.write(container), items.length)
302
+
303
+ /**
304
+ * Run after collection is built
305
+ *
306
+ * @global
307
+ * @event bajo:afterBuildCollection
308
+ * @param {string} container
309
+ * @param {Object[]} items
310
+ * @see {@tutorial hook}
311
+ * @see Bajo#buildCollections
312
+ */
313
+ await this.runHook(`${ns}:afterBuildCollection`, container, items)
314
+ this.app[ns].log.debug('collected%s%d', this.t(container), items.length)
279
315
  return items
280
316
  }
281
317
 
282
318
  /**
283
- * Calling any plugin's method by its name. Name format: ```ns:methodName```.
319
+ * Calling any plugin's method by its name:
320
+ *
284
321
  * - If name is a string, the corresponding plugin's method will be called with passed args as its parameters
285
322
  * - 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
286
323
  * - If name is a function, this function will be run under scope with the remaining args
@@ -288,7 +325,7 @@ class Bajo extends BasePlugin {
288
325
  *
289
326
  * @method
290
327
  * @async
291
- * @param {(string|Object|function)} name - Method's name, function handler, plain object or plugin instance
328
+ * @param {(TNsPathPairs|Object|function)} name - Method's name, function handler, plain object or plugin instance
292
329
  * @param {...any} [args] - One or more arguments passed as parameter to the handler
293
330
  * @returns {any} Returned value
294
331
  */
@@ -301,10 +338,10 @@ class Bajo extends BasePlugin {
301
338
  }
302
339
  const bajo = scope.app.bajo
303
340
  if (isString(item)) {
304
- if (item.startsWith('applet:') &amp;&amp; bajo.applets.length > 0) {
341
+ if (item.startsWith('applet:') &amp;&amp; bajo.app.applets.length > 0) {
305
342
  const [, ns, path] = item.split(':')
306
- const applet = find(bajo.applets, a => (a.ns === ns || a.alias === ns))
307
- if (applet) result = await bajo.runApplet(applet, path, ...args)
343
+ const applet = find(bajo.app.applets, a => (a.ns === ns || a.alias === ns))
344
+ if (applet &amp;&amp; scope.app.bajoCli) result = await scope.app.bajoCli.runApplet(applet, path, ...args)
308
345
  } else {
309
346
  const [ns, method, ...params] = item.split(':')
310
347
  const fn = bajo.getMethod(`${ns}:${method}`)
@@ -332,7 +369,7 @@ class Bajo extends BasePlugin {
332
369
  * @async
333
370
  * @param {function} handler - Function handler. Can be an async function. Scoped to the running plugin
334
371
  * @param {(string|Object)} [options={}] - Options. If a string is provided, it serves as the glob pattern, otherwise:
335
- * @param {(string|Array)} [options.glob] - Glob pattern. If provided,
372
+ * @param {(string|string[])} [options.glob] - Glob pattern. If provided,
336
373
  * @param {boolean} [options.useBajo=false] - If true, add ```bajo``` to the running plugins too
337
374
  * @param {string} [options.prefix=''] - Prepend glob pattern with prefix
338
375
  * @param {boolean} [options.noUnderscore=true] - If true (default), matched file with name starts with underscore is ignored
@@ -342,7 +379,7 @@ class Bajo extends BasePlugin {
342
379
  eachPlugins = async (handler, options = {}) => {
343
380
  if (typeof options === 'string') options = { glob: options }
344
381
  const result = {}
345
- const pluginPkgs = cloneDeep(this.app.bajo.pluginPkgs) ?? []
382
+ const pluginPkgs = cloneDeep(this.app.pluginPkgs) ?? []
346
383
  const { glob, useBajo, prefix = '', noUnderscore = true, returnItems } = options
347
384
  if (useBajo) pluginPkgs.unshift('bajo')
348
385
  for (const pkgName of pluginPkgs) {
@@ -388,11 +425,12 @@ class Bajo extends BasePlugin {
388
425
  }
389
426
 
390
427
  /**
391
- * Object returned by {@link BajoCore#getUnitFormat|getUnitFormat}
428
+ * Object returned by {@link Bajo#getUnitFormat|bajo:getUnitFormat}
392
429
  *
393
- * @typedef {Object} ObjectFormatType
430
+ * @typedef {Object} TBajoFormatResult
394
431
  * @property {string} unitSys - Unit system
395
432
  * @property {Object} format - Format object
433
+ * @see Bajo#getUnitFormat
396
434
  */
397
435
 
398
436
  /**
@@ -402,7 +440,7 @@ class Bajo extends BasePlugin {
402
440
  * @param {Object} [options={}] - Options
403
441
  * @param {string} [options.lang] - Language to use. Defaults to the one you set in config
404
442
  * @param {string} [options.unitSys] - Unit system to use. Defaults to language's unit system or ```metric``` if unspecified
405
- * @returns {ObjectFormatType} - Returned value
443
+ * @returns {TBajoFormatResult} - Returned value
406
444
  */
407
445
  getUnitFormat = (options = {}) => {
408
446
  const lang = options.lang ?? this.config.lang
@@ -415,16 +453,16 @@ class Bajo extends BasePlugin {
415
453
  * Format value by type
416
454
  *
417
455
  * @method
418
- * @param {string} type - Format type. See {@link FormatType} for acceptable values
456
+ * @param {string} type - Format type. See {@link TBajoFormatType} for acceptable values
419
457
  * @param {any} value - Value to format
420
- * @param {string} [dataType] - Value's data type. See {@link DataType} for acceptable values
458
+ * @param {string} [dataType] - Value's data type. See {@link TBajoDataType} for acceptable values
421
459
  * @param {Object} [options={}] - Options
422
460
  * @param {boolean} [options.withUnit=true] - Return with its unit appended
423
461
  * @param {string} [options.lang] - Format value according to this language. Defaults to the one you set in config
424
462
  * @returns {(Array|string)} Return string if ```withUnit``` is true. Otherwise is an array of ```[value, unit, separator]```
425
463
  */
426
464
  formatByType = (type, value, dataType, options = {}) => {
427
- const { defaultsDeep } = this.lib.aneka
465
+ const { defaultsDeep } = this.app.lib.aneka
428
466
  const { format } = this.getUnitFormat(options)
429
467
  const { withUnit = true } = options
430
468
  const lang = options.lang ?? this.config.lang
@@ -442,7 +480,7 @@ class Bajo extends BasePlugin {
442
480
  *
443
481
  * @method
444
482
  * @param {any} value - Value to format
445
- * @param {string} [type] - Data type to use. See {@link DataType} for acceptable values. If not provided, return the untouched value
483
+ * @param {string} [type] - Data type to use. See {@link TBajoDataType} for acceptable values. If not provided, return the untouched value
446
484
  * @param {Object} [options={}] - Options
447
485
  * @param {string} [options.emptyValue=''] - Empty value to use if function resulted empty. Defaults to the one from your config
448
486
  * @param {boolean} [options.withUnit=true] - Return with its unit appended
@@ -452,7 +490,7 @@ class Bajo extends BasePlugin {
452
490
  * @returns {string} Formatted value
453
491
  */
454
492
  format = (value, type, options = {}) => {
455
- const { defaultsDeep } = this.lib.aneka
493
+ const { defaultsDeep } = this.app.lib.aneka
456
494
  const { format } = this.config.intl
457
495
  const { emptyValue = format.emptyValue } = options
458
496
  const lang = options.lang ?? this.config.lang
@@ -463,7 +501,7 @@ class Bajo extends BasePlugin {
463
501
  if (value instanceof Date) type = 'datetime'
464
502
  }
465
503
  if (['float', 'double'].includes(type) &amp;&amp; this.app.bajoSpatial) {
466
- const { latToDms, lngToDms } = this.app.bajoSpatial.lib.anekaSpatial
504
+ const { latToDms, lngToDms } = this.app.lib.anekaSpatial
467
505
  if (options.latitude) return latToDms(value)
468
506
  if (options.longitude) return lngToDms(value)
469
507
  }
@@ -596,7 +634,7 @@ class Bajo extends BasePlugin {
596
634
  *
597
635
  * @method
598
636
  * @param {string} pkgName - Package name to find
599
- * @param {*} base - Provide base name if ```pkgName``` is a module under ```base```'s package name
637
+ * @param {string} base - Provide base name if ```pkgName``` is a module under ```base```'s package name
600
638
  * @returns {string} Return absolute package directory
601
639
  */
602
640
  getModuleDir = (pkgName, base) => {
@@ -624,7 +662,7 @@ class Bajo extends BasePlugin {
624
662
  */
625
663
  getPluginDataDir = (name, ensureDir = true) => {
626
664
  const plugin = this.getPlugin(name)
627
- const dir = `${this.app.bajo.dir.data}/plugins/${plugin.name}`
665
+ const dir = `${this.app.bajo.dir.data}/plugins/${plugin.ns}`
628
666
  if (ensureDir) fs.ensureDirSync(dir)
629
667
  return dir
630
668
  }
@@ -633,7 +671,7 @@ class Bajo extends BasePlugin {
633
671
  * Resolve file path from:
634
672
  *
635
673
  * - local/absolute file
636
- * - ns based path (```myPlugin:/path/to/file.txt```)
674
+ * - TNsPath (```myPlugin:/path/to/file.txt```)
637
675
  *
638
676
  * @method
639
677
  * @param {string} file - File path, see above for supported types
@@ -675,46 +713,38 @@ class Bajo extends BasePlugin {
675
713
  if (silent) return false
676
714
  throw this.error('pluginWithNameAliasNotLoaded%s', name)
677
715
  }
678
- name = plugin.name
716
+ name = plugin.ns
679
717
  }
680
718
  return this.app[name]
681
719
  }
682
720
 
683
721
  /**
684
- * Import file/module from any loaded plugins
722
+ * Import file/module from any loaded plugins.
685
723
  *
686
- * Your plugin structure:
687
- * ```
688
- * |- src
689
- * | |- lib
690
- * | | |- my-module.js
691
- * |- index.js
692
- * |- package.json
693
- * ```
724
+ * Method proxy from {@link module:Lib.importModule}
694
725
  *
695
- * Inside your app/plugin:
696
- * ```javascript
697
- * const { importModule } = this.app.bajo
698
- * const myModule = await importModule('myPlugin:/src/lib/my-module.js')
699
- * ```
700
726
  * @method
701
727
  * @async
702
- * @param {string} file - File in format ```ns:&lt;ns based file path>```
703
- * @param {Object} [options={}] - Options
704
- * @param {boolean} [options.asDefaultImport=true] - If ```true``` (default), return default imported module
705
- * @param {boolean} [options.asHandler] - If ```true```, return as a {@link HandlerType|handler}
706
- * @param {boolean} [options.noCache] - If ```true```, always import as a fresh copy
707
- * @returns {(function|Object)}
728
+ * @see module:Lib.importModule
708
729
  */
709
730
  importModule = async (file, { asDefaultImport, asHandler, noCache } = {}) => {
710
731
  return await importModule.call(this, file, { asDefaultImport, asHandler, noCache })
711
732
  }
712
733
 
713
734
  /**
714
- * Import one or more package belongs to a plugin
735
+ * Import one or more packages belongs to a plugin.
736
+ *
737
+ * If the last arguments passed is an object, this object serves as options object:
738
+ * - ```returnDefault```: should return package's default export. Defaults to ```true```
739
+ * - ```throwNotFound```: should throw if package is not found. Defaults to ```false```
740
+ * - ```noCache```: always use fresh import. Defaults to ```false```
741
+ * - ```asObject```: see below. Defaults to ```false```
715
742
  *
716
- * Example: you want to import packages ```delay``` and ```chalk``` from ```bajo``` namespace and use it inside your app/plugin
743
+ * Return value:
744
+ * - if ```options.asObject``` is ```true``` (default ```false```), return as object with package's names as it's keys
745
+ * - Otherwise depends on how many parameters are provided, it should return the named package or an array of packages
717
746
  *
747
+ * Example: you want to import ```delay``` and ```chalk``` from ```bajo``` plugin because you want to use it in your code
718
748
  * ```javascript
719
749
  * const { importPkg } from this.app.bajo
720
750
  * const [delay, chalk] = await importPkg('bajo:delay', 'bajo:chalk')
@@ -725,14 +755,14 @@ class Bajo extends BasePlugin {
725
755
  *
726
756
  * @method
727
757
  * @async
728
- * @param {...any} pkgs - One or more packages in format ```ns:packageName```
729
- * @returns {(Object|Array)} Depends on how many parameters are provided, it should return the named package or an array of packages
758
+ * @param {...TNsPathPairs} pkgs - One or more packages in format ```{ns}:{packageName}```
759
+ * @returns {(Object|Array)} See above
730
760
  */
731
761
  importPkg = async (...pkgs) => {
732
- const { defaultsDeep } = this.lib.aneka
762
+ const { defaultsDeep } = this.app.lib.aneka
733
763
  const result = {}
734
764
  const notFound = []
735
- let opts = { returnDefault: true, thrownNotFound: false }
765
+ let opts = { returnDefault: true, throwNotFound: false }
736
766
  if (isPlainObject(last(pkgs))) {
737
767
  opts = defaultsDeep(pkgs.pop(), opts)
738
768
  }
@@ -744,7 +774,7 @@ class Bajo extends BasePlugin {
744
774
  notFound.push(pkg)
745
775
  continue
746
776
  }
747
- const p = this.readJson(`${dir}/package.json`, opts.thrownNotFound)
777
+ const p = this.readJson(`${dir}/package.json`, opts.throwNotFound)
748
778
  const mainFileOrg = dir + '/' + (p.main ?? get(p, 'exports.default', 'index.js'))
749
779
  let mainFile = resolvePath(mainFileOrg, os.platform() === 'win32')
750
780
  if (isEmpty(path.extname(mainFile))) {
@@ -760,17 +790,17 @@ class Bajo extends BasePlugin {
760
790
  result[name] = mod
761
791
  }
762
792
  if (notFound.length > 0) throw this.error('cantFind%s', this.join(notFound))
763
- if (pkgs.length === 1) return result[keys(result)[0]]
764
793
  if (opts.asObject) return result
794
+ if (pkgs.length === 1) return result[keys(result)[0]]
765
795
  return values(result)
766
796
  }
767
797
 
768
798
  /**
769
- * Check whether directory is empty or not. More info please {@link https://github.com/gulpjs/empty-dir|check here}.
799
+ * Check whether a directory is empty or not. More info please {@link https://github.com/gulpjs/empty-dir|check here}.
770
800
  *
771
801
  * @method
772
802
  * @async
773
- * @param {string} dir - Directory to check. Can be a ns based directory too!
803
+ * @param {(string|TNsPathPairs)} dir - Directory to check
774
804
  * @param {function} filterFn - Filter function to filter out files that cause false positives.
775
805
  * @returns {boolean}
776
806
  */
@@ -784,7 +814,7 @@ class Bajo extends BasePlugin {
784
814
  * Check whether log level is within log's app current level
785
815
  *
786
816
  * @method
787
- * @param {string} level - Level to check. See {@link LogLevelsType} for more
817
+ * @param {string} level - Level to check. See {@link TLogLevels} for more
788
818
  * @returns {boolean}
789
819
  */
790
820
  isLogInRange = (level) => {
@@ -833,19 +863,28 @@ class Bajo extends BasePlugin {
833
863
  return this.isValidAppPlugin(dir, 'plugin', returnPkg)
834
864
  }
835
865
 
836
- join = (array, sep) => {
837
- const { isSet } = this.lib.aneka
866
+ /**
867
+ * Human friendly join array of items.
868
+ *
869
+ * @method
870
+ * @param {any[]} array - Array to join
871
+ * @param {(string|Object)} options - If provided and is a string, it will be used as separator
872
+ * @param {string} [options.separator=', '] - Separator to use
873
+ * @param {string} [options.lastSeparator=and] - Text to use as the last separator
874
+ * @returns {string}
875
+ */
876
+ join = (array, options) => {
877
+ const { isSet } = this.app.lib.aneka
838
878
  const translate = val => {
839
- if (this &amp;&amp; this.print) return this.print.write(val).toLowerCase()
840
- return val
879
+ return this.t(val).toLowerCase()
841
880
  }
842
881
  if (array.length === 0) return translate('none')
843
882
  if (array.length === 1) return array[0]
844
- if (isSet(sep) &amp;&amp; !isPlainObject(sep)) return array.join(sep)
845
- let { separator = ', ', joiner = 'and' } = sep ?? {}
846
- joiner = translate(joiner)
883
+ if (isSet(options) &amp;&amp; !isPlainObject(options)) return array.join(options)
884
+ let { separator = ', ', lastSeparator = 'and' } = options ?? {}
885
+ lastSeparator = translate(lastSeparator)
847
886
  const last = (array.pop() ?? '').trim()
848
- return array.map(a => (a + '').trim()).join(separator) + ` ${joiner} ${last}`
887
+ return array.map(a => (a + '').trim()).join(separator) + ` ${lastSeparator} ${last}`
849
888
  }
850
889
 
851
890
  /**
@@ -866,22 +905,24 @@ class Bajo extends BasePlugin {
866
905
  * Parse duration to its millisecond value. Use {@link https://github.com/vercel/ms|ms} under the hood
867
906
  *
868
907
  * @method
869
- * @param {(number|string)} dur - If string is given, parse this to its millisecond value. Otherwise return as is
908
+ * @param {(number|string)} dur - If string is given, parse this to its millisecond value. Otherwise returns as is
870
909
  * @returns {number}
910
+ * @see {@link https://github.com/vercel/ms|ms}
871
911
  */
872
912
  parseDur = (dur) => {
873
913
  return isNumber(dur) ? dur : ms(dur)
874
914
  }
875
915
 
876
916
  /**
877
- * Parse datetime string as Javascript object. Please visit {@link https://day.js.org|dayjs} for valid formats and more infos
917
+ * Parse datetime string as Javascript date object. Please visit {@link https://day.js.org|dayjs} for valid formats and more infos
878
918
  *
879
919
  * @method
880
920
  * @param {string} dt - Datetime string
881
- * @returns {Object} Javascript object
921
+ * @returns {Object} Javascript date object
922
+ * @see {@link https://day.js.org|dayjs}
882
923
  */
883
924
  parseDt = (dt) => {
884
- const value = this.lib.dayjs(dt)
925
+ const value = this.app.lib.dayjs(dt)
885
926
  if (!value.isValid()) throw this.error('dtUnparsable%s', dt)
886
927
  return value.toDate()
887
928
  }
@@ -891,7 +932,7 @@ class Bajo extends BasePlugin {
891
932
  * to parse values, so please have a visit to know how it works
892
933
  *
893
934
  * If ```options.parseValue``` is ```true```, any key ends with ```Dur``` and ```Dt``` will
894
- * also be parsed as millisecond and Javascript datetime accordingly
935
+ * also be parsed as millisecond and Javascript date time accordingly.
895
936
  *
896
937
  * @method
897
938
  * @param {(Object|string)} input - If string is given, parse it first using JSON.parse
@@ -900,14 +941,15 @@ class Bajo extends BasePlugin {
900
941
  * @param {boolean} [options.parseValue=false] - If ```true```, values will be parsed &amp; normalized
901
942
  * @param {string} [options.lang] - If provided, use this language instead of the one in config
902
943
  * @returns {Object}
944
+ * @see {@link https://github.com/ladjs/dotenv-parse-variables}
903
945
  */
904
946
  parseObject = (input, options = {}) => {
905
947
  const { silent = true, parseValue = false, lang, ns } = options
906
- const { isSet } = this.lib.aneka
948
+ const { isSet } = this.app.lib.aneka
907
949
  const translate = (item) => {
908
950
  const scope = ns ? this.app[ns] : this
909
951
  const [text, ...args] = item.split('|')
910
- return scope.print.write(text, ...args, { lang })
952
+ return scope.t(text, ...args, { lang })
911
953
  }
912
954
  const statics = ['*']
913
955
  if (isString(input)) {
@@ -957,7 +999,7 @@ class Bajo extends BasePlugin {
957
999
  }
958
1000
 
959
1001
  pick = (obj, items, excludeUnset) => {
960
- const { isSet } = this.lib.aneka
1002
+ const { isSet } = this.app.lib.aneka
961
1003
  const result = {}
962
1004
  for (const item of items) {
963
1005
  const [k, nk] = item.split(':')
@@ -986,25 +1028,25 @@ class Bajo extends BasePlugin {
986
1028
  * @returns {Object}
987
1029
  */
988
1030
  readConfig = async (file, { ns, pattern, globOptions = {}, ignoreError, defValue = {}, opts = {} } = {}) => {
989
- if (!ns) ns = this.name
1031
+ if (!ns) ns = this.ns
990
1032
  file = resolvePath(this.getPluginFile(file))
991
1033
  let ext = path.extname(file)
992
1034
  const fname = path.dirname(file) + '/' + path.basename(file, ext)
993
1035
  ext = ext.toLowerCase()
994
1036
  if (ext === '.js') {
995
- const { readHandler } = find(this.app.bajo.configHandlers, { ext })
1037
+ const { readHandler } = find(this.app.configHandlers, { ext })
996
1038
  return this.parseObject(await readHandler.call(this.app[ns], file, opts))
997
1039
  }
998
- if (ext === '.json') return await this.readJson(file)
1040
+ if (ext === '.json') return await this.fromJson(file, null)
999
1041
  if (!['', '.*'].includes(ext)) {
1000
- const item = find(this.app.bajo.configHandlers, { ext })
1042
+ const item = find(this.app.configHandlers, { ext })
1001
1043
  if (!item) {
1002
1044
  if (!ignoreError) throw this.error('cantParse%s', file, { code: 'BAJO_CONFIG_NO_PARSER' })
1003
1045
  return this.parseObject(defValue)
1004
1046
  }
1005
1047
  return this.parseObject(await item.readHandler.call(this.app[ns], file, opts))
1006
1048
  }
1007
- const item = pattern ?? `${fname}.{${map(map(this.app.bajo.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
1049
+ const item = pattern ?? `${fname}.{${map(map(this.app.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
1008
1050
  const files = await fastGlob(item, globOptions)
1009
1051
  if (files.length === 0) {
1010
1052
  if (!ignoreError) throw this.error('noConfigFileFound', { code: 'BAJO_CONFIG_FILE_NOT_FOUND' })
@@ -1013,12 +1055,12 @@ class Bajo extends BasePlugin {
1013
1055
  let config = defValue
1014
1056
  for (const f of files) {
1015
1057
  const ext = path.extname(f).toLowerCase()
1016
- const item = find(this.app.bajo.configHandlers, { ext })
1058
+ const item = find(this.app.configHandlers, { ext })
1017
1059
  if (!item) {
1018
1060
  if (!ignoreError) throw this.error('cantParse%s', f, { code: 'BAJO_CONFIG_NO_PARSER' })
1019
1061
  continue
1020
1062
  }
1021
- config = await item.readHandler.call(this.app[ns], f, opts)
1063
+ config = await item.readHandler.call(this.app[ns], f, null, opts)
1022
1064
  if (!isEmpty(config)) break
1023
1065
  }
1024
1066
  return this.parseObject(config)
@@ -1034,7 +1076,7 @@ class Bajo extends BasePlugin {
1034
1076
  */
1035
1077
  readJson = (file, thrownNotFound = false) => {
1036
1078
  if (isPlainObject(thrownNotFound)) thrownNotFound = false
1037
- if (!fs.existsSync(file) &amp;&amp; thrownNotFound) throw this.error('notFound%s%s', this.print.write('file'), file)
1079
+ if (!fs.existsSync(file) &amp;&amp; thrownNotFound) throw this.error('notFound%s%s', this.t('file'), file)
1038
1080
  let resp
1039
1081
  try {
1040
1082
  resp = fs.readFileSync(file, 'utf8')
@@ -1043,12 +1085,49 @@ class Bajo extends BasePlugin {
1043
1085
  return this.parseObject(JSON.parse(resp))
1044
1086
  }
1045
1087
 
1088
+ fromJson (file, isContent) {
1089
+ const content = isContent ? file : fs.readFileSync(file, 'utf8')
1090
+ return JSON.parse(content)
1091
+ }
1092
+
1093
+ toJson = (file, isContent, opts = 2) => {
1094
+ const content = isContent ? file : JSON.parse(fs.readFileSync(file, 'utf8'))
1095
+ return JSON.stringify(content, null, opts)
1096
+ }
1097
+
1098
+ /**
1099
+ * Read all config files by path
1100
+ *
1101
+ * @method
1102
+ * @async
1103
+ * @param {string} path - Base path to start looking config files
1104
+ * @returns {Object}
1105
+ */
1106
+ readAllConfigs = async (path) => {
1107
+ const { defaultsDeep } = this.app.lib.aneka
1108
+ let cfg = {}
1109
+ let ext = {}
1110
+ // default config file
1111
+ try {
1112
+ cfg = await this.readConfig(`${path}.*`, { ignoreError: true })
1113
+ } catch (err) {
1114
+ if (['BAJO_CONFIG_NO_PARSER'].includes(err.code)) throw err
1115
+ }
1116
+ // env based config file
1117
+ try {
1118
+ ext = await this.readConfig(`${path}-${this.config.env}.*`, { ignoreError: true })
1119
+ } catch (err) {
1120
+ if (!['BAJO_CONFIG_FILE_NOT_FOUND'].includes(err.code)) throw err
1121
+ }
1122
+ return defaultsDeep({}, ext, cfg)
1123
+ }
1124
+
1046
1125
  /**
1047
- * Run named hook
1126
+ * Run named hook/event
1048
1127
  *
1049
1128
  * @method
1050
1129
  * @async
1051
- * @param {string} hookName - ns based hook name
1130
+ * @param {TNsPathPairs} hookName
1052
1131
  * @param {...any} [args] - Argument passed to the hook function
1053
1132
  * @returns {Array} Array of hook execution results
1054
1133
  */
@@ -1087,7 +1166,7 @@ class Bajo extends BasePlugin {
1087
1166
  */
1088
1167
  saveAsDownload = async (file, item, printSaved = true) => {
1089
1168
  const { print, getPluginDataDir } = this.app.bajo
1090
- const fname = increment(`${getPluginDataDir(this.name)}/download/${trim(file, '/')}`, { fs: true })
1169
+ const fname = increment(`${getPluginDataDir(this.ns)}/download/${trim(file, '/')}`, { fs: true })
1091
1170
  const dir = path.dirname(fname)
1092
1171
  if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
1093
1172
  await fs.writeFile(fname, item, 'utf8')
@@ -1097,4 +1176,4 @@ class Bajo extends BasePlugin {
1097
1176
  }
1098
1177
 
1099
1178
  export default Bajo
1100
- </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 Framework</a><div class="mobile-nav-links"><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo.app</a></div><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><div class="mobile-sidebar-items-c"><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-class_helper_bajo.html">class/helper/bajo</a></div><div class="sidebar-section-children"><a href="module-class_helper_plugin.html">class/helper/plugin</a></div><div class="sidebar-section-children"><a href="module-lib_create-method.html">lib/create-method</a></div><div class="sidebar-section-children"><a href="module-lib_formats.html">lib/formats</a></div><div class="sidebar-section-children"><a href="module-lib_log-levels.html">lib/log-levels</a></div><div class="sidebar-section-children"><a href="module-lib_resolve-path.html">lib/resolve-path</a></div><div class="sidebar-section-children"><a href="module-lib_shim.html">lib/shim</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="BasePlugin.html">BasePlugin</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><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-contribution.html">Contribution</a></div><div class="sidebar-section-children"><a href="tutorial-ecosystem.html">Ecosystem</a></div><div class="sidebar-section-children"><a href="tutorial-getting-started.html">Getting Started</a></div><div class="sidebar-section-children"><a href="tutorial-plugin-dev.html">Plugin Development</a></div><div class="sidebar-section-children"><a href="tutorial-user-guide.html">User Guide</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#NsPathType">NsPathType</a></div><div class="sidebar-section-children"><a href="global.html#ObjectFormatType">ObjectFormatType</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>
1179
+ </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="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><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</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#event:bajo:afterAll%257Bmethod%257D">bajo:afterAll{method}</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:afterBootComplete">bajo:afterBootComplete</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:afterBuildCollection">bajo:afterBuildCollection</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:afterCollectHooks">bajo:afterCollectHooks</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:beforeAll%257Bmethod%257D">bajo:beforeAll{method}</a></div><div class="sidebar-section-children"><a href="global.html#event:bajo:beforeBuildCollection">bajo:beforeBuildCollection</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:afterAppletRun">{ns}:afterAppletRun</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:after%257Bmethod%257D">{ns}:after{method}</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:beforeAppletRun">{ns}:beforeAppletRun</a></div><div class="sidebar-section-children"><a href="global.html#event:%257Bns%257D:before%257Bmethod%257D">{ns}:before{method}</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_Bajo.html">Helper/Bajo</a></div><div class="sidebar-section-children"><a href="module-Helper_Base.html">Helper/Base</a></div><div class="sidebar-section-children"><a href="module-Lib.html">Lib</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#TAppConfigHandler">TAppConfigHandler</a></div><div class="sidebar-section-children"><a href="global.html#TAppEnv">TAppEnv</a></div><div class="sidebar-section-children"><a href="global.html#TAppLib">TAppLib</a></div><div class="sidebar-section-children"><a href="global.html#TBajoDataType">TBajoDataType</a></div><div class="sidebar-section-children"><a href="global.html#TBajoFormatResult">TBajoFormatResult</a></div><div class="sidebar-section-children"><a href="global.html#TBajoFormatType">TBajoFormatType</a></div><div class="sidebar-section-children"><a href="global.html#TLogJson">TLogJson</a></div><div class="sidebar-section-children"><a href="global.html#TLogLevels">TLogLevels</a></div><div class="sidebar-section-children"><a href="global.html#TNsPathPairs">TNsPathPairs</a></div><div class="sidebar-section-children"><a href="global.html#TNsPathResult">TNsPathResult</a></div><div class="sidebar-section-children"><a href="global.html#TPrintOptions">TPrintOptions</a></div><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>