bajo 2.18.0 → 2.20.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.
- package/.github/workflows/test.yml +37 -0
- package/class/_helper.js +23 -7
- package/class/app.js +64 -47
- package/class/bajo.js +182 -138
- package/class/base.js +3 -3
- package/class/cache.js +60 -0
- package/class/err.js +14 -11
- package/class/log.js +41 -40
- package/class/plugin.js +35 -36
- package/class/print.js +54 -51
- package/class/tools.js +3 -4
- package/docs/App.html +7 -7
- package/docs/Bajo.html +2 -2
- package/docs/Base.html +1 -1
- package/docs/Cache.html +3 -0
- package/docs/Err.html +2 -2
- package/docs/Log.html +2 -2
- package/docs/Plugin.html +1 -1
- package/docs/Print.html +1 -1
- package/docs/Tools.html +3 -0
- package/docs/class__helper.js.html +694 -0
- package/docs/class_app.js.html +307 -149
- package/docs/class_bajo.js.html +316 -464
- package/docs/class_base.js.html +35 -32
- package/docs/class_cache.js.html +150 -0
- package/docs/class_err.js.html +144 -0
- package/docs/class_log.js.html +270 -0
- package/docs/class_plugin.js.html +98 -71
- package/docs/class_print.js.html +261 -0
- package/docs/class_tools.js.html +44 -0
- package/docs/data/search.json +1 -1
- package/docs/global.html +1 -4
- package/docs/index.html +1 -1
- package/docs/index.js.html +21 -14
- package/docs/lib_find-deep.js.html +27 -0
- package/docs/lib_formats.js.html +19 -19
- package/docs/lib_freeze.js.html +19 -0
- package/docs/lib_import-module.js.html +16 -14
- package/docs/lib_index.js.html +9 -0
- package/docs/lib_log-levels.js.html +2 -2
- package/docs/module-Helper.html +3 -0
- package/docs/module-Lib.html +3 -8
- package/docs/scripts/core.js +477 -476
- package/docs/scripts/resize.js +36 -36
- package/docs/scripts/search.js +105 -105
- package/docs/scripts/third-party/fuse.js +1 -1
- package/docs/scripts/third-party/hljs-line-num-original.js +285 -282
- package/docs/scripts/third-party/hljs-line-num.js +1 -1
- package/docs/scripts/third-party/hljs-original.js +1202 -1195
- package/docs/scripts/third-party/hljs.js +1 -1
- package/docs/scripts/third-party/popper.js +1 -1
- package/docs/scripts/third-party/tippy.js +1 -1
- package/docs/scripts/third-party/tocbot.js +509 -508
- package/index.js +8 -11
- package/lib/find-deep.js +3 -3
- package/lib/formats.js +17 -17
- package/lib/freeze.js +3 -3
- package/lib/import-module.js +8 -8
- package/package.json +3 -2
- package/test/app.test.js +183 -0
- package/test/bajo.test.js +125 -0
- package/test/base.test.js +74 -107
- package/test/cache.test.js +94 -0
- package/test/e2e.test.js +137 -0
- package/test/err.test.js +73 -0
- package/test/helper.test.js +39 -0
- package/test/import-module.test.js +138 -0
- package/test/integration.test.js +218 -0
- package/test/log.test.js +119 -0
- package/test/plugin.test.js +116 -0
- package/test/print.test.js +100 -0
- package/test/tools.test.js +38 -0
- package/wiki/CHANGES.md +12 -0
- package/.mocharc.json +0 -4
package/docs/class_bajo.js.html
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
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 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'
|
|
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-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: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 class="sidebar-section-children"><a href="module-Helper%257Bns%257D_afterAppletRun.html">Helper{ns}:afterAppletRun</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-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#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 Tools from './tools.js'
|
|
4
|
+
import Plugin from './plugin.js'
|
|
4
5
|
import increment from 'add-filename-increment'
|
|
5
6
|
import fs from 'fs-extra'
|
|
6
7
|
import path from 'path'
|
|
7
8
|
import os from 'os'
|
|
8
|
-
import ms from 'ms'
|
|
9
|
-
import dotenvParseVariables from 'dotenv-parse-variables'
|
|
10
9
|
import emptyDir from 'empty-dir'
|
|
11
10
|
import lodash from 'lodash'
|
|
12
|
-
import currentLoc from '../lib/current-loc.js'
|
|
13
11
|
import { createRequire } from 'module'
|
|
14
12
|
import getGlobalPath from 'get-global-path'
|
|
15
|
-
import { customAlphabet } from 'nanoid'
|
|
16
13
|
import fastGlob from 'fast-glob'
|
|
17
14
|
import querystring from 'querystring'
|
|
18
|
-
import deepFreeze from 'deep-freeze-strict'
|
|
19
|
-
import resolvePath from '../lib/resolve-path.js'
|
|
20
15
|
import importModule from '../lib/import-module.js'
|
|
21
16
|
import logLevels from '../lib/log-levels.js'
|
|
22
17
|
import { types as formatTypes, formats } from '../lib/formats.js'
|
|
18
|
+
import aneka from 'aneka'
|
|
23
19
|
import {
|
|
24
20
|
buildBaseConfig,
|
|
25
21
|
buildExtConfig,
|
|
@@ -28,17 +24,37 @@ import {
|
|
|
28
24
|
bootOrder,
|
|
29
25
|
bootPlugins,
|
|
30
26
|
exitHandler
|
|
31
|
-
} from './
|
|
27
|
+
} from './_helper.js'
|
|
32
28
|
|
|
33
29
|
const require = createRequire(import.meta.url)
|
|
34
30
|
|
|
35
31
|
const {
|
|
36
32
|
isFunction, map, isObject,
|
|
37
|
-
trim, filter, isEmpty, orderBy, pullAt, find, camelCase,
|
|
38
|
-
cloneDeep, isPlainObject, isArray, isString,
|
|
33
|
+
trim, filter, isEmpty, orderBy, pullAt, find, camelCase,
|
|
34
|
+
cloneDeep, isPlainObject, isArray, isString, omit, keys, indexOf,
|
|
39
35
|
last, get, has, values, dropRight, pick
|
|
40
36
|
} = lodash
|
|
41
37
|
|
|
38
|
+
const { resolvePath } = aneka
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Name based ```{ns}:{path}``` format.
|
|
42
|
+
*
|
|
43
|
+
* @typedef {string} TNsPathPairs
|
|
44
|
+
* @see TNsPathResult
|
|
45
|
+
* @see Bajo#buildNsPath
|
|
46
|
+
* @see Bajo#breakNsPath
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Object returned by {@link Bajo#getUnitFormat|bajo:getUnitFormat}.
|
|
51
|
+
*
|
|
52
|
+
* @typedef {Object} TBajoFormatResult
|
|
53
|
+
* @property {string} unitSys - Unit system.
|
|
54
|
+
* @property {Object} format - Format object.
|
|
55
|
+
* @see Bajo#getUnitFormat
|
|
56
|
+
*/
|
|
57
|
+
|
|
42
58
|
/**
|
|
43
59
|
* The Core. The main engine. The one and only plugin that control app's boot process and
|
|
44
60
|
* making sure all other plugins working nicely.
|
|
@@ -46,31 +62,28 @@ const {
|
|
|
46
62
|
* @class
|
|
47
63
|
*/
|
|
48
64
|
class Bajo extends Plugin {
|
|
49
|
-
static alias = 'bajo'
|
|
50
65
|
/**
|
|
51
|
-
* @param {App} app - App instance. Usefull to call app method inside a plugin
|
|
66
|
+
* @param {App} app - App instance. Usefull to call app method inside a plugin.
|
|
52
67
|
*/
|
|
53
68
|
constructor (app) {
|
|
54
69
|
super('bajo', app)
|
|
70
|
+
this.alias = 'bajo'
|
|
55
71
|
this.whiteSpace = [' ', '\t', '\n', '\r']
|
|
56
72
|
/**
|
|
57
|
-
* Config object
|
|
73
|
+
* Config object.
|
|
58
74
|
*
|
|
59
75
|
* @type {Object}
|
|
60
76
|
* @see {@tutorial config}
|
|
61
77
|
*/
|
|
62
78
|
this.config = {}
|
|
63
79
|
|
|
80
|
+
// by defaualt, only these config formats below are supported.
|
|
64
81
|
app.configHandlers = [
|
|
65
|
-
{ ext: '.js', readHandler: this.
|
|
82
|
+
{ ext: '.js', readHandler: this.fromJs },
|
|
66
83
|
{ ext: '.json', readHandler: this.fromJson, writeHandler: this.toJson }
|
|
67
84
|
]
|
|
68
|
-
}
|
|
69
85
|
|
|
70
|
-
|
|
71
|
-
let mod = await importModule(file)
|
|
72
|
-
if (isFunction(mod)) mod = await mod.call(this, opts)
|
|
73
|
-
return mod
|
|
86
|
+
this.hooks = []
|
|
74
87
|
}
|
|
75
88
|
|
|
76
89
|
/**
|
|
@@ -95,40 +108,12 @@ class Bajo extends Plugin {
|
|
|
95
108
|
await bootOrder.call(this)
|
|
96
109
|
await bootPlugins.call(this)
|
|
97
110
|
await exitHandler.call(this)
|
|
111
|
+
if (this.app.bajoSpatial) {
|
|
112
|
+
this.anekaSpatial = await this.importPkg('bajoSpatial:aneka-spatial')
|
|
113
|
+
}
|
|
98
114
|
}
|
|
99
115
|
|
|
100
|
-
|
|
101
|
-
* Resolve file name to filesystem's path. Windows path separator ```\```
|
|
102
|
-
* is normalized to Unix's ```/```
|
|
103
|
-
*
|
|
104
|
-
* @method
|
|
105
|
-
* @param {string} file - File to resolve
|
|
106
|
-
* @param {boolean} [asFileUrl=false] - Return as file URL format ```file:///<name>```
|
|
107
|
-
* @returns {string}
|
|
108
|
-
*/
|
|
109
|
-
resolvePath = (file, asFileUrl) => {
|
|
110
|
-
return resolvePath(file, asFileUrl)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Freeze object
|
|
115
|
-
*
|
|
116
|
-
* @method
|
|
117
|
-
* @param {Object} obj - Object to freeze
|
|
118
|
-
* @param {boolean} [shallow=false] - If ```false``` (default), deep freeze object
|
|
119
|
-
*/
|
|
120
|
-
freeze = (obj, shallow = false) => {
|
|
121
|
-
if (shallow) Object.freeze(obj)
|
|
122
|
-
else deepFreeze(obj)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
setImmediate = async () => {
|
|
126
|
-
return new Promise((resolve) => {
|
|
127
|
-
setImmediate(() => resolve())
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
breakNsPathFromFile = ({ file, dir, baseNs, suffix = '', getType } = {}) => {
|
|
116
|
+
breakNsPathFromFile = ({ file = '', dir = '', ns, suffix = '', getType } = {}) => {
|
|
132
117
|
let item = file.replace(dir + suffix, '')
|
|
133
118
|
let type
|
|
134
119
|
if (getType) {
|
|
@@ -140,32 +125,24 @@ class Bajo extends Plugin {
|
|
|
140
125
|
let [name, _path] = item.split('@')
|
|
141
126
|
if (!_path) {
|
|
142
127
|
_path = name
|
|
143
|
-
name =
|
|
128
|
+
name = ns
|
|
144
129
|
}
|
|
145
130
|
_path = camelCase(_path)
|
|
146
131
|
const names = map(name.split('.'), n => camelCase(n))
|
|
147
|
-
const [
|
|
148
|
-
return { ns, subNs, path: _path, fullNs: names.join('.'), type }
|
|
132
|
+
const [_ns, subNs] = names
|
|
133
|
+
return { ns: _ns, subNs, path: _path, fullNs: names.join('.'), type }
|
|
149
134
|
}
|
|
150
135
|
|
|
151
136
|
/**
|
|
152
|
-
*
|
|
153
|
-
* @typedef {string} TNsPathPairs
|
|
154
|
-
* @see TNsPathResult
|
|
155
|
-
* @see Bajo#buildNsPath
|
|
156
|
-
* @see Bajo#breakNsPath
|
|
157
|
-
*/
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Build ns/path pairs
|
|
137
|
+
* Build ns/path pairs.
|
|
161
138
|
*
|
|
162
139
|
* @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}
|
|
140
|
+
* @param {object} [options={}] - Options object.
|
|
141
|
+
* @param {string} [options.ns=''] - Namespace.
|
|
142
|
+
* @param {string} [options.subNs] - Sub namespace.
|
|
143
|
+
* @param {string} [options.subSubNs] - Sub sub namespace.
|
|
144
|
+
* @param {string} [options.path] - Path.
|
|
145
|
+
* @returns {TNsPathPairs} Ns/path pairs.
|
|
169
146
|
*/
|
|
170
147
|
buildNsPath = ({ ns = '', subNs, subSubNs, path } = {}) => {
|
|
171
148
|
if (subNs) ns += '.' + subNs
|
|
@@ -174,21 +151,21 @@ class Bajo extends Plugin {
|
|
|
174
151
|
}
|
|
175
152
|
|
|
176
153
|
/**
|
|
177
|
-
* Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath}
|
|
154
|
+
* Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath}.
|
|
178
155
|
*
|
|
179
156
|
* @typedef {Object} TNsPathResult
|
|
180
|
-
* @property {string} ns - Namespace
|
|
181
|
-
* @property {string} [subNs] - Sub namespace
|
|
182
|
-
* @property {string} [subSubNs] - Sub of sub namespace
|
|
183
|
-
* @property {string} path - Path without query string or hash
|
|
184
|
-
* @property {string} fullPath - Full path, including query string and hash
|
|
157
|
+
* @property {string} ns - Namespace.
|
|
158
|
+
* @property {string} [subNs] - Sub namespace.
|
|
159
|
+
* @property {string} [subSubNs] - Sub of sub namespace.
|
|
160
|
+
* @property {string} path - Path without query string or hash.
|
|
161
|
+
* @property {string} fullPath - Full path, including query string and hash.
|
|
185
162
|
* @see TNsPathPairs
|
|
186
163
|
* @see Bajo#buildNsPath
|
|
187
164
|
* @see Bajo#breakNsPath
|
|
188
165
|
*/
|
|
189
166
|
|
|
190
167
|
/**
|
|
191
|
-
* Break name to its namespace & path infos
|
|
168
|
+
* Break name to its namespace & path infos.
|
|
192
169
|
*
|
|
193
170
|
* @method
|
|
194
171
|
* @param {(TNsPathPairs|string)} name - Name to break
|
|
@@ -208,7 +185,7 @@ class Bajo extends Plugin {
|
|
|
208
185
|
[ns, subNs, subSubNs] = ns.split('.')
|
|
209
186
|
if (checkNs) {
|
|
210
187
|
if (!this.app[ns]) {
|
|
211
|
-
const plugin = this.getPlugin(ns)
|
|
188
|
+
const plugin = this.app.getPlugin(ns)
|
|
212
189
|
if (plugin) ns = plugin.ns
|
|
213
190
|
}
|
|
214
191
|
if (!this.app[ns]) throw this.error('unknownPluginOrNotLoaded%s')
|
|
@@ -245,19 +222,19 @@ class Bajo extends Plugin {
|
|
|
245
222
|
*
|
|
246
223
|
* @method
|
|
247
224
|
* @async
|
|
248
|
-
* @param {Object} options - Options
|
|
225
|
+
* @param {Object} options - Options.
|
|
249
226
|
* @param {string} [options.ns] - Namespace. If not provided, defaults to ```bajo```
|
|
250
|
-
* @param {function} [options.handler] - Handler to call while building the collection item
|
|
251
|
-
* @param {string[]} [options.dupChecks=[]] - Array of keys to check for duplicates
|
|
252
|
-
* @param {string} options.container - Key used as container name
|
|
253
|
-
* @param {boolean} [options.useDefaultName=true] - If true (default) and ```name``` key is not provided, returned collection will be named ```default
|
|
227
|
+
* @param {function} [options.handler] - Handler to call while building the collection item.
|
|
228
|
+
* @param {string[]} [options.dupChecks=[]] - Array of keys to check for duplicates.
|
|
229
|
+
* @param {string} options.container - Key used as container name.
|
|
230
|
+
* @param {boolean} [options.useDefaultName=true] - If true (default) and ```name``` key is not provided, returned collection will be named ```default```.
|
|
254
231
|
* @fires bajo:beforeBuildCollection
|
|
255
232
|
* @fires bajo:afterBuildCollection
|
|
256
233
|
* @returns {Object[]} The collection
|
|
257
234
|
*/
|
|
258
235
|
buildCollections = async (options = {}) => {
|
|
259
|
-
|
|
260
|
-
|
|
236
|
+
const { parseObject } = this.app.lib
|
|
237
|
+
let { ns, handler, dupChecks = [], container, useDefaultName = true, noDefault = true } = options
|
|
261
238
|
if (!ns) ns = this.ns
|
|
262
239
|
const cfg = this.app[ns].getConfig()
|
|
263
240
|
let items = get(cfg, container, [])
|
|
@@ -265,7 +242,7 @@ class Bajo extends Plugin {
|
|
|
265
242
|
this.app[ns].log.trace('collecting%s', this.t(container))
|
|
266
243
|
|
|
267
244
|
/**
|
|
268
|
-
* Run before collection is built
|
|
245
|
+
* Run before collection is built.
|
|
269
246
|
*
|
|
270
247
|
* @global
|
|
271
248
|
* @event bajo:beforeBuildCollection
|
|
@@ -276,7 +253,7 @@ class Bajo extends Plugin {
|
|
|
276
253
|
await this.runHook(`${ns}:beforeBuildCollection`, container)
|
|
277
254
|
const deleted = []
|
|
278
255
|
for (const index in items) {
|
|
279
|
-
const item = items[index]
|
|
256
|
+
const item = parseObject(items[index])
|
|
280
257
|
if (useDefaultName) {
|
|
281
258
|
if (!has(item, 'name')) {
|
|
282
259
|
if (find(items, { name: 'default' })) throw this.app[ns].error('collExists%s', 'default')
|
|
@@ -300,6 +277,8 @@ class Bajo extends Plugin {
|
|
|
300
277
|
}
|
|
301
278
|
}
|
|
302
279
|
|
|
280
|
+
if (!noDefault && !items.find(item => item.name === 'default')) this.app[ns].fatal('missing%s%s', 'default', container)
|
|
281
|
+
|
|
303
282
|
/**
|
|
304
283
|
* Run after collection is built
|
|
305
284
|
*
|
|
@@ -325,26 +304,25 @@ class Bajo extends Plugin {
|
|
|
325
304
|
*
|
|
326
305
|
* @method
|
|
327
306
|
* @async
|
|
328
|
-
* @param {(TNsPathPairs|Object|function)} name - Method's name, function handler, plain object or plugin instance
|
|
329
|
-
* @param {...any} [args] - One or more arguments passed as parameter to the handler
|
|
330
|
-
* @returns {any} Returned value
|
|
307
|
+
* @param {(TNsPathPairs|Object|function)} name - Method's name, function handler, plain object or plugin instance.
|
|
308
|
+
* @param {...any} [args] - One or more arguments passed as parameter to the handler.
|
|
309
|
+
* @returns {any} Returned value.
|
|
331
310
|
*/
|
|
332
311
|
callHandler = async (item, ...args) => {
|
|
333
312
|
let result
|
|
334
313
|
let scope = this
|
|
335
|
-
if (item instanceof Plugin) {
|
|
314
|
+
if (item instanceof Tools || item instanceof Plugin) {
|
|
336
315
|
scope = item
|
|
337
316
|
item = args.shift()
|
|
338
317
|
}
|
|
339
|
-
const bajo = scope.app.bajo
|
|
340
318
|
if (isString(item)) {
|
|
341
|
-
if (item.startsWith('applet:') &&
|
|
319
|
+
if (item.startsWith('applet:') && this.app.applets.length > 0) {
|
|
342
320
|
const [, ns, path] = item.split(':')
|
|
343
|
-
const applet = find(
|
|
344
|
-
if (applet &&
|
|
321
|
+
const applet = find(this.app.applets, a => (a.ns === ns || a.alias === ns))
|
|
322
|
+
if (applet && this.app.bajoCli) result = await this.app.bajoCli.runApplet(applet, path, ...args)
|
|
345
323
|
} else {
|
|
346
324
|
const [ns, method, ...params] = item.split(':')
|
|
347
|
-
const fn =
|
|
325
|
+
const fn = this.getMethod(`${ns}:${method}`)
|
|
348
326
|
if (fn) {
|
|
349
327
|
if (params.length > 0) args.unshift(...params)
|
|
350
328
|
result = await fn(...args)
|
|
@@ -367,34 +345,30 @@ class Bajo extends Plugin {
|
|
|
367
345
|
*
|
|
368
346
|
* @method
|
|
369
347
|
* @async
|
|
370
|
-
* @param {function} handler - Function handler. Can be an async function. Scoped to the running plugin
|
|
348
|
+
* @param {function} handler - Function handler. Can be an async function. Scoped to the running plugin.
|
|
371
349
|
* @param {(string|Object)} [options={}] - Options. If a string is provided, it serves as the glob pattern, otherwise:
|
|
372
350
|
* @param {(string|string[])} [options.glob] - Glob pattern. If provided,
|
|
373
|
-
* @param {boolean} [options.useBajo=false] - If true, add ```bajo``` to the running plugins too
|
|
374
|
-
* @param {string} [options.prefix=''] - Prepend glob pattern with prefix
|
|
375
|
-
* @param {boolean} [options.noUnderscore=true] - If true (default), matched file with name starts with underscore is ignored
|
|
376
|
-
* @param {any} [options.returnItems] - If true, each value of returned handler call will be saved as an object with running plugin name as its keys
|
|
351
|
+
* @param {boolean} [options.useBajo=false] - If true, add ```bajo``` to the running plugins too.
|
|
352
|
+
* @param {string} [options.prefix=''] - Prepend glob pattern with prefix.
|
|
353
|
+
* @param {boolean} [options.noUnderscore=true] - If true (default), matched file with name starts with underscore is ignored.
|
|
354
|
+
* @param {any} [options.returnItems] - If true, each value of returned handler call will be saved as an object with running plugin name as its keys.
|
|
377
355
|
* @returns {any}
|
|
378
356
|
*/
|
|
379
357
|
eachPlugins = async (handler, options = {}) => {
|
|
380
|
-
if (
|
|
358
|
+
if (isString(options)) options = { glob: options }
|
|
359
|
+
const { glob = [], useBajo, prefix = '', noUnderscore = true, returnItems, opts = {} } = options
|
|
360
|
+
const globs = isString(glob) ? [glob] : [...glob]
|
|
361
|
+
const pluginPkgs = useBajo ? [...cloneDeep(this.app.pluginPkgs), 'bajo'] : this.app.pluginPkgs
|
|
381
362
|
const result = {}
|
|
382
|
-
const pluginPkgs = cloneDeep(this.app.pluginPkgs) ?? []
|
|
383
|
-
const { glob, useBajo, prefix = '', noUnderscore = true, returnItems } = options
|
|
384
|
-
if (useBajo) pluginPkgs.unshift('bajo')
|
|
385
363
|
for (const pkgName of pluginPkgs) {
|
|
386
364
|
const ns = camelCase(pkgName)
|
|
387
365
|
let r
|
|
388
|
-
if (
|
|
366
|
+
if (globs.length > 0) {
|
|
389
367
|
const base = prefix === '' ? `${this.app[ns].dir.pkg}/extend` : `${this.app[ns].dir.pkg}/extend/${prefix}`
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
for (const i in pattern) {
|
|
395
|
-
if (!path.isAbsolute(pattern[i])) pattern[i] = `${base}/${pattern[i]}`
|
|
396
|
-
}
|
|
397
|
-
const files = await fastGlob(pattern, opts)
|
|
368
|
+
const patterns = globs.map(glob => {
|
|
369
|
+
return !path.isAbsolute(glob) ? `${base}/${glob}` : glob
|
|
370
|
+
})
|
|
371
|
+
const files = await fastGlob.glob(patterns, opts)
|
|
398
372
|
for (const f of files) {
|
|
399
373
|
if (path.basename(f)[0] === '_' && noUnderscore) continue
|
|
400
374
|
const resp = await handler.call(this.app[ns], { file: f, dir: base })
|
|
@@ -425,22 +399,13 @@ class Bajo extends Plugin {
|
|
|
425
399
|
}
|
|
426
400
|
|
|
427
401
|
/**
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
* @typedef {Object} TBajoFormatResult
|
|
431
|
-
* @property {string} unitSys - Unit system
|
|
432
|
-
* @property {Object} format - Format object
|
|
433
|
-
* @see Bajo#getUnitFormat
|
|
434
|
-
*/
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Get unit format
|
|
402
|
+
* Get unit format.
|
|
438
403
|
*
|
|
439
404
|
* @method
|
|
440
|
-
* @param {Object} [options={}] - Options
|
|
441
|
-
* @param {string} [options.lang] - Language to use. Defaults to the one you set in config
|
|
442
|
-
* @param {string} [options.unitSys] - Unit system to use. Defaults to language's unit system or ```metric``` if unspecified
|
|
443
|
-
* @returns {TBajoFormatResult}
|
|
405
|
+
* @param {Object} [options={}] - Options.
|
|
406
|
+
* @param {string} [options.lang] - Language to use. Defaults to the one you set in config.
|
|
407
|
+
* @param {string} [options.unitSys] - Unit system to use. Defaults to language's unit system or ```metric``` if unspecified.
|
|
408
|
+
* @returns {TBajoFormatResult} Returned value.
|
|
444
409
|
*/
|
|
445
410
|
getUnitFormat = (options = {}) => {
|
|
446
411
|
const lang = options.lang ?? this.config.lang
|
|
@@ -450,16 +415,16 @@ class Bajo extends Plugin {
|
|
|
450
415
|
}
|
|
451
416
|
|
|
452
417
|
/**
|
|
453
|
-
* Format value by type
|
|
418
|
+
* Format value by type.
|
|
454
419
|
*
|
|
455
420
|
* @method
|
|
456
|
-
* @param {string} type - Format type. See {@link TBajoFormatType} for acceptable values
|
|
457
|
-
* @param {any} value - Value to format
|
|
458
|
-
* @param {string} [dataType] - Value's data type. See {@link TBajoDataType} for acceptable values
|
|
459
|
-
* @param {Object} [options={}] - Options
|
|
460
|
-
* @param {boolean} [options.withUnit=true] - Return with its unit appended
|
|
461
|
-
* @param {string} [options.lang] - Format value according to this language. Defaults to the one you set in config
|
|
462
|
-
* @returns {(Array|string)} Return string if ```withUnit``` is true. Otherwise is an array of ```[value, unit, separator]
|
|
421
|
+
* @param {string} type - Format type. See {@link TBajoFormatType} for acceptable values.
|
|
422
|
+
* @param {any} value - Value to format.
|
|
423
|
+
* @param {string} [dataType] - Value's data type. See {@link TBajoDataType} for acceptable values.
|
|
424
|
+
* @param {Object} [options={}] - Options.
|
|
425
|
+
* @param {boolean} [options.withUnit=true] - Return with its unit appended.
|
|
426
|
+
* @param {string} [options.lang] - Format value according to this language. Defaults to the one you set in config.
|
|
427
|
+
* @returns {(Array|string)} Return string if ```withUnit``` is true. Otherwise is an array of ```[value, unit, separator]```.
|
|
463
428
|
*/
|
|
464
429
|
formatByType = (type, value, dataType, options = {}) => {
|
|
465
430
|
const { defaultsDeep } = this.app.lib.aneka
|
|
@@ -476,21 +441,21 @@ class Bajo extends Plugin {
|
|
|
476
441
|
}
|
|
477
442
|
|
|
478
443
|
/**
|
|
479
|
-
* Format value
|
|
444
|
+
* Format value.
|
|
480
445
|
*
|
|
481
446
|
* @method
|
|
482
|
-
* @param {any} value - Value to format
|
|
483
|
-
* @param {string} [type] - Data type to use. See {@link TBajoDataType} for acceptable values. If not provided, return the untouched value
|
|
484
|
-
* @param {Object} [options={}] - Options
|
|
485
|
-
* @param {string} [options.emptyValue=''] - Empty value to use if function resulted empty. Defaults to the one from your config
|
|
486
|
-
* @param {boolean} [options.withUnit=true] - Return with its unit appended
|
|
487
|
-
* @param {string} [options.lang] - Format value according to this language. Defaults to the one you set in config
|
|
488
|
-
* @param {string} [options.latitude] - If Bajo Spatial is loaded and data type is a double or float, then format it as latitude in degree, minute, second
|
|
489
|
-
* @param {string} [options.longitude] - If Bajo Spatial is loaded and data type is a double or float, then format it as longitude in degree, minute, second
|
|
490
|
-
* @returns {string} Formatted value
|
|
447
|
+
* @param {any} value - Value to format.
|
|
448
|
+
* @param {string} [type] - Data type to use. See {@link TBajoDataType} for acceptable values. If not provided, return the untouched value.
|
|
449
|
+
* @param {Object} [options={}] - Options.
|
|
450
|
+
* @param {string} [options.emptyValue=''] - Empty value to use if function resulted empty. Defaults to the one from your config.
|
|
451
|
+
* @param {boolean} [options.withUnit=true] - Return with its unit appended.
|
|
452
|
+
* @param {string} [options.lang] - Format value according to this language. Defaults to the one you set in config.
|
|
453
|
+
* @param {string} [options.latitude] - If Bajo Spatial is loaded and data type is a double or float, then format it as latitude in degree, minute, second.
|
|
454
|
+
* @param {string} [options.longitude] - If Bajo Spatial is loaded and data type is a double or float, then format it as longitude in degree, minute, second.
|
|
455
|
+
* @returns {string} Formatted value.
|
|
491
456
|
*/
|
|
492
457
|
format = (value, type, options = {}) => {
|
|
493
|
-
const { defaultsDeep } = this.app.lib.aneka
|
|
458
|
+
const { defaultsDeep, isSet } = this.app.lib.aneka
|
|
494
459
|
const { format } = this.config.intl
|
|
495
460
|
const { emptyValue = format.emptyValue } = options
|
|
496
461
|
const lang = options.lang ?? this.config.lang
|
|
@@ -500,8 +465,8 @@ class Bajo extends Plugin {
|
|
|
500
465
|
if (type === 'auto') {
|
|
501
466
|
if (value instanceof Date) type = 'datetime'
|
|
502
467
|
}
|
|
503
|
-
if (['float', 'double'].includes(type) && this.
|
|
504
|
-
const { latToDms, lngToDms } = this.
|
|
468
|
+
if (['float', 'double'].includes(type) && this.anekaSpatial) {
|
|
469
|
+
const { latToDms, lngToDms } = this.anekaSpatial
|
|
505
470
|
if (options.latitude) return latToDms(value)
|
|
506
471
|
if (options.longitude) return lngToDms(value)
|
|
507
472
|
}
|
|
@@ -532,46 +497,16 @@ class Bajo extends Plugin {
|
|
|
532
497
|
}
|
|
533
498
|
if (['array'].includes(type)) return value.join(', ')
|
|
534
499
|
if (['object'].includes(type)) return JSON.stringify(value)
|
|
500
|
+
if (['boolean'].includes(type) && isSet(value)) return value ? this.t('true', { lang }) : this.t('false', { lang })
|
|
535
501
|
return value
|
|
536
502
|
}
|
|
537
503
|
|
|
538
504
|
/**
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
* @method
|
|
542
|
-
* @param {(boolean|string|Object)} [options={}] - Options. If set to ```true``` or ```alpha```, it will generate alphaphet only characters. If set to ```int```, it will generate integer only characters. Otherwise:
|
|
543
|
-
* @param {string} [options.pattern] - Character pattern to use. Defaults to all available alphanumeric characters
|
|
544
|
-
* @param {number} [options.length=13] - Length of resulted characters
|
|
545
|
-
* @param {string} [options.case] - If set to ```lower``` to use lower cased pattern only. For upper cased pattern, set it to ```upper```
|
|
546
|
-
* @param {boolean} [options.returnInstance] - Set to ```true``` to return {@link https://github.com/ai/nanoid|nanoid} instance instead of string
|
|
547
|
-
* @returns {(string|Object)} Return string or instance of {@link https://github.com/ai/nanoid|nanoid}
|
|
548
|
-
*/
|
|
549
|
-
generateId = (options = {}) => {
|
|
550
|
-
let type
|
|
551
|
-
if (options === true) options = 'alpha'
|
|
552
|
-
if (options === 'int') {
|
|
553
|
-
type = options
|
|
554
|
-
options = { pattern: '0123456789', length: 15 }
|
|
555
|
-
} else if (options === 'alpha') {
|
|
556
|
-
type = options
|
|
557
|
-
options = { pattern: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', length: 15 }
|
|
558
|
-
}
|
|
559
|
-
let { pattern, length = 13, returnInstance } = options
|
|
560
|
-
pattern = pattern ?? 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
|
561
|
-
if (options.case === 'lower') pattern = pattern.toLowerCase()
|
|
562
|
-
else if (options.case === 'upper') pattern = pattern.toUpperCase()
|
|
563
|
-
const nid = customAlphabet(pattern, length)
|
|
564
|
-
if (returnInstance) return nid
|
|
565
|
-
const value = nid()
|
|
566
|
-
return type === 'int' ? parseInt(value) : value
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* Get NPM global module directory
|
|
505
|
+
* Get NPM global module directory.
|
|
571
506
|
*
|
|
572
507
|
* @method
|
|
573
|
-
* @param {string} [pkgName] - If provided, return this package global directory. Otherwise the npm global module directory
|
|
574
|
-
* @param {boolean} [silent=true] - Set to ```false``` to throw exception in case of error. Otherwise silently returns undefined
|
|
508
|
+
* @param {string} [pkgName] - If provided, return this package global directory. Otherwise the npm global module directory.
|
|
509
|
+
* @param {boolean} [silent=true] - Set to ```false``` to throw exception in case of error. Otherwise silently returns undefined.
|
|
575
510
|
* @returns {string}
|
|
576
511
|
*/
|
|
577
512
|
getGlobalModuleDir = (pkgName, silent = true) => {
|
|
@@ -595,49 +530,30 @@ class Bajo extends Plugin {
|
|
|
595
530
|
}
|
|
596
531
|
|
|
597
532
|
/**
|
|
598
|
-
* Get class method by name
|
|
533
|
+
* Get class method by name.
|
|
599
534
|
*
|
|
600
535
|
* @method
|
|
601
|
-
* @param {string} name - Name in format ```ns:methodName
|
|
602
|
-
* @param {boolean} [thrown=true] - If ```true``` (default), throw
|
|
603
|
-
* @returns {function} Class method
|
|
536
|
+
* @param {string} name - Name in format ```ns:methodName```.
|
|
537
|
+
* @param {boolean} [thrown=true] - If ```true``` (default), throw exception in case of error.
|
|
538
|
+
* @returns {function} Class method.
|
|
604
539
|
*/
|
|
605
540
|
getMethod = (name = '', thrown = true) => {
|
|
606
|
-
const { ns, path } = this.breakNsPath(name)
|
|
541
|
+
const { ns, path } = this.breakNsPath(name, thrown)
|
|
607
542
|
const method = get(this.app, `${ns}.${path}`)
|
|
608
543
|
if (method && isFunction(method)) return method
|
|
609
544
|
if (thrown) throw this.error('cantFindMethod%s', name)
|
|
610
545
|
}
|
|
611
546
|
|
|
612
547
|
/**
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* @method
|
|
616
|
-
* @param {string} item - Item to find
|
|
617
|
-
* @param {Array} paths - Array of path to look for
|
|
618
|
-
* @returns {string}
|
|
619
|
-
*/
|
|
620
|
-
findDeep = (item, paths) => {
|
|
621
|
-
let dir
|
|
622
|
-
for (const p of paths) {
|
|
623
|
-
const d = `${p}/${item}`
|
|
624
|
-
if (fs.existsSync(d)) {
|
|
625
|
-
dir = d
|
|
626
|
-
break
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
return dir
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
/**
|
|
633
|
-
* Get module directory, locally and globally
|
|
548
|
+
* Get module directory, locally and globally.
|
|
634
549
|
*
|
|
635
550
|
* @method
|
|
636
|
-
* @param {string} pkgName - Package name to find
|
|
637
|
-
* @param {string} base - Provide base name if ```pkgName``` is a module under ```base```'s package name
|
|
638
|
-
* @returns {string} Return absolute package directory
|
|
551
|
+
* @param {string} pkgName - Package name to find.
|
|
552
|
+
* @param {string} base - Provide base name if ```pkgName``` is a module under ```base```'s package name.
|
|
553
|
+
* @returns {string} Return absolute package directory.
|
|
639
554
|
*/
|
|
640
555
|
getModuleDir = (pkgName, base) => {
|
|
556
|
+
const { findDeep } = this.app.lib
|
|
641
557
|
if (pkgName === 'main') return resolvePath(this.app.dir)
|
|
642
558
|
if (base === 'main') base = this.app.dir
|
|
643
559
|
else if (this && this.app && this.app[base]) base = this.app[base].pkgName
|
|
@@ -646,78 +562,12 @@ class Bajo extends Plugin {
|
|
|
646
562
|
const gdir = this.getGlobalModuleDir()
|
|
647
563
|
paths.unshift(gdir)
|
|
648
564
|
paths.unshift(resolvePath(path.join(this.app.dir, 'node_modules')))
|
|
649
|
-
let dir =
|
|
650
|
-
if (base && !dir) dir =
|
|
565
|
+
let dir = findDeep(pkgPath, paths)
|
|
566
|
+
if (base && !dir) dir = findDeep(`${base}/node_modules/${pkgPath}`, paths)
|
|
651
567
|
if (!dir) return null
|
|
652
568
|
return resolvePath(path.dirname(dir))
|
|
653
569
|
}
|
|
654
570
|
|
|
655
|
-
/**
|
|
656
|
-
* Get plugin data directory
|
|
657
|
-
*
|
|
658
|
-
* @method
|
|
659
|
-
* @param {string} name - Plugin name (namespace) or alias
|
|
660
|
-
* @param {boolean} [ensureDir=true] - Set ```true``` (default) to ensure directory is existed
|
|
661
|
-
* @returns {string}
|
|
662
|
-
*/
|
|
663
|
-
getPluginDataDir = (name, ensureDir = true) => {
|
|
664
|
-
const plugin = this.getPlugin(name)
|
|
665
|
-
const dir = `${this.app.bajo.dir.data}/plugins/${plugin.ns}`
|
|
666
|
-
if (ensureDir) fs.ensureDirSync(dir)
|
|
667
|
-
return dir
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* Resolve file path from:
|
|
672
|
-
*
|
|
673
|
-
* - local/absolute file
|
|
674
|
-
* - TNsPath (```myPlugin:/path/to/file.txt```)
|
|
675
|
-
*
|
|
676
|
-
* @method
|
|
677
|
-
* @param {string} file - File path, see above for supported types
|
|
678
|
-
* @returns {string} Resolved file path
|
|
679
|
-
*/
|
|
680
|
-
getPluginFile = (file) => {
|
|
681
|
-
if (!this) return file
|
|
682
|
-
if (file[0] === '.') file = `${currentLoc(import.meta).dir}/${trim(file.slice(1), '/')}`
|
|
683
|
-
if (file.includes(':')) {
|
|
684
|
-
if (file.slice(1, 2) === ':') return file // windows fs
|
|
685
|
-
const { ns, path } = this.breakNsPath(file)
|
|
686
|
-
if (ns !== 'file' && this && this.app && this.app[ns] && ns.length > 1) {
|
|
687
|
-
file = `${this.app[ns].dir.pkg}${path}`
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
return file
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* Get plugin by name
|
|
695
|
-
*
|
|
696
|
-
* @method
|
|
697
|
-
* @param {string} name - Plugin name/namespace or alias
|
|
698
|
-
* @param {boolean} [silent] - If ```true```, silently return undefined even on error
|
|
699
|
-
* @returns {Object} Plugin object
|
|
700
|
-
*/
|
|
701
|
-
getPlugin = (name, silent) => {
|
|
702
|
-
if (!this.app[name]) {
|
|
703
|
-
// alias?
|
|
704
|
-
let plugin
|
|
705
|
-
for (const key in this.app) {
|
|
706
|
-
const item = this.app[key]
|
|
707
|
-
if (item instanceof Plugin && (item.alias === name || item.pkgName === name)) {
|
|
708
|
-
plugin = item
|
|
709
|
-
break
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
if (!plugin) {
|
|
713
|
-
if (silent) return false
|
|
714
|
-
throw this.error('pluginWithNameAliasNotLoaded%s', name)
|
|
715
|
-
}
|
|
716
|
-
name = plugin.ns
|
|
717
|
-
}
|
|
718
|
-
return this.app[name]
|
|
719
|
-
}
|
|
720
|
-
|
|
721
571
|
/**
|
|
722
572
|
* Import file/module from any loaded plugins.
|
|
723
573
|
*
|
|
@@ -755,8 +605,8 @@ class Bajo extends Plugin {
|
|
|
755
605
|
*
|
|
756
606
|
* @method
|
|
757
607
|
* @async
|
|
758
|
-
* @param {...TNsPathPairs} pkgs - One or more packages in format ```{ns}:{packageName}
|
|
759
|
-
* @returns {(Object|Array)} See above
|
|
608
|
+
* @param {...TNsPathPairs} pkgs - One or more packages in format ```{ns}:{packageName}```.
|
|
609
|
+
* @returns {(Object|Array)} See above.
|
|
760
610
|
*/
|
|
761
611
|
importPkg = async (...pkgs) => {
|
|
762
612
|
const { defaultsDeep } = this.app.lib.aneka
|
|
@@ -789,7 +639,7 @@ class Bajo extends Plugin {
|
|
|
789
639
|
}
|
|
790
640
|
result[name] = mod
|
|
791
641
|
}
|
|
792
|
-
if (notFound.length > 0) throw this.error('cantFind%s', this.join(notFound))
|
|
642
|
+
if (notFound.length > 0 && opts.throwNotFound) throw this.error('cantFind%s', this.join(notFound))
|
|
793
643
|
if (opts.asObject) return result
|
|
794
644
|
if (pkgs.length === 1) return result[keys(result)[0]]
|
|
795
645
|
return values(result)
|
|
@@ -800,21 +650,21 @@ class Bajo extends Plugin {
|
|
|
800
650
|
*
|
|
801
651
|
* @method
|
|
802
652
|
* @async
|
|
803
|
-
* @param {(string|TNsPathPairs)} dir - Directory to check
|
|
653
|
+
* @param {(string|TNsPathPairs)} dir - Directory to check.
|
|
804
654
|
* @param {function} filterFn - Filter function to filter out files that cause false positives.
|
|
805
655
|
* @returns {boolean}
|
|
806
656
|
*/
|
|
807
657
|
isEmptyDir = async (dir, filterFn) => {
|
|
808
|
-
dir = resolvePath(this.getPluginFile(dir))
|
|
658
|
+
dir = resolvePath(this.app.getPluginFile(dir))
|
|
809
659
|
await fs.exists(dir)
|
|
810
660
|
return await emptyDir(dir, filterFn)
|
|
811
661
|
}
|
|
812
662
|
|
|
813
663
|
/**
|
|
814
|
-
* Check whether log level is within log's app current level
|
|
664
|
+
* Check whether log level is within log's app current level.
|
|
815
665
|
*
|
|
816
666
|
* @method
|
|
817
|
-
* @param {string} level - Level to check. See {@link TLogLevels} for more
|
|
667
|
+
* @param {string} level - Level to check. See {@link TLogLevels} for more.
|
|
818
668
|
* @returns {boolean}
|
|
819
669
|
*/
|
|
820
670
|
isLogInRange = (level) => {
|
|
@@ -838,11 +688,11 @@ class Bajo extends Plugin {
|
|
|
838
688
|
}
|
|
839
689
|
|
|
840
690
|
/**
|
|
841
|
-
* Check whether directory is a valid Bajo app
|
|
691
|
+
* Check whether directory is a valid Bajo app.
|
|
842
692
|
*
|
|
843
693
|
* @method
|
|
844
|
-
* @param {string} dir - Directory to check
|
|
845
|
-
* @param {boolean} [returnPkg] - Set ```true``` to return its package.json content
|
|
694
|
+
* @param {string} dir - Directory to check.
|
|
695
|
+
* @param {boolean} [returnPkg] - Set ```true``` to return its package.json content.
|
|
846
696
|
* @returns {(boolean|Object)}
|
|
847
697
|
*/
|
|
848
698
|
isValidApp = (dir, returnPkg) => {
|
|
@@ -851,11 +701,11 @@ class Bajo extends Plugin {
|
|
|
851
701
|
}
|
|
852
702
|
|
|
853
703
|
/**
|
|
854
|
-
* Check whether directory is a valid Bajo plugin
|
|
704
|
+
* Check whether directory is a valid Bajo plugin.
|
|
855
705
|
*
|
|
856
706
|
* @method
|
|
857
|
-
* @param {string} dir - Directory to check
|
|
858
|
-
* @param {boolean} [returnPkg] - Set ```true``` to return its package.json content
|
|
707
|
+
* @param {string} dir - Directory to check.
|
|
708
|
+
* @param {boolean} [returnPkg] - Set ```true``` to return its package.json content.
|
|
859
709
|
* @returns {(boolean|Object)}
|
|
860
710
|
*/
|
|
861
711
|
isValidPlugin = (dir, returnPkg) => {
|
|
@@ -868,31 +718,31 @@ class Bajo extends Plugin {
|
|
|
868
718
|
*
|
|
869
719
|
* @method
|
|
870
720
|
* @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
|
|
721
|
+
* @param {(string|Object)} options - If provided and is a string, it will be used as separator.
|
|
722
|
+
* @param {string} [options.separator=', '] - Separator to use.
|
|
723
|
+
* @param {string} [options.lastSeparator=and] - Text to use as the last separator.
|
|
874
724
|
* @returns {string}
|
|
875
725
|
*/
|
|
876
|
-
join = (
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
726
|
+
join = (input = [], options = {}) => {
|
|
727
|
+
const array = [...input]
|
|
728
|
+
if (isString(options)) options = { separator: options }
|
|
729
|
+
let { separator = ', ', lastSeparator = 'and', lang } = options
|
|
730
|
+
const translate = (val) => {
|
|
731
|
+
return this.t(val, { lang }).toLowerCase()
|
|
880
732
|
}
|
|
881
733
|
if (array.length === 0) return translate('none')
|
|
882
734
|
if (array.length === 1) return array[0]
|
|
883
|
-
if (isSet(options) && !isPlainObject(options)) return array.join(options)
|
|
884
|
-
let { separator = ', ', lastSeparator = 'and' } = options ?? {}
|
|
885
735
|
lastSeparator = translate(lastSeparator)
|
|
886
736
|
const last = (array.pop() ?? '').trim()
|
|
887
737
|
return array.map(a => (a + '').trim()).join(separator) + ` ${lastSeparator} ${last}`
|
|
888
738
|
}
|
|
889
739
|
|
|
890
740
|
/**
|
|
891
|
-
* Return its numeric portion of a value
|
|
741
|
+
* Return its numeric portion of a value.
|
|
892
742
|
*
|
|
893
743
|
* @method
|
|
894
|
-
* @param {string} [value=''] - Value to get its numeric portion
|
|
895
|
-
* @param {string} [defUnit=''] - Default unit if value doesn't have one
|
|
744
|
+
* @param {string} [value=''] - Value to get its numeric portion.
|
|
745
|
+
* @param {string} [defUnit=''] - Default unit if value doesn't have one.
|
|
896
746
|
* @returns {string}
|
|
897
747
|
*/
|
|
898
748
|
numUnit = (value = '', defUnit = '') => {
|
|
@@ -902,155 +752,117 @@ class Bajo extends Plugin {
|
|
|
902
752
|
}
|
|
903
753
|
|
|
904
754
|
/**
|
|
905
|
-
*
|
|
906
|
-
*
|
|
907
|
-
* @method
|
|
908
|
-
* @param {(number|string)} dur - If string is given, parse this to its millisecond value. Otherwise returns as is
|
|
909
|
-
* @returns {number}
|
|
910
|
-
* @see {@link https://github.com/vercel/ms|ms}
|
|
911
|
-
*/
|
|
912
|
-
parseDur = (dur) => {
|
|
913
|
-
return isNumber(dur) ? dur : ms(dur)
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
/**
|
|
917
|
-
* Parse datetime string as Javascript date object. Please visit {@link https://day.js.org|dayjs} for valid formats and more infos
|
|
918
|
-
*
|
|
919
|
-
* @method
|
|
920
|
-
* @param {string} dt - Datetime string
|
|
921
|
-
* @returns {Object} Javascript date object
|
|
922
|
-
* @see {@link https://day.js.org|dayjs}
|
|
923
|
-
*/
|
|
924
|
-
parseDt = (dt) => {
|
|
925
|
-
const value = this.app.lib.dayjs(dt)
|
|
926
|
-
if (!value.isValid()) throw this.error('dtUnparsable%s', dt)
|
|
927
|
-
return value.toDate()
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
/**
|
|
931
|
-
* Parse an object and optionally normalize its values recursively. Use {@link https://github.com/ladjs/dotenv-parse-variables}
|
|
932
|
-
* to parse values, so please have a visit to know how it works
|
|
755
|
+
* Read and parse file as config object. Supported types: ```.js``` and ```.json```.
|
|
756
|
+
* More supports can be added using plugin. {@link https://github.com/ardhi/bajo-config|bajo-config} gives you additional supports for ```.yml```, ```.yaml``` and ```.toml``` file.
|
|
933
757
|
*
|
|
934
|
-
* If
|
|
935
|
-
* also be parsed as millisecond and Javascript date time accordingly.
|
|
758
|
+
* If file extension is ```.*```, it will be auto detected and parsed accordingly
|
|
936
759
|
*
|
|
937
760
|
* @method
|
|
938
|
-
* @
|
|
939
|
-
* @param {
|
|
940
|
-
* @param {
|
|
941
|
-
* @param {boolean} [options.
|
|
942
|
-
* @param {string} [options.
|
|
761
|
+
* @async
|
|
762
|
+
* @param {string} file - File to read and parse.
|
|
763
|
+
* @param {Object} [options={}] - Options.
|
|
764
|
+
* @param {boolean} [options.ignoreError] - Any exception will be silently discarded.
|
|
765
|
+
* @param {string} [options.ns] - If given, use this as the scope.
|
|
766
|
+
* @param {string} [options.pattern] - If given and auto detection is on (extension is ```.*```), it will be used for instead the default one.
|
|
767
|
+
* @param {Object} [options.defValue={}] - Default value to use if value returned empty.
|
|
768
|
+
* @param {Object} [options.parserOpts={}] - Parser setting.
|
|
769
|
+
* @param {Object} [options.globOpts={}] - {@link https://github.com/mrmlnc/fast-glob|fast-glob} options.
|
|
943
770
|
* @returns {Object}
|
|
944
|
-
* @see {@link https://github.com/ladjs/dotenv-parse-variables}
|
|
945
771
|
*/
|
|
946
|
-
|
|
947
|
-
const {
|
|
948
|
-
const {
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
772
|
+
readConfig = async (file, options = {}) => {
|
|
773
|
+
const { parseObject } = this.app.lib
|
|
774
|
+
const { defaultsDeep } = this.app.lib.aneka
|
|
775
|
+
const { uniq, isString, isArray, findIndex, isPlainObject, merge } = this.app.lib._
|
|
776
|
+
let { ns, baseNs, extend, checkOverride, merge: merged, pattern, ignoreError = true, defValue = {}, parserOpts = {}, globOpts = {}, handler, cache = {} } = options
|
|
777
|
+
|
|
778
|
+
const getParseOptsArgs = (opts, orig) => {
|
|
779
|
+
opts.parserOpts = opts.parserOpts ?? {}
|
|
780
|
+
opts.parserOpts.args = opts.parserOpts.args ?? []
|
|
781
|
+
const idx = findIndex(opts.parserOpts.args, item => {
|
|
782
|
+
return isPlainObject(item) && Object.keys(item)[0] === '_orig'
|
|
783
|
+
})
|
|
784
|
+
if (idx > -1) opts.parserOpts.args[idx] = { _orig: orig }
|
|
785
|
+
else opts.parserOpts.args.push({ _orig: orig })
|
|
953
786
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
if (
|
|
960
|
-
|
|
787
|
+
|
|
788
|
+
const output = async (obj) => {
|
|
789
|
+
let orig = parseObject(obj)
|
|
790
|
+
if (!baseNs || extend === false) {
|
|
791
|
+
await this.runHook('bajo:afterReadConfig', file, orig, options)
|
|
792
|
+
if (cache.name) await this.app.cache.save(cache.name, orig, cache.ttlDur)
|
|
793
|
+
return orig
|
|
961
794
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
let
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
else obj[newK] = v
|
|
984
|
-
mutated.push(k)
|
|
985
|
-
} else if (parseValue) {
|
|
986
|
-
obj[k] = dotenvParseVariables(set({}, 'item', v), { assignToProcessEnv: false }).item
|
|
987
|
-
if (isArray(obj[k])) obj[k] = obj[k].map(item => typeof item === 'string' ? item.trim() : item)
|
|
988
|
-
}
|
|
989
|
-
if (k.slice(-3) === 'Dur') obj[k] = this.parseDur(v)
|
|
990
|
-
if (k.slice(-2) === 'Dt') obj[k] = this.parseDt(v)
|
|
991
|
-
} catch (err) {
|
|
992
|
-
obj[k] = undefined
|
|
993
|
-
if (!silent) throw err
|
|
994
|
-
}
|
|
795
|
+
const { suffix = '', keys = [] } = options
|
|
796
|
+
let bases = this.app.getAllNs()
|
|
797
|
+
if (isString(extend)) extend = extend.split(',').map(i => i.trim)
|
|
798
|
+
if (isArray(extend)) bases = [...extend, 'main']
|
|
799
|
+
bases = uniq(bases)
|
|
800
|
+
let ext = isArray(orig) ? [] : {}
|
|
801
|
+
const dir = this.app[ns].dir.pkg
|
|
802
|
+
let [names, _path] = file.split(':')
|
|
803
|
+
if (file.slice(0, names.length + 1) !== `${ns}:`) _path = file.slice(dir.length + 1)
|
|
804
|
+
if (_path.startsWith('extend/')) _path = _path.slice(7)
|
|
805
|
+
if (_path.startsWith(`${baseNs}/`)) _path = _path.slice(baseNs.length + 1)
|
|
806
|
+
_path = _path.slice(0, -(path.extname(_path).length)) + '.*'
|
|
807
|
+
// check for override? Override only exists in main plugin
|
|
808
|
+
const opts = omit(options, ['suffix', 'keys', 'extend'])
|
|
809
|
+
if (checkOverride) {
|
|
810
|
+
getParseOptsArgs(opts, orig)
|
|
811
|
+
const fileExt = `${this.app.main.dir.pkg}/extend/${baseNs}/override/${ns}${suffix}/${_path}`
|
|
812
|
+
await this.runHook('bajo.override:beforeReadConfig', fileExt, options)
|
|
813
|
+
const result = parseObject(await this.readConfig(fileExt, { ...opts, extend: false, checkOverride: false, merge: false }))
|
|
814
|
+
await this.runHook('bajo.override:afterReadConfig', fileExt, result, options)
|
|
815
|
+
if (!isEmpty(result)) orig = result
|
|
995
816
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
817
|
+
getParseOptsArgs(opts, orig)
|
|
818
|
+
const binder = merged ? merge : defaultsDeep
|
|
819
|
+
for (const base of bases) {
|
|
820
|
+
if (!this.app[base]) continue
|
|
821
|
+
options.sourceNs = base
|
|
822
|
+
const fileExt = `${this.app[base].dir.pkg}/extend/${baseNs}/extend/${ns}${suffix}/${_path}`
|
|
823
|
+
await this.runHook('bajo.extend:beforeReadConfig', fileExt, options)
|
|
824
|
+
const result = parseObject(await this.readConfig(fileExt, { ...opts, extend: false, merge: false }))
|
|
825
|
+
await this.runHook('bajo.extend:afterReadConfig', fileExt, result, options)
|
|
826
|
+
if (isEmpty(result)) continue
|
|
827
|
+
if (isArray(result)) ext = [...result, ...ext]
|
|
828
|
+
else ext = binder({}, result, ext)
|
|
829
|
+
}
|
|
830
|
+
delete options.sourceNs
|
|
831
|
+
let result = isArray(orig) ? [...orig, ...ext] : binder({}, keys.length > 0 ? pick(ext, keys) : ext, orig)
|
|
832
|
+
if (handler) result = await this.callHandler(this.app[ns], handler, result)
|
|
833
|
+
await this.runHook('bajo:afterReadConfig', file, result, options)
|
|
834
|
+
if (cache.name) await this.app.cache.save(cache.name, result, cache.ttlDur)
|
|
835
|
+
return result
|
|
1008
836
|
}
|
|
1009
|
-
return result
|
|
1010
|
-
}
|
|
1011
837
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
*
|
|
1018
|
-
* @method
|
|
1019
|
-
* @async
|
|
1020
|
-
* @param {string} file - File to read and parse
|
|
1021
|
-
* @param {Object} [options={}] - Options
|
|
1022
|
-
* @param {boolean} [options.ignoreError] - Any exception will be silently discarded
|
|
1023
|
-
* @param {string} [options.ns] - If given, use this as the scope
|
|
1024
|
-
* @param {string} [options.pattern] - If given and auto detection is on (extension is ```.*```), it will be used for instead the default one
|
|
1025
|
-
* @param {Object} [options.globOptions={}] - {@link https://github.com/mrmlnc/fast-glob|fast-glob} options
|
|
1026
|
-
* @param {Object} [options.defValue={}] - Default value to use if value returned empty
|
|
1027
|
-
* @param {Object} [options.opts={}] - Parser setting
|
|
1028
|
-
* @returns {Object}
|
|
1029
|
-
*/
|
|
1030
|
-
readConfig = async (file, { ns, pattern, globOptions = {}, ignoreError, defValue = {}, opts = {} } = {}) => {
|
|
838
|
+
let result
|
|
839
|
+
if (cache.name) result = await this.app.cache.load(cache.name, cache.ttlDur)
|
|
840
|
+
if (result) return result
|
|
841
|
+
await this.runHook('bajo:beforeReadConfig', file, options)
|
|
842
|
+
parserOpts.readFromFile = true
|
|
1031
843
|
if (!ns) ns = this.ns
|
|
1032
|
-
file = resolvePath(this.getPluginFile(file))
|
|
844
|
+
file = resolvePath(this.app.getPluginFile(file))
|
|
1033
845
|
let ext = path.extname(file)
|
|
1034
846
|
const fname = path.dirname(file) + '/' + path.basename(file, ext)
|
|
1035
847
|
ext = ext.toLowerCase()
|
|
1036
848
|
if (ext === '.js') {
|
|
1037
849
|
const { readHandler } = find(this.app.configHandlers, { ext })
|
|
1038
|
-
return
|
|
850
|
+
return await output(await readHandler.call(this.app[ns], file, parserOpts))
|
|
1039
851
|
}
|
|
1040
|
-
if (ext === '.json') return await this.fromJson(file,
|
|
852
|
+
if (ext === '.json') return await output(await this.fromJson(file, parserOpts))
|
|
1041
853
|
if (!['', '.*'].includes(ext)) {
|
|
1042
854
|
const item = find(this.app.configHandlers, { ext })
|
|
1043
855
|
if (!item) {
|
|
1044
856
|
if (!ignoreError) throw this.error('cantParse%s', file, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
1045
|
-
return
|
|
857
|
+
return await output(defValue)
|
|
1046
858
|
}
|
|
1047
|
-
return
|
|
859
|
+
return await output(await item.readHandler.call(this.app[ns], file, parserOpts))
|
|
1048
860
|
}
|
|
1049
861
|
const item = pattern ?? `${fname}.{${map(map(this.app.configHandlers, 'ext'), k => k.slice(1)).join(',')}}`
|
|
1050
|
-
const files = await fastGlob(item,
|
|
862
|
+
const files = await fastGlob(item, globOpts ?? {})
|
|
1051
863
|
if (files.length === 0) {
|
|
1052
864
|
if (!ignoreError) throw this.error('noConfigFileFound', { code: 'BAJO_CONFIG_FILE_NOT_FOUND' })
|
|
1053
|
-
return
|
|
865
|
+
return await output(defValue)
|
|
1054
866
|
}
|
|
1055
867
|
let config = defValue
|
|
1056
868
|
for (const f of files) {
|
|
@@ -1060,21 +872,22 @@ class Bajo extends Plugin {
|
|
|
1060
872
|
if (!ignoreError) throw this.error('cantParse%s', f, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
1061
873
|
continue
|
|
1062
874
|
}
|
|
1063
|
-
config = await item.readHandler.call(this.app[ns], f,
|
|
875
|
+
config = await item.readHandler.call(this.app[ns], f, parserOpts)
|
|
1064
876
|
if (!isEmpty(config)) break
|
|
1065
877
|
}
|
|
1066
|
-
return
|
|
878
|
+
return await output(config)
|
|
1067
879
|
}
|
|
1068
880
|
|
|
1069
881
|
/**
|
|
1070
|
-
* Read and parse json file
|
|
882
|
+
* Read and parse json file.
|
|
1071
883
|
*
|
|
1072
884
|
* @method
|
|
1073
|
-
* @param {string} file - File to read
|
|
1074
|
-
* @param {boolean} [thrownNotFound=false] - If ```true```, silently ignore if file is not found
|
|
885
|
+
* @param {string} file - File to read.
|
|
886
|
+
* @param {boolean} [thrownNotFound=false] - If ```true```, silently ignore if file is not found.
|
|
1075
887
|
* @returns {Object}
|
|
1076
888
|
*/
|
|
1077
889
|
readJson = (file, thrownNotFound = false) => {
|
|
890
|
+
const { parseObject } = this.app.lib
|
|
1078
891
|
if (isPlainObject(thrownNotFound)) thrownNotFound = false
|
|
1079
892
|
if (!fs.existsSync(file) && thrownNotFound) throw this.error('notFound%s%s', this.t('file'), file)
|
|
1080
893
|
let resp
|
|
@@ -1082,40 +895,78 @@ class Bajo extends Plugin {
|
|
|
1082
895
|
resp = fs.readFileSync(file, 'utf8')
|
|
1083
896
|
} catch (err) {}
|
|
1084
897
|
if (isEmpty(resp)) return resp
|
|
1085
|
-
return
|
|
898
|
+
return parseObject(JSON.parse(resp))
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Read and parse JavaScript file.
|
|
903
|
+
*
|
|
904
|
+
* @async
|
|
905
|
+
* @method
|
|
906
|
+
* @param {string} file - File to read and parse.
|
|
907
|
+
* @param {Object} [options={}] - Options.
|
|
908
|
+
* @returns {Object} Parsed JavaScript object.
|
|
909
|
+
*/
|
|
910
|
+
async fromJs (file, options = {}) {
|
|
911
|
+
const args = options.args ?? []
|
|
912
|
+
let mod = await importModule(file)
|
|
913
|
+
if (isFunction(mod)) mod = await mod.call(this, ...args)
|
|
914
|
+
return mod
|
|
1086
915
|
}
|
|
1087
916
|
|
|
1088
|
-
|
|
1089
|
-
|
|
917
|
+
/**
|
|
918
|
+
* Read and parse JSON string or object.
|
|
919
|
+
*
|
|
920
|
+
* @param {string} data - Filename to load from or JSON string to parse.
|
|
921
|
+
* @param {Object} [options={}] - Options.
|
|
922
|
+
* @returns {Object} Parsed JSON object.
|
|
923
|
+
*/
|
|
924
|
+
fromJson (data, options = {}) {
|
|
925
|
+
const content = options.readFromFile ? fs.readFileSync(data, 'utf8') : data
|
|
1090
926
|
return JSON.parse(content)
|
|
1091
927
|
}
|
|
1092
928
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
929
|
+
/**
|
|
930
|
+
* Convert data to JSON string.
|
|
931
|
+
*
|
|
932
|
+
* @method
|
|
933
|
+
* @param {Object} data - Data to convert to JSON string.
|
|
934
|
+
* @param {Object} [options={}] - Options.
|
|
935
|
+
* @param {boolean} [options.writeToFile=false] - If true, write the JSON string to a file.
|
|
936
|
+
* @param {string} [options.saveAsFile] - The file path to save the JSON string if writeToFile is true.
|
|
937
|
+
* @returns {string} JSON string
|
|
938
|
+
*/
|
|
939
|
+
toJson = (data, options = {}) => {
|
|
940
|
+
const content = JSON.stringify(data, null, omit(options, ['writeToFile']))
|
|
941
|
+
if (options.writeToFile) {
|
|
942
|
+
fs.writeFileSync(options.saveAsFile, content, 'utf8')
|
|
943
|
+
return
|
|
944
|
+
}
|
|
945
|
+
return content
|
|
1096
946
|
}
|
|
1097
947
|
|
|
1098
948
|
/**
|
|
1099
|
-
* Read all config files
|
|
949
|
+
* Read all config files from path.
|
|
1100
950
|
*
|
|
1101
951
|
* @method
|
|
1102
952
|
* @async
|
|
1103
|
-
* @param {string} path - Base path to start looking config files
|
|
1104
|
-
* @
|
|
953
|
+
* @param {string} path - Base path to start looking config files.
|
|
954
|
+
* @param {Object} [options={}] - Options.
|
|
955
|
+
* @returns {Object} Merged configuration object.
|
|
1105
956
|
*/
|
|
1106
|
-
readAllConfigs = async (path) => {
|
|
957
|
+
readAllConfigs = async (path, options) => {
|
|
1107
958
|
const { defaultsDeep } = this.app.lib.aneka
|
|
1108
959
|
let cfg = {}
|
|
1109
960
|
let ext = {}
|
|
1110
961
|
// default config file
|
|
1111
962
|
try {
|
|
1112
|
-
cfg = await this.readConfig(`${path}.*`,
|
|
963
|
+
cfg = await this.readConfig(`${path}.*`, options)
|
|
1113
964
|
} catch (err) {
|
|
1114
965
|
if (['BAJO_CONFIG_NO_PARSER'].includes(err.code)) throw err
|
|
1115
966
|
}
|
|
1116
967
|
// env based config file
|
|
1117
968
|
try {
|
|
1118
|
-
ext = await this.readConfig(`${path}-${this.config.env}.*`,
|
|
969
|
+
ext = await this.readConfig(`${path}-${this.config.env}.*`, options)
|
|
1119
970
|
} catch (err) {
|
|
1120
971
|
if (!['BAJO_CONFIG_FILE_NOT_FOUND'].includes(err.code)) throw err
|
|
1121
972
|
}
|
|
@@ -1123,29 +974,30 @@ class Bajo extends Plugin {
|
|
|
1123
974
|
}
|
|
1124
975
|
|
|
1125
976
|
/**
|
|
1126
|
-
* Run named hook/event
|
|
977
|
+
* Run named hook/event.
|
|
1127
978
|
*
|
|
1128
979
|
* @method
|
|
1129
980
|
* @async
|
|
1130
|
-
* @param {TNsPathPairs} hookName
|
|
1131
|
-
* @param
|
|
1132
|
-
* @returns {Array} Array of hook execution results
|
|
981
|
+
* @param {TNsPathPairs} hookName - Name of the hook to run.
|
|
982
|
+
* @param {...any} [args] - Argument passed to the hook function.
|
|
983
|
+
* @returns {Array} Array of hook execution results.
|
|
1133
984
|
*/
|
|
1134
985
|
runHook = async (hookName, ...args) => {
|
|
1135
|
-
|
|
1136
|
-
let fns = filter(this.app.bajo.hooks, { ns, path })
|
|
986
|
+
let fns = filter(this.hooks, { name: hookName })
|
|
1137
987
|
if (isEmpty(fns)) return []
|
|
1138
988
|
fns = orderBy(fns, ['level'])
|
|
1139
989
|
const results = []
|
|
1140
990
|
for (const i in fns) {
|
|
1141
991
|
const fn = fns[i]
|
|
1142
|
-
const scope = this.app[fn.src]
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
992
|
+
const scope = this.app[fn.src ?? 'main'] ?? this
|
|
993
|
+
if (fn.noWait) fn.handler.call(scope, ...args)
|
|
994
|
+
else {
|
|
995
|
+
const res = await fn.handler.call(scope, ...args)
|
|
996
|
+
results.push({
|
|
997
|
+
hook: hookName,
|
|
998
|
+
resp: res
|
|
999
|
+
})
|
|
1000
|
+
}
|
|
1149
1001
|
}
|
|
1150
1002
|
return results
|
|
1151
1003
|
}
|
|
@@ -1159,14 +1011,14 @@ class Bajo extends Plugin {
|
|
|
1159
1011
|
*
|
|
1160
1012
|
* @method
|
|
1161
1013
|
* @async
|
|
1162
|
-
* @param {string} file - File name
|
|
1163
|
-
* @param {Object} item - Item to save
|
|
1164
|
-
* @param {boolean} [printSaved=true] - Print info on screen
|
|
1165
|
-
* @returns {string} Full file path
|
|
1014
|
+
* @param {string} file - File name.
|
|
1015
|
+
* @param {Object} item - Item to save.
|
|
1016
|
+
* @param {boolean} [printSaved=true] - Print info on screen.
|
|
1017
|
+
* @returns {string} Full file path.
|
|
1166
1018
|
*/
|
|
1167
1019
|
saveAsDownload = async (file, item, printSaved = true) => {
|
|
1168
|
-
const { print
|
|
1169
|
-
const fname = increment(`${getPluginDataDir(this.ns)}/download/${trim(file, '/')}`, { fs: true })
|
|
1020
|
+
const { print } = this.app.bajo
|
|
1021
|
+
const fname = increment(`${this.app.getPluginDataDir(this.ns)}/download/${trim(file, '/')}`, { fs: true })
|
|
1170
1022
|
const dir = path.dirname(fname)
|
|
1171
1023
|
if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
|
|
1172
1024
|
await fs.writeFile(fname, item, 'utf8')
|
|
@@ -1176,4 +1028,4 @@ class Bajo extends Plugin {
|
|
|
1176
1028
|
}
|
|
1177
1029
|
|
|
1178
1030
|
export default Bajo
|
|
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:
|
|
1031
|
+
</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-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: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 class="sidebar-section-children"><a href="module-Helper%257Bns%257D_afterAppletRun.html">Helper{ns}:afterAppletRun</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-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#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>
|