bajo 2.22.0 → 2.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsdoc.conf.json +2 -1
- package/class/app.js +220 -107
- package/class/bajo.js +258 -177
- package/class/base.js +85 -24
- package/class/cache.js +8 -16
- package/class/err.js +31 -10
- package/class/log.js +46 -38
- package/class/plugin.js +53 -30
- package/class/print.js +18 -15
- package/class/tools.js +6 -5
- package/docs/App.html +51 -1
- package/docs/Bajo.html +1 -1
- package/docs/Base.html +34 -1
- package/docs/Cache.html +1 -1
- package/docs/Err.html +2 -2
- package/docs/Log.html +2 -2
- package/docs/Main.html +3 -0
- package/docs/Plugin.html +1 -1
- package/docs/Print.html +1 -1
- package/docs/Tools.html +1 -1
- package/docs/class_app.js.html +222 -109
- package/docs/class_bajo.js.html +260 -179
- package/docs/class_base.js.html +87 -26
- package/docs/class_cache.js.html +10 -18
- package/docs/class_err.js.html +33 -12
- package/docs/class_log.js.html +48 -40
- package/docs/class_plugin.js.html +55 -32
- package/docs/class_print.js.html +20 -17
- package/docs/class_tools.js.html +8 -7
- package/docs/data/search.json +1 -1
- package/docs/extend_bajo_hook.js.html +289 -0
- package/docs/global.html +22 -1
- package/docs/index.html +1 -1
- package/docs/index.js.html +53 -16
- package/docs/lib_applet-hook.js.html +328 -0
- package/docs/lib_config.js.html +167 -0
- package/docs/lib_helper.js.html +186 -192
- package/docs/module-Applet.html +3 -0
- package/docs/module-Helper-Main.html +3 -0
- package/docs/module-Helper.html +1 -8
- package/docs/module-Hook.html +1 -1
- package/docs/tutorial-01_WELCOME.html +3 -0
- package/docs/tutorial-02_GETTING_STARTED.html +125 -0
- package/docs/tutorial-03_USER_GUIDE.html +54 -0
- package/docs/tutorial-04_DEV_GUIDE.html +178 -0
- package/docs/tutorial-05_ECOSYSTEM.html +3 -0
- package/extend/bajo/intl/en-US.json +2 -1
- package/extend/bajo/intl/id.json +2 -1
- package/index.js +51 -14
- package/lib/applet-hook.js +325 -0
- package/lib/config.js +164 -0
- package/lib/helper.js +184 -190
- package/package.json +6 -2
- package/test/00-global-hooks.test.js +44 -0
- package/test/e2e/_run.js +19 -0
- package/test/e2e/e2e-applet-process.test.js +66 -0
- package/test/e2e/e2e-boot-process.test.js +62 -0
- package/test/e2e/e2e-hooks-process.test.js +68 -0
- package/test/integration/_setup.js +55 -0
- package/test/integration/aspect-01-boot-instance.test.js +24 -0
- package/test/integration/aspect-02-plugin-loading.test.js +24 -0
- package/test/integration/aspect-03-config-merge.test.js +27 -0
- package/test/integration/aspect-04-intl-loading.test.js +29 -0
- package/test/integration/aspect-05-cache-roundtrip.test.js +26 -0
- package/test/integration/aspect-06-log-file-save.test.js +28 -0
- package/test/integration/aspect-07-plugin-data-dir.test.js +25 -0
- package/test/integration/aspect-08-plugin-lookup.test.js +25 -0
- package/test/integration/aspect-09-config-formats.test.js +26 -0
- package/test/integration/aspect-10-hooks.test.js +38 -0
- package/test/unit/app.test.js +115 -0
- package/test/unit/applet-hook.test.js +10 -0
- package/test/unit/bajo.test.js +151 -0
- package/test/unit/base.test.js +90 -0
- package/test/unit/cache.test.js +89 -0
- package/test/unit/config.test.js +14 -0
- package/test/unit/err.test.js +57 -0
- package/test/unit/helper.test.js +116 -0
- package/test/unit/index.test.js +40 -0
- package/test/unit/log.test.js +84 -0
- package/test/unit/plugin.test.js +95 -0
- package/test/unit/print.test.js +72 -0
- package/test/unit/tools.test.js +29 -0
- package/wiki/CHANGES.md +9 -0
- package/wiki/tutorials/01_WELCOME.md +18 -0
- package/wiki/tutorials/02_GETTING_STARTED.md +366 -0
- package/wiki/tutorials/03_USER_GUIDE.md +262 -0
- package/wiki/tutorials/04_DEV_GUIDE.md +386 -0
- package/wiki/tutorials/05_ECOSYSTEM.md +95 -0
- package/wiki/tutorials/tutorials.json +17 -0
- package/lib/hook.js +0 -228
- package/test/app.test.js +0 -183
- package/test/bajo.test.js +0 -124
- package/test/base.test.js +0 -75
- package/test/cache.test.js +0 -94
- package/test/e2e.test.js +0 -137
- package/test/err.test.js +0 -73
- package/test/helper.test.js +0 -39
- package/test/import-module.test.js +0 -138
- package/test/integration.test.js +0 -218
- package/test/log.test.js +0 -119
- package/test/plugin.test.js +0 -116
- package/test/print.test.js +0 -100
- package/test/tools.test.js +0 -38
- package/wiki/CONFIG.md +0 -36
- package/wiki/DEV_GUIDE.md +0 -3
- package/wiki/ECOSYSTEM.md +0 -93
- package/wiki/GETTING-STARTED.md +0 -356
- package/wiki/USER-GUIDE.md +0 -256
package/docs/class_bajo.js.html
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: class/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="Cache.html">Cache</a></div><div class="sidebar-section-children"><a href="Err.html">Err</a></div><div class="sidebar-section-children"><a href="Log.html">Log</a></div><div class="sidebar-section-children"><a href="Plugin.html">Plugin</a></div><div class="sidebar-section-children"><a href="Print.html">Print</a></div><div class="sidebar-section-children"><a href="Tools.html">Tools</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div><div class="sidebar-section-children"><a href="module-Hook.html">Hook</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#boot">boot</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/bajo" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/bajo" target="">Github</a></div><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">class_bajo.js</h1></header><article><pre class="prettyprint source lang-js"><code>import Tools from './tools.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-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-01_WELCOME.html">Welcome</a></div><div class="sidebar-section-children"><a href="tutorial-02_GETTING_STARTED.html">Getting Started</a></div><div class="sidebar-section-children"><a href="tutorial-03_USER_GUIDE.html">User Guide</a></div><div class="sidebar-section-children"><a href="tutorial-04_DEV_GUIDE.html">Developer Guide</a></div><div class="sidebar-section-children"><a href="tutorial-05_ECOSYSTEM.html">Ecosystem</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="App.html">App</a></div><div class="sidebar-section-children"><a href="Bajo.html">Bajo</a></div><div class="sidebar-section-children"><a href="Base.html">Base</a></div><div class="sidebar-section-children"><a href="Cache.html">Cache</a></div><div class="sidebar-section-children"><a href="Err.html">Err</a></div><div class="sidebar-section-children"><a href="Log.html">Log</a></div><div class="sidebar-section-children"><a href="Main.html">Main</a></div><div class="sidebar-section-children"><a href="Plugin.html">Plugin</a></div><div class="sidebar-section-children"><a href="Print.html">Print</a></div><div class="sidebar-section-children"><a href="Tools.html">Tools</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-Applet.html">Applet</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div><div class="sidebar-section-children"><a href="module-Hook.html">Hook</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#boot">boot</a></div><div class="sidebar-section-children"><a href="global.html#package%25C2%25B7json">package·json</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/bajo" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/bajo" target="">Github</a></div><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">class_bajo.js</h1></header><article><pre class="prettyprint source lang-js"><code>import Tools from './tools.js'
|
|
4
4
|
import Plugin from './plugin.js'
|
|
5
5
|
import increment from 'add-filename-increment'
|
|
6
6
|
import fs from 'fs-extra'
|
|
@@ -15,11 +15,14 @@ import * as yaml from 'js-yaml'
|
|
|
15
15
|
import aneka from 'aneka'
|
|
16
16
|
import {
|
|
17
17
|
buildBaseConfig,
|
|
18
|
-
|
|
18
|
+
buildConfig,
|
|
19
19
|
buildPlugins,
|
|
20
20
|
collectConfigHandlers,
|
|
21
21
|
bootOrder,
|
|
22
|
-
|
|
22
|
+
checkNameAliases,
|
|
23
|
+
checkDependencies,
|
|
24
|
+
collectHooks,
|
|
25
|
+
runPlugins,
|
|
23
26
|
exitHandler,
|
|
24
27
|
importModule,
|
|
25
28
|
types as formatTypes,
|
|
@@ -29,20 +32,20 @@ import {
|
|
|
29
32
|
const require = createRequire(import.meta.url)
|
|
30
33
|
|
|
31
34
|
const {
|
|
32
|
-
isFunction, map, isObject,
|
|
35
|
+
isFunction, map, isObject, findIndex, uniq, merge,
|
|
33
36
|
trim, filter, isEmpty, orderBy, pullAt, find, camelCase,
|
|
34
37
|
cloneDeep, isPlainObject, isArray, isString, omit, keys, indexOf,
|
|
35
|
-
last, get, has, values, pick
|
|
38
|
+
last, get, has, values, pick, isBoolean
|
|
36
39
|
} = lodash
|
|
37
40
|
|
|
38
|
-
const { resolvePath, getGlobalModuleDir } = aneka
|
|
41
|
+
const { resolvePath, getGlobalModuleDir, defaultsDeep, isSet, parseObject } = aneka
|
|
39
42
|
|
|
40
43
|
/**
|
|
41
|
-
* Name
|
|
44
|
+
* Name in `{ns}:{path}` format.
|
|
42
45
|
*
|
|
43
46
|
* @typedef {string} TNsPathPairs
|
|
44
47
|
* @memberof Bajo
|
|
45
|
-
* @see TNsPathResult
|
|
48
|
+
* @see Bajo.TNsPathResult
|
|
46
49
|
* @see Bajo#buildNsPath
|
|
47
50
|
* @see Bajo#breakNsPath
|
|
48
51
|
*/
|
|
@@ -58,23 +61,30 @@ const { resolvePath, getGlobalModuleDir } = aneka
|
|
|
58
61
|
*/
|
|
59
62
|
|
|
60
63
|
/**
|
|
61
|
-
* Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath}.
|
|
64
|
+
* Object returned by {@link Bajo#breakNsPath|bajo:breakNsPath()}.
|
|
62
65
|
*
|
|
63
66
|
* @typedef {Object} TNsPathResult
|
|
64
67
|
* @memberof Bajo
|
|
65
|
-
* @property {string} ns - Namespace
|
|
68
|
+
* @property {string} [ns] - Namespace
|
|
66
69
|
* @property {string} [subNs] - Sub namespace
|
|
67
70
|
* @property {string} [subSubNs] - Sub of sub namespace
|
|
71
|
+
* @property {string} [fullNs] - Full namespace, including sub namespaces
|
|
68
72
|
* @property {string} path - Path without query string or hash
|
|
69
|
-
* @property {string} fullPath - Full path, including query string and hash
|
|
70
|
-
* @
|
|
73
|
+
* @property {string} [fullPath] - Full path, including query string and hash
|
|
74
|
+
* @property {string} [realPath] - Path without query string or hash, but with parameters replaced with their values
|
|
75
|
+
* @property {string} [realFullPath] - Full path, including query string and hash, but with parameters replaced with their values
|
|
76
|
+
* @property {Object} [qs] - Query string object
|
|
77
|
+
* @property {Object} [params] - Parameters object
|
|
78
|
+
* @see Bajo.TNsPathPairs
|
|
71
79
|
* @see Bajo#buildNsPath
|
|
72
80
|
* @see Bajo#breakNsPath
|
|
73
81
|
*/
|
|
74
82
|
|
|
75
83
|
/**
|
|
76
|
-
* The
|
|
77
|
-
*
|
|
84
|
+
* The core plugin. The main engine. The special plugin that controls the app's boot process and
|
|
85
|
+
* makes sure all other plugins work nicely.
|
|
86
|
+
*
|
|
87
|
+
* Don't create your own instance of this class or {@link App} class. Instead, use the {@link boot} process.
|
|
78
88
|
*
|
|
79
89
|
* @class
|
|
80
90
|
*/
|
|
@@ -88,57 +98,61 @@ class Bajo extends Plugin {
|
|
|
88
98
|
super('bajo', app)
|
|
89
99
|
|
|
90
100
|
/**
|
|
91
|
-
* Alias
|
|
101
|
+
* Alias. Read-only
|
|
92
102
|
* @type {string}
|
|
103
|
+
* @default 'bajo'
|
|
93
104
|
*/
|
|
94
105
|
this.alias = 'bajo'
|
|
95
106
|
|
|
96
107
|
/**
|
|
97
|
-
*
|
|
108
|
+
* Array of white space characters. Used to trim strings
|
|
98
109
|
* @type {string[]}
|
|
99
110
|
*/
|
|
100
111
|
this.whiteSpace = [' ', '\t', '\n', '\r']
|
|
101
112
|
|
|
102
113
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* @type {Bajo.TObject}
|
|
114
|
+
* Configuration object
|
|
115
|
+
* @type {Bajo.TConfig}
|
|
106
116
|
* @see {@tutorial config}
|
|
107
117
|
*/
|
|
108
118
|
this.config = {}
|
|
109
119
|
|
|
110
120
|
/**
|
|
111
|
-
* Hooks container.
|
|
112
|
-
*
|
|
121
|
+
* Hooks container. This is where all hooks definition are stored.
|
|
113
122
|
* @type {Array<Bajo.THook>}
|
|
114
123
|
*/
|
|
115
124
|
this.hooks = []
|
|
116
125
|
}
|
|
117
126
|
|
|
118
127
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
+
* Bajo boot process. This method is called by the {@link App} class during the app's boot process:
|
|
129
|
+
* 1. Building Bajo's {@link module:Helper.buildBaseConfig|base configuration}
|
|
130
|
+
* 2. Collect all {@link module:Helper.collectConfigHandlers|config handlers} from all loaded plugins
|
|
131
|
+
* 3. Build {@link module:Helper.buildConfig|configuration} object
|
|
132
|
+
* 4. {@link module:Helper.buildPlugins|Building plugins} listed in `package.json` or `.plugins` file
|
|
133
|
+
* 5. Determining the {@link module:Helper.bootOrder|boot order}
|
|
134
|
+
* 6. Ensure the {@link module:Helper.checkNameAliases|uniqueness} of all plugins' name and alias
|
|
135
|
+
* 7. Ensure all plugins {@link module:Helper.checkDependencies|dependencies} are met
|
|
136
|
+
* 8. Collect all {@link module:Helper.collectHooks|hooks} from all loaded plugins
|
|
137
|
+
* 9. {@link module:Helper.runPlugins|Run all plugins} according to the boot order
|
|
138
|
+
* 10. And finally attaching all {@link module:Helper.exitHandler|exit handlers} it could find
|
|
128
139
|
*
|
|
129
140
|
* @method
|
|
130
141
|
* @async
|
|
131
142
|
*/
|
|
132
|
-
|
|
143
|
+
bootApp = async () => {
|
|
133
144
|
await buildBaseConfig.call(this)
|
|
134
145
|
await collectConfigHandlers.call(this)
|
|
135
|
-
await
|
|
146
|
+
await buildConfig.call(this)
|
|
136
147
|
await buildPlugins.call(this)
|
|
137
148
|
await bootOrder.call(this)
|
|
138
|
-
await
|
|
149
|
+
await checkNameAliases.call(this)
|
|
150
|
+
await checkDependencies.call(this)
|
|
151
|
+
await collectHooks.call(this)
|
|
152
|
+
await runPlugins.call(this)
|
|
139
153
|
await exitHandler.call(this)
|
|
140
154
|
if (this.app.bajoSpatial) {
|
|
141
|
-
this.anekaSpatial = await this.importPkg('bajoSpatial:aneka-spatial')
|
|
155
|
+
this.app.lib.anekaSpatial = await this.importPkg('bajoSpatial:aneka-spatial')
|
|
142
156
|
}
|
|
143
157
|
}
|
|
144
158
|
|
|
@@ -193,12 +207,24 @@ class Bajo extends Plugin {
|
|
|
193
207
|
}
|
|
194
208
|
|
|
195
209
|
/**
|
|
196
|
-
* Break name to
|
|
210
|
+
* Break `name` to their components.
|
|
211
|
+
*
|
|
212
|
+
* If path starts with `//`, e.g. name is `https://example.com`, it will be treated as a URL and returned as an
|
|
213
|
+
* object with only `path` property filled with the original name.
|
|
214
|
+
*
|
|
215
|
+
* If query string is present in the path, it will be parsed and returned as an object with `qs`
|
|
216
|
+
* property containing the parsed query string.
|
|
217
|
+
*
|
|
218
|
+
* If path contains parameters in the format of `:key|value` or `{key|value}`, they will be extracted and returned
|
|
219
|
+
* as an object with `params` property containing the extracted parameters.
|
|
220
|
+
*
|
|
221
|
+
* This method is one of the most used method in Bajo. It is because every files, names, resources, and even commands
|
|
222
|
+
* are all identified by their namespace and path.
|
|
197
223
|
*
|
|
198
224
|
* @method
|
|
199
|
-
* @param {
|
|
200
|
-
* @param {boolean} [checkNs=true] - If `true` (default), namespace
|
|
201
|
-
* @returns {TNsPathResult}
|
|
225
|
+
* @param {Bajo.TNsPathPairs} name - Name in format `ns:path`
|
|
226
|
+
* @param {boolean} [checkNs=true] - If `true` (default), check if the namespace exists in the app. If not, throw an error
|
|
227
|
+
* @returns {Bajo.TNsPathResult}
|
|
202
228
|
*/
|
|
203
229
|
breakNsPath = (name = '', checkNs = true) => {
|
|
204
230
|
let [ns, ...path] = name.split(':')
|
|
@@ -227,14 +253,17 @@ class Bajo extends Plugin {
|
|
|
227
253
|
const params = {}
|
|
228
254
|
for (const idx in parts) {
|
|
229
255
|
const part = parts[idx]
|
|
230
|
-
if (part
|
|
256
|
+
if (part.indexOf('|') === -1 && ![':', '{'].includes(part[0])) {
|
|
231
257
|
realParts.push(part)
|
|
232
258
|
continue
|
|
233
259
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
260
|
+
let [key, val] = part.split('|')
|
|
261
|
+
if (!val) val = key[0] === '{' ? '}' : ''
|
|
262
|
+
key = key.slice(1)
|
|
263
|
+
val = val[val.length - 1] === '}' ? val.slice(0, val.length - 1) : val
|
|
264
|
+
// parts[idx] = key
|
|
265
|
+
params[key] = val
|
|
266
|
+
realParts.push(isEmpty(val) ? parts[idx] : val)
|
|
238
267
|
}
|
|
239
268
|
path = parts.join('/')
|
|
240
269
|
const realPath = realParts.join('/')
|
|
@@ -242,33 +271,39 @@ class Bajo extends Plugin {
|
|
|
242
271
|
if (!isEmpty(qs)) fullPath += ('?' + querystring.stringify(qs, null, null, { encodeURIComponent: (text) => (text) }))
|
|
243
272
|
let realFullPath = realPath
|
|
244
273
|
if (!isEmpty(qs)) realFullPath += ('?' + querystring.stringify(qs, null, null, { encodeURIComponent: (text) => (text) }))
|
|
245
|
-
return { ns, path, subNs, subSubNs, qs, fullPath, fullNs, realPath, realFullPath }
|
|
274
|
+
return { ns, path, subNs, subSubNs, qs, params, fullPath, fullNs, realPath, realFullPath }
|
|
246
275
|
}
|
|
247
276
|
|
|
248
277
|
/**
|
|
249
|
-
* Method to transform config's array or object into
|
|
278
|
+
* Method to transform config's array or object into a collection of objects with uniformed structure. This is useful to build a collection of items
|
|
279
|
+
* from config's array or object, e.g. a collection of commands, routes, etc.
|
|
280
|
+
*
|
|
281
|
+
* You typically also provide a `handler` function to transform each item in the collection. The handler function will be called with an object
|
|
282
|
+
* containing the following keys:
|
|
283
|
+
* - `item`: the current item in the collection
|
|
284
|
+
* - `index`: the index of the current item in the collection
|
|
285
|
+
* - `cfg`: the entire config object
|
|
250
286
|
*
|
|
251
287
|
* @method
|
|
252
288
|
* @async
|
|
253
|
-
* @param {Object} options - Options
|
|
254
|
-
* @param {string} [options.ns] - Namespace. If not provided, defaults to `bajo`
|
|
255
|
-
* @param {function} [options.handler] -
|
|
256
|
-
* @param {string[]} [options.dupChecks=[]] - Array of keys to check for duplicates
|
|
257
|
-
* @param {string} options.container - Key used as container name
|
|
258
|
-
* @param {boolean} [options.useDefaultName=true] - If true (default) and `name` key is not provided, returned
|
|
259
|
-
* @
|
|
260
|
-
* @
|
|
261
|
-
* @
|
|
289
|
+
* @param {Object} [options={}] - Options
|
|
290
|
+
* @param {string} [options.ns='bajo'] - Namespace. If not provided, defaults to `bajo`
|
|
291
|
+
* @param {function} [options.handler] - Function to transform each item while building
|
|
292
|
+
* @param {string[]} [options.dupChecks=[]] - Array of keys to check for duplicates
|
|
293
|
+
* @param {string} options.container - Key used as container name
|
|
294
|
+
* @param {boolean} [options.useDefaultName=true] - If true (default) and `name` key is not provided, returned item will be named `default`
|
|
295
|
+
* @returns {Array<Object>} Returned collection of objects
|
|
296
|
+
* @see module:Hook.{ns}:beforeBuildCollection
|
|
297
|
+
* @see module:Hook.{ns}:afterBuildCollection
|
|
262
298
|
*/
|
|
263
299
|
buildCollections = async (options = {}) => {
|
|
264
300
|
const { parseObject } = this.app.lib
|
|
265
|
-
|
|
266
|
-
if (!ns) ns = this.ns
|
|
301
|
+
const { ns = this.ns, handler, dupChecks = [], container, useDefaultName = true, noDefault = true } = options
|
|
267
302
|
const cfg = this.app[ns].getConfig()
|
|
268
303
|
let items = get(cfg, container, [])
|
|
269
304
|
if (!isArray(items)) items = [items]
|
|
270
305
|
this.app[ns].log.trace('collecting%s', this.t(container))
|
|
271
|
-
await this.runHook(`${ns}:beforeBuildCollection`, container)
|
|
306
|
+
await this.runHook(`${ns}:beforeBuildCollection`, container, items)
|
|
272
307
|
const deleted = []
|
|
273
308
|
for (const index in items) {
|
|
274
309
|
const item = parseObject(items[index])
|
|
@@ -302,8 +337,7 @@ class Bajo extends Plugin {
|
|
|
302
337
|
}
|
|
303
338
|
|
|
304
339
|
/**
|
|
305
|
-
* Calling
|
|
306
|
-
*
|
|
340
|
+
* Calling a function handler in any plugins:
|
|
307
341
|
* - If name is a string, the corresponding plugin's method will be called with passed args as its parameters
|
|
308
342
|
* - 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
|
|
309
343
|
* - If name is a function, this function will be run under scope with the remaining args
|
|
@@ -311,9 +345,9 @@ class Bajo extends Plugin {
|
|
|
311
345
|
*
|
|
312
346
|
* @method
|
|
313
347
|
* @async
|
|
314
|
-
* @param {(TNsPathPairs|
|
|
315
|
-
* @param {
|
|
316
|
-
* @returns {
|
|
348
|
+
* @param {(TNsPathPairs|Plugin|function|Object)} name - Method's name, plugin instance, function handler or plain object. See above for details
|
|
349
|
+
* @param {...*} [args] - One or more arguments passed as parameter to the handler
|
|
350
|
+
* @returns {Promise<*>} Returned value
|
|
317
351
|
*/
|
|
318
352
|
callHandler = async (item, ...args) => {
|
|
319
353
|
let result
|
|
@@ -358,8 +392,8 @@ class Bajo extends Plugin {
|
|
|
358
392
|
* @param {boolean} [options.useBajo=false] - If true, add `bajo` to the running plugins too.
|
|
359
393
|
* @param {string} [options.prefix=''] - Prepend glob pattern with prefix.
|
|
360
394
|
* @param {boolean} [options.noUnderscore=true] - If true (default), matched file with name starts with underscore is ignored.
|
|
361
|
-
* @param {
|
|
362
|
-
* @returns {
|
|
395
|
+
* @param {*} [options.returnItems] - If true, each value of returned handler call will be saved as an object with running plugin name as its keys.
|
|
396
|
+
* @returns {*}
|
|
363
397
|
*/
|
|
364
398
|
eachPlugins = async (handler, options = {}) => {
|
|
365
399
|
if (isString(options)) options = { glob: options }
|
|
@@ -426,7 +460,7 @@ class Bajo extends Plugin {
|
|
|
426
460
|
*
|
|
427
461
|
* @method
|
|
428
462
|
* @param {string} type - Format type. See {@link TBajoFormatType} for acceptable values.
|
|
429
|
-
* @param {
|
|
463
|
+
* @param {*} value - Value to format.
|
|
430
464
|
* @param {string} [dataType] - Value's data type. See {@link TBajoDataType} for acceptable values.
|
|
431
465
|
* @param {Object} [options={}] - Options.
|
|
432
466
|
* @param {boolean} [options.withUnit=true] - Return with its unit appended.
|
|
@@ -434,7 +468,6 @@ class Bajo extends Plugin {
|
|
|
434
468
|
* @returns {(Array|string)} Return string if `withUnit` is true. Otherwise is an array of `[value, unit, separator]`.
|
|
435
469
|
*/
|
|
436
470
|
formatByType = (type, value, dataType, options = {}) => {
|
|
437
|
-
const { defaultsDeep } = this.app.lib.aneka
|
|
438
471
|
const { format } = this.getUnitFormat(options)
|
|
439
472
|
const { withUnit = true } = options
|
|
440
473
|
const lang = options.lang ?? this.config.lang
|
|
@@ -451,7 +484,7 @@ class Bajo extends Plugin {
|
|
|
451
484
|
* Format value.
|
|
452
485
|
*
|
|
453
486
|
* @method
|
|
454
|
-
* @param {
|
|
487
|
+
* @param {*} value - Value to format.
|
|
455
488
|
* @param {string} [type] - Data type to use. See {@link TBajoDataType} for acceptable values. If not provided, return the untouched value.
|
|
456
489
|
* @param {Object} [options={}] - Options.
|
|
457
490
|
* @param {string} [options.emptyValue=''] - Empty value to use if function resulted empty. Defaults to the one from your config.
|
|
@@ -462,7 +495,6 @@ class Bajo extends Plugin {
|
|
|
462
495
|
* @returns {string} Formatted value.
|
|
463
496
|
*/
|
|
464
497
|
format = (value, type, options = {}) => {
|
|
465
|
-
const { defaultsDeep, isSet } = this.app.lib.aneka
|
|
466
498
|
const { format } = this.config.intl
|
|
467
499
|
const { emptyValue = format.emptyValue } = options
|
|
468
500
|
const lang = options.lang ?? this.config.lang
|
|
@@ -587,7 +619,6 @@ class Bajo extends Plugin {
|
|
|
587
619
|
* @returns {(Object|Array)} See above.
|
|
588
620
|
*/
|
|
589
621
|
importPkg = async (...pkgs) => {
|
|
590
|
-
const { defaultsDeep } = this.app.lib.aneka
|
|
591
622
|
const result = {}
|
|
592
623
|
const notFound = []
|
|
593
624
|
let opts = { returnDefault: true, throwNotFound: false }
|
|
@@ -602,7 +633,7 @@ class Bajo extends Plugin {
|
|
|
602
633
|
notFound.push(pkg)
|
|
603
634
|
continue
|
|
604
635
|
}
|
|
605
|
-
const p = this.
|
|
636
|
+
const p = await this.fromJson(`${dir}/package.json`, { readFromFile: true, throwNotFound: opts.throwNotFound })
|
|
606
637
|
const mainFileOrg = dir + '/' + (p.main ?? get(p, 'exports.default', 'index.js'))
|
|
607
638
|
let mainFile = resolvePath(mainFileOrg, os.platform() === 'win32')
|
|
608
639
|
if (isEmpty(path.extname(mainFile))) {
|
|
@@ -677,35 +708,34 @@ class Bajo extends Plugin {
|
|
|
677
708
|
}
|
|
678
709
|
|
|
679
710
|
/**
|
|
680
|
-
*
|
|
711
|
+
* Return human friendly joined array of items.
|
|
681
712
|
*
|
|
682
713
|
* @method
|
|
683
|
-
* @param {
|
|
684
|
-
* @param {(string|Object)} options - If provided and is a string, it will be used as separator.
|
|
714
|
+
* @param {Array<*>} input - Array to join
|
|
715
|
+
* @param {(string|Object)} [options={}] - If provided and is a string, it will be used as separator.
|
|
685
716
|
* @param {string} [options.separator=', '] - Separator to use.
|
|
686
|
-
* @param {string} [options.lastSeparator=and] - Text to use as the last separator.
|
|
717
|
+
* @param {string} [options.lastSeparator='and'] - Text to use as the last separator.
|
|
687
718
|
* @returns {string}
|
|
688
719
|
*/
|
|
689
720
|
join = (input = [], options = {}) => {
|
|
690
721
|
const array = [...input]
|
|
691
722
|
if (isString(options)) options = { separator: options }
|
|
692
|
-
|
|
723
|
+
const { separator = ', ', lastSeparator = 'and', lang } = options
|
|
693
724
|
const translate = (val) => {
|
|
694
725
|
return this.t(val, { lang }).toLowerCase()
|
|
695
726
|
}
|
|
696
727
|
if (array.length === 0) return translate('none')
|
|
697
728
|
if (array.length === 1) return array[0]
|
|
698
|
-
lastSeparator = translate(lastSeparator)
|
|
699
729
|
const last = (array.pop() ?? '').trim()
|
|
700
|
-
return array.map(a => (a + '').trim()).join(separator) + ` ${lastSeparator} ${last}`
|
|
730
|
+
return array.map(a => (a + '').trim()).join(separator) + ` ${translate(lastSeparator)} ${last}`
|
|
701
731
|
}
|
|
702
732
|
|
|
703
733
|
/**
|
|
704
|
-
*
|
|
734
|
+
* Get numeric portion and its unit from a string.
|
|
705
735
|
*
|
|
706
736
|
* @method
|
|
707
|
-
* @param {string} [value=''] - Value to get its numeric portion
|
|
708
|
-
* @param {string} [defUnit=''] - Default unit if value doesn't have one
|
|
737
|
+
* @param {string} [value=''] - Value to get its numeric portion
|
|
738
|
+
* @param {string} [defUnit=''] - Default unit if value doesn't have one
|
|
709
739
|
* @returns {string}
|
|
710
740
|
*/
|
|
711
741
|
numUnit = (value = '', defUnit = '') => {
|
|
@@ -716,27 +746,31 @@ class Bajo extends Plugin {
|
|
|
716
746
|
|
|
717
747
|
/**
|
|
718
748
|
* Read and parse file as config object. Supported types: `.js`, `.json` and `.yml/.yaml`.
|
|
719
|
-
* More supports can be added using plugin. {@link https://github.
|
|
749
|
+
* More supports can be added using plugin. {@link https://ardhi.github.io/bajo-config|bajo-config} gives you additional supports for `.yml`, `.yaml` and `.toml` file.
|
|
720
750
|
*
|
|
721
751
|
* If file extension is `.*`, it will be auto detected and parsed accordingly
|
|
722
752
|
*
|
|
723
753
|
* @method
|
|
724
754
|
* @async
|
|
725
755
|
* @param {string} file - File to read and parse.
|
|
726
|
-
* @param {Object} [options={}] - Options
|
|
727
|
-
* @param {boolean} [options.ignoreError] - Any exception will be silently discarded
|
|
728
|
-
* @param {string} [options.ns] - If
|
|
729
|
-
* @param {string} [options.
|
|
730
|
-
* @param {
|
|
731
|
-
* @param {
|
|
732
|
-
* @param {
|
|
756
|
+
* @param {Object} [options={}] - Options
|
|
757
|
+
* @param {boolean} [options.ignoreError] - Any exception will be silently discarded
|
|
758
|
+
* @param {string} [options.ns] - If provided, scoped to this namespace. Otherwise, the running plugin's namespace will be used
|
|
759
|
+
* @param {string} [options.baseNs] - If provided, it will be used as the base namespace for extending config from other plugins
|
|
760
|
+
* @param {string|string[]|boolean} [options.extend] - If provided, it will be used as the base namespace for extending config from other plugins. Set to `false` to disable extending
|
|
761
|
+
* @param {boolean} [options.checkOverride] - If `true` and `baseNs` is provided or `extend` is not `false`, check for override config in main plugin
|
|
762
|
+
* @param {boolean} [options.merge] - If `true`, config from other plugins will be merged into the original config. Otherwise, it will perform a deep defaults merge
|
|
763
|
+
* @param {string} [options.pattern] - If provided and auto detection is on (extension is `.*`), it will be used for instead the auto generated one
|
|
764
|
+
* @param {Object} [options.defValue={}] - Default value to use if value returned empty
|
|
765
|
+
* @param {Object} [options.parserOpts={}] - Parser options
|
|
766
|
+
* @param {Object} [options.globOpts={}] - {@link https://github.com/mrmlnc/fast-glob|fast-glob} options
|
|
733
767
|
* @returns {Object}
|
|
734
768
|
*/
|
|
735
769
|
readConfig = async (file, options = {}) => {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
770
|
+
let {
|
|
771
|
+
ns, baseNs, extend, checkOverride, merge: merged, pattern, ignoreError = true,
|
|
772
|
+
defValue = {}, parserOpts = {}, globOpts = {}, handler, cache = {}
|
|
773
|
+
} = options
|
|
740
774
|
|
|
741
775
|
const getParseOptsArgs = (opts, orig) => {
|
|
742
776
|
opts.parserOpts = opts.parserOpts ?? {}
|
|
@@ -757,7 +791,7 @@ class Bajo extends Plugin {
|
|
|
757
791
|
}
|
|
758
792
|
const { suffix = '', keys = [] } = options
|
|
759
793
|
let bases = this.app.getAllNs()
|
|
760
|
-
if (isString(extend)) extend = extend.split(',').map(i => i.trim)
|
|
794
|
+
if (isString(extend)) extend = extend.split(',').map(i => i.trim())
|
|
761
795
|
if (isArray(extend)) bases = [...extend, 'main']
|
|
762
796
|
bases = uniq(bases)
|
|
763
797
|
let ext = isArray(orig) ? [] : {}
|
|
@@ -802,23 +836,24 @@ class Bajo extends Plugin {
|
|
|
802
836
|
if (cache.name) result = await this.app.cache.load(cache.name, cache.ttlDur)
|
|
803
837
|
if (result) return result
|
|
804
838
|
await this.runHook('bajo:beforeReadConfig', file, options)
|
|
805
|
-
|
|
839
|
+
const readOpts = {
|
|
840
|
+
readFromFile: true,
|
|
841
|
+
throwNotFound: !ignoreError,
|
|
842
|
+
defValue,
|
|
843
|
+
parserOpts
|
|
844
|
+
}
|
|
806
845
|
if (!ns) ns = this.ns
|
|
807
846
|
file = resolvePath(this.app.getPluginFile(file))
|
|
808
847
|
let ext = path.extname(file)
|
|
809
848
|
const fname = path.dirname(file) + '/' + path.basename(file, ext)
|
|
810
849
|
ext = ext.toLowerCase()
|
|
811
|
-
if (['.js', '.json'].includes(ext)) {
|
|
812
|
-
const item = find(this.app.configHandlers, { ext })
|
|
813
|
-
return await output(await item.readHandler.call(this.app[ns], file, parserOpts))
|
|
814
|
-
}
|
|
815
850
|
if (!['', '.*'].includes(ext)) {
|
|
816
851
|
const item = find(this.app.configHandlers, { ext })
|
|
817
852
|
if (!item) {
|
|
818
853
|
if (!ignoreError) throw this.error('cantParse%s', file, { code: 'BAJO_CONFIG_NO_PARSER' })
|
|
819
854
|
return await output(defValue)
|
|
820
855
|
}
|
|
821
|
-
return await output(await item.readHandler.call(this.app[item.ns], file,
|
|
856
|
+
return await output(await item.readHandler.call(this.app[item.ns], file, readOpts))
|
|
822
857
|
}
|
|
823
858
|
const formats = this.app.getConfigFormats(true)
|
|
824
859
|
const item = pattern ?? `${fname}.{${formats.join(',')}}`
|
|
@@ -836,147 +871,174 @@ class Bajo extends Plugin {
|
|
|
836
871
|
continue
|
|
837
872
|
}
|
|
838
873
|
const _ns = ['.js', '.json'].includes(ext) ? ns : item.ns
|
|
839
|
-
config = await item.readHandler.call(this.app[_ns], f,
|
|
874
|
+
config = await item.readHandler.call(this.app[_ns], f, readOpts)
|
|
840
875
|
if (!isEmpty(config)) break
|
|
841
876
|
}
|
|
842
877
|
return await output(config)
|
|
843
878
|
}
|
|
844
879
|
|
|
845
|
-
/**
|
|
846
|
-
* Read and parse json file.
|
|
847
|
-
*
|
|
848
|
-
* @method
|
|
849
|
-
* @param {string} file - File to read.
|
|
850
|
-
* @param {boolean} [thrownNotFound=false] - If `true`, silently ignore if file is not found.
|
|
851
|
-
* @returns {Object}
|
|
852
|
-
*/
|
|
853
|
-
readJson = (file, thrownNotFound = false) => {
|
|
854
|
-
const { parseObject } = this.app.lib
|
|
855
|
-
if (isPlainObject(thrownNotFound)) thrownNotFound = false
|
|
856
|
-
if (!fs.existsSync(file) && thrownNotFound) throw this.error('notFound%s%s', this.t('file'), file)
|
|
857
|
-
let resp
|
|
858
|
-
try {
|
|
859
|
-
resp = fs.readFileSync(file, 'utf8')
|
|
860
|
-
} catch (err) {}
|
|
861
|
-
if (isEmpty(resp)) return resp
|
|
862
|
-
return parseObject(JSON.parse(resp))
|
|
863
|
-
}
|
|
864
|
-
|
|
865
880
|
/**
|
|
866
881
|
* Read and parse JavaScript file.
|
|
867
882
|
*
|
|
868
883
|
* @async
|
|
869
884
|
* @method
|
|
870
|
-
* @param {string} file - File to read and parse
|
|
871
|
-
* @param {
|
|
872
|
-
* @
|
|
885
|
+
* @param {string} file - File to read and parse
|
|
886
|
+
* @param {boolean} [options.readFromFile=false] - Ignored for this method. Always read from file.
|
|
887
|
+
* @param {boolean} [options.throwNotFound=false] - If `true`, throw exception if file is not found
|
|
888
|
+
* @param {object} [options.defValue={}] - Default value to use if value returned empty
|
|
889
|
+
* @param {object} [options.parserOpts={}] - Options to be passed if file exports a function
|
|
890
|
+
* @returns {Object} Parsed JavaScript object
|
|
873
891
|
*/
|
|
874
892
|
async fromJs (file, options = {}) {
|
|
875
|
-
|
|
893
|
+
if (isBoolean(options)) options = {}
|
|
894
|
+
options.defValue = options.defValue ?? {}
|
|
895
|
+
if (options.throwNotFound && !fs.existsSync(file)) throw this.error('notFound%s%s', this.t('file'), file)
|
|
876
896
|
let mod = await importModule(file)
|
|
877
|
-
if (isFunction(mod)) mod = await mod.call(this,
|
|
878
|
-
return mod
|
|
897
|
+
if (isFunction(mod)) mod = await mod.call(this, options.parserOpts)
|
|
898
|
+
return isEmpty(mod) ? options.defValue : mod
|
|
879
899
|
}
|
|
880
900
|
|
|
881
901
|
/**
|
|
882
|
-
*
|
|
902
|
+
* Parse JSON string or read and parse JSON file.
|
|
883
903
|
*
|
|
884
|
-
* @
|
|
885
|
-
* @
|
|
886
|
-
* @
|
|
904
|
+
* @async
|
|
905
|
+
* @method
|
|
906
|
+
* @param {string} text - Text to be parsed or file path to be read if `options.readFromFile` is `true`
|
|
907
|
+
* @param {object|boolean} [options={}] - Options object. If a boolean is provided, it will be treated as `options.readFromFile`
|
|
908
|
+
* @param {boolean} [options.readFromFile=false] - If `true`, `text` is treated as a file path
|
|
909
|
+
* @param {boolean} [options.throwNotFound=false] - If `true`, throw exception if file is not found
|
|
910
|
+
* @param {object} [options.defValue={}] - Default value to use if value returned empty
|
|
911
|
+
* @param {object} [options.parserOpts={}] - Options to be passed to `JSON.parse()`
|
|
912
|
+
* @returns {Object} Parsed object.
|
|
913
|
+
* @see Bajo#toJson
|
|
887
914
|
*/
|
|
888
|
-
fromJson (
|
|
889
|
-
|
|
890
|
-
|
|
915
|
+
async fromJson (text, options = {}) {
|
|
916
|
+
if (isBoolean(options)) options = { readFromFile: options }
|
|
917
|
+
options.defValue = options.defValue ?? {}
|
|
918
|
+
if (options.readFromFile && !fs.existsSync(text) && options.throwNotFound) throw this.error('notFound%s%s', this.t('file'), text)
|
|
919
|
+
const content = options.readFromFile ? fs.readFileSync(text, 'utf8') : text
|
|
920
|
+
const result = JSON.parse(content)
|
|
921
|
+
return isEmpty(result) ? options.defValue : result
|
|
891
922
|
}
|
|
892
923
|
|
|
893
924
|
/**
|
|
894
|
-
* Parse YAML text
|
|
925
|
+
* Parse YAML text or read and parse YAML file.
|
|
895
926
|
*
|
|
927
|
+
* @async
|
|
896
928
|
* @method
|
|
897
|
-
* @param {string} text - Text to be parsed
|
|
898
|
-
* @param {object} options - Options object
|
|
929
|
+
* @param {string} text - Text to be parsed or file path to be read if `options.readFromFile` is `true`
|
|
930
|
+
* @param {object|boolean} [options={}] - Options object. If a boolean is provided, it will be treated as `options.readFromFile`
|
|
931
|
+
* @param {boolean} [options.readFromFile=false] - If `true`, `text` is treated as a file path
|
|
932
|
+
* @param {boolean} [options.throwNotFound=false] - If `true`, throw exception if file is not found
|
|
933
|
+
* @param {object} [options.parserOpts={}] - Options to be passed to `YAML.load()`
|
|
934
|
+
* @param {object} [options.defValue={}] - Default value to use if value returned empty
|
|
899
935
|
* @returns {object} Parsed object
|
|
936
|
+
* @see Bajo#toYaml
|
|
900
937
|
*/
|
|
901
|
-
fromYaml
|
|
902
|
-
|
|
938
|
+
async fromYaml (text, options = {}) {
|
|
939
|
+
if (isBoolean(options)) options = { readFromFile: options }
|
|
940
|
+
options.defValue = options.defValue ?? {}
|
|
941
|
+
if (options.readFromFile && !fs.existsSync(text) && options.throwNotFound) throw this.error('notFound%s%s', this.t('file'), text)
|
|
903
942
|
const content = options.readFromFile ? fs.readFileSync(text, 'utf8') : text
|
|
904
|
-
|
|
943
|
+
const result = yaml.load(content)
|
|
944
|
+
return isEmpty(result) ? options.defValue : result
|
|
905
945
|
}
|
|
906
946
|
|
|
907
947
|
/**
|
|
908
|
-
* Parse YML text. Alias for fromYaml.
|
|
948
|
+
* Parse YML text or read and parse YML file. Alias for {@link Bajo#fromYaml}.
|
|
909
949
|
*
|
|
950
|
+
* @async
|
|
910
951
|
* @method
|
|
911
|
-
* @param {string} text - Text to be parsed
|
|
912
|
-
* @param {object} options - Options object
|
|
952
|
+
* @param {string} text - Text to be parsed or file path to be read if `options.readFromFile` is `true`
|
|
953
|
+
* @param {object|boolean} [options={}] - Options object. If a boolean is provided, it will be treated as `options.readFromFile`
|
|
954
|
+
* @param {boolean} [options.readFromFile=false] - If `true`, `text` is treated as a file path
|
|
955
|
+
* @param {boolean} [options.throwNotFound=false] - If `true`, throw exception if file is not found
|
|
956
|
+
* @param {object} [options.defValue={}] - Default value to use if value returned empty
|
|
957
|
+
* @param {object} [options.parserOpts={}] - Options to be passed to `YAML.load()`
|
|
913
958
|
* @returns {object} Parsed object
|
|
959
|
+
* @see Bajo#toYml
|
|
914
960
|
*/
|
|
915
|
-
fromYml
|
|
961
|
+
async fromYml (text, options = {}) {
|
|
916
962
|
return this.fromYaml(text, options)
|
|
917
963
|
}
|
|
918
964
|
|
|
919
965
|
/**
|
|
920
|
-
* Convert data to JSON string.
|
|
966
|
+
* Convert data to JSON string, optionally write to file if `options.writeToFile` is provided.
|
|
921
967
|
*
|
|
968
|
+
* @async
|
|
922
969
|
* @method
|
|
923
|
-
* @param {Object} data - Data to convert to JSON string
|
|
924
|
-
* @param {Object} [options={}] - Options.
|
|
925
|
-
* @param {
|
|
926
|
-
* @param {
|
|
927
|
-
* @returns {string} JSON string
|
|
970
|
+
* @param {Object} data - Data to convert to JSON string
|
|
971
|
+
* @param {Object|string} [options={}] - Options object. If a string is provided, it will be treated as `options.writeToFile`
|
|
972
|
+
* @param {string} [options.writeToFile] - If not empty, write result to this file path instead of returning it as string
|
|
973
|
+
* @param {Object} [options.parserOpts={}] - Options for `JSON.stringify()`
|
|
974
|
+
* @returns {Promise<string|void>} JSON string or void if written to file
|
|
975
|
+
* @see Bajo#fromJson
|
|
928
976
|
*/
|
|
929
|
-
toJson
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
977
|
+
async toJson (data, options = {}) {
|
|
978
|
+
if (isString(options)) options = { writeToFile: options }
|
|
979
|
+
options.parserOpts = options.parserOpts ?? {}
|
|
980
|
+
options.parserOpts.space = options.parserOpts.space ?? 2
|
|
981
|
+
const content = JSON.stringify(data, null, options.parserOpts)
|
|
982
|
+
if (isString(options.writeToFile)) {
|
|
983
|
+
fs.writeFileSync(options.writeToFile, content, 'utf8')
|
|
933
984
|
return
|
|
934
985
|
}
|
|
935
986
|
return content
|
|
936
987
|
}
|
|
937
988
|
|
|
938
989
|
/**
|
|
939
|
-
* Convert object to YAML string
|
|
990
|
+
* Convert object to YAML string, optionally write to file if `options.writeToFile` is provided.
|
|
940
991
|
*
|
|
992
|
+
* @async
|
|
941
993
|
* @method
|
|
942
994
|
* @param {object} object - Object to be converted
|
|
943
|
-
* @param {object} options - Options object
|
|
944
|
-
* @
|
|
995
|
+
* @param {object|string} [options] - Options object. If a string is provided, it will be treated as `options.writeToFile`
|
|
996
|
+
* @param {string} [options.writeToFile] - If not empty, write result to this file path instead of returning it as string
|
|
997
|
+
* @param {Object} [options.parserOpts={}] - Options for `YAML.dump()`
|
|
998
|
+
* @returns {Promise<string|void>} YAML string or void if written to file
|
|
999
|
+
* @see Bajo#fromYaml
|
|
945
1000
|
*/
|
|
946
|
-
toYaml
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
const content = yaml.dump(object,
|
|
1001
|
+
async toYaml (object, options = {}) {
|
|
1002
|
+
if (isString(options)) options = { writeToFile: options }
|
|
1003
|
+
options.parserOpts = options.parserOpts ?? {}
|
|
1004
|
+
const content = yaml.dump(object, options.parserOpts)
|
|
950
1005
|
if (options.writeToFile) {
|
|
951
|
-
|
|
952
|
-
|
|
1006
|
+
if (isString(options.writeToFile)) {
|
|
1007
|
+
fs.writeFileSync(options.writeToFile, content, 'utf8')
|
|
1008
|
+
return
|
|
1009
|
+
}
|
|
953
1010
|
}
|
|
954
1011
|
return content
|
|
955
1012
|
}
|
|
956
1013
|
|
|
957
1014
|
/**
|
|
958
|
-
* Convert object to YML string. Alias for toYaml.
|
|
959
|
-
*
|
|
1015
|
+
* Convert object to YML string, optionally write to file if `options.writeToFile` is provided. Alias for {@link Bajo#toYaml}.
|
|
1016
|
+
* @async
|
|
960
1017
|
* @method
|
|
961
1018
|
* @param {object} object - Object to be converted
|
|
962
|
-
* @param {object} options - Options object
|
|
963
|
-
* @
|
|
1019
|
+
* @param {object|string} [options] - Options object. If a string is provided, it will be treated as `options.writeToFile`
|
|
1020
|
+
* @param {string} [options.writeToFile] - If not empty, write result to this file path instead of returning it as string
|
|
1021
|
+
* @param {Object} [options.parserOpts={}] - Options for `YAML.dump()`
|
|
1022
|
+
* @returns {Promise<string|void>} YAML string or void if written to file
|
|
1023
|
+
* @see Bajo#fromYml
|
|
964
1024
|
*/
|
|
965
|
-
toYml
|
|
1025
|
+
async toYml (object, options = {}) {
|
|
966
1026
|
return this.toYaml(object, options)
|
|
967
1027
|
}
|
|
968
1028
|
|
|
969
1029
|
/**
|
|
970
|
-
* Read all
|
|
1030
|
+
* Read all forms of configuration files from file path.
|
|
1031
|
+
*
|
|
1032
|
+
* Internally, it will call {@link Bajo#readConfig} twice, first for the default config file and
|
|
1033
|
+
* second for the environment based config file. Then it will merge both results using `defaultsDeep`.
|
|
971
1034
|
*
|
|
972
1035
|
* @method
|
|
973
1036
|
* @async
|
|
974
1037
|
* @param {string} path - Base path to start looking config files.
|
|
975
|
-
* @param {Object} [options={}] - Options.
|
|
1038
|
+
* @param {Object} [options={}] - Options. See {@link Bajo#readConfig} for more.
|
|
976
1039
|
* @returns {Object} Merged configuration object.
|
|
977
1040
|
*/
|
|
978
1041
|
readAllConfigs = async (path, options) => {
|
|
979
|
-
const { defaultsDeep } = this.app.lib.aneka
|
|
980
1042
|
let cfg = {}
|
|
981
1043
|
let ext = {}
|
|
982
1044
|
// default config file
|
|
@@ -995,7 +1057,14 @@ class Bajo extends Plugin {
|
|
|
995
1057
|
}
|
|
996
1058
|
|
|
997
1059
|
/**
|
|
998
|
-
* Run named
|
|
1060
|
+
* Run named {@link module:Hook}.
|
|
1061
|
+
*
|
|
1062
|
+
* If no hook found with the given name, it will return an empty array.
|
|
1063
|
+
* If a hook has `noWait` set to `true`, it will not wait for the hook to finish and will not return its result.
|
|
1064
|
+
*
|
|
1065
|
+
* > **Note**: Even though this method returns a result, it is not recommended to use the result for any purpose.
|
|
1066
|
+
* Use the result only for debugging or logging purposes. Hooks are designed to be fast, lightweight and mutate
|
|
1067
|
+
* arguments given to them so that the next hook can benefit from the changes.
|
|
999
1068
|
*
|
|
1000
1069
|
* @method
|
|
1001
1070
|
* @async
|
|
@@ -1023,6 +1092,18 @@ class Bajo extends Plugin {
|
|
|
1023
1092
|
return results
|
|
1024
1093
|
}
|
|
1025
1094
|
|
|
1095
|
+
/**
|
|
1096
|
+
* Get download directory. If doesn't exist, it will be created automatically.
|
|
1097
|
+
*
|
|
1098
|
+
* @method
|
|
1099
|
+
* @returns {string} Absolute path to the download directory
|
|
1100
|
+
*/
|
|
1101
|
+
getDownloadDir = () => {
|
|
1102
|
+
const dir = `${this.app.getPluginDataDir(this.ns)}/download`
|
|
1103
|
+
fs.ensureDirSync(dir)
|
|
1104
|
+
return dir
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1026
1107
|
/**
|
|
1027
1108
|
* Save item as file in Bajo's download directory. That is a directory inside your
|
|
1028
1109
|
* Bajo plugin's data directory.
|
|
@@ -1038,27 +1119,27 @@ class Bajo extends Plugin {
|
|
|
1038
1119
|
* @returns {string} Full file path.
|
|
1039
1120
|
*/
|
|
1040
1121
|
saveAsDownload = async (file, item, printSaved = true) => {
|
|
1041
|
-
const
|
|
1042
|
-
const fname = increment(`${this.app.getPluginDataDir(this.ns)}/download/${trim(file, '/')}`, { fs: true })
|
|
1043
|
-
const dir = path.dirname(fname)
|
|
1044
|
-
if (!fs.existsSync(dir)) fs.ensureDirSync(dir)
|
|
1122
|
+
const fname = increment(`${this.getDownloadDir()}/${trim(file, '/')}`, { fs: true })
|
|
1045
1123
|
await fs.writeFile(fname, item, 'utf8')
|
|
1046
|
-
if (printSaved) print.succeed('savedAs%s', path.resolve(fname), { skipSilence: true })
|
|
1124
|
+
if (printSaved) this.print.succeed('savedAs%s', path.resolve(fname), { skipSilence: true })
|
|
1047
1125
|
return fname
|
|
1048
1126
|
}
|
|
1049
1127
|
|
|
1050
1128
|
/**
|
|
1051
|
-
*
|
|
1129
|
+
* Parse `input` using all registered config handlers. The first handler that returns a
|
|
1052
1130
|
* valid object or array will be used.
|
|
1053
1131
|
*
|
|
1132
|
+
* Use this method if you want to parse a text `input` that can be in any format supported by the registered config handlers.
|
|
1133
|
+
*
|
|
1054
1134
|
* @method
|
|
1055
1135
|
* @param {string} input - The input string to be processed by the config handlers.
|
|
1056
1136
|
* @param {string[]} [exts] - Optional array of extensions to filter the config handlers. If provided, only handlers with matching extensions will be used.
|
|
1057
1137
|
* @param {object} [options={}] - Options to be passed to the config handlers.
|
|
1058
1138
|
* @returns {Object|Array|null} The result from the first successful config handler, or null if none succeed.
|
|
1059
1139
|
*/
|
|
1060
|
-
|
|
1140
|
+
parseWithConfig = async (input, exts, options = {}) => {
|
|
1061
1141
|
let result
|
|
1142
|
+
options.readFromFile = false
|
|
1062
1143
|
const handlers = exts ? this.app.configHandlers.filter(h => exts.includes(h.ext)) : this.app.configHandlers
|
|
1063
1144
|
for (const handler of handlers) {
|
|
1064
1145
|
if (result) break
|
|
@@ -1073,4 +1154,4 @@ class Bajo extends Plugin {
|
|
|
1073
1154
|
}
|
|
1074
1155
|
|
|
1075
1156
|
export default Bajo
|
|
1076
|
-
</code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">Bajo API</a><div class="mobile-nav-links"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/bajo" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/bajo" target="">Github</a></div><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="App.html">App</a></div><div class="sidebar-section-children"><a href="Bajo.html">Bajo</a></div><div class="sidebar-section-children"><a href="Base.html">Base</a></div><div class="sidebar-section-children"><a href="Cache.html">Cache</a></div><div class="sidebar-section-children"><a href="Err.html">Err</a></div><div class="sidebar-section-children"><a href="Log.html">Log</a></div><div class="sidebar-section-children"><a href="Plugin.html">Plugin</a></div><div class="sidebar-section-children"><a href="Print.html">Print</a></div><div class="sidebar-section-children"><a href="Tools.html">Tools</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div><div class="sidebar-section-children"><a href="module-Hook.html">Hook</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#boot">boot</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|
|
1157
|
+
</code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">Bajo API</a><div class="mobile-nav-links"><div class="navbar-item"><a id="" href="https://www.npmjs.com/package/bajo" target="">NPM</a></div><div class="navbar-item"><a id="" href="https://github.com/ardhi/bajo" target="">Github</a></div><div class="navbar-item"><a id="" href="https://bajo.app" target="">Bajo</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-01_WELCOME.html">Welcome</a></div><div class="sidebar-section-children"><a href="tutorial-02_GETTING_STARTED.html">Getting Started</a></div><div class="sidebar-section-children"><a href="tutorial-03_USER_GUIDE.html">User Guide</a></div><div class="sidebar-section-children"><a href="tutorial-04_DEV_GUIDE.html">Developer Guide</a></div><div class="sidebar-section-children"><a href="tutorial-05_ECOSYSTEM.html">Ecosystem</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="App.html">App</a></div><div class="sidebar-section-children"><a href="Bajo.html">Bajo</a></div><div class="sidebar-section-children"><a href="Base.html">Base</a></div><div class="sidebar-section-children"><a href="Cache.html">Cache</a></div><div class="sidebar-section-children"><a href="Err.html">Err</a></div><div class="sidebar-section-children"><a href="Log.html">Log</a></div><div class="sidebar-section-children"><a href="Main.html">Main</a></div><div class="sidebar-section-children"><a href="Plugin.html">Plugin</a></div><div class="sidebar-section-children"><a href="Print.html">Print</a></div><div class="sidebar-section-children"><a href="Tools.html">Tools</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-Applet.html">Applet</a></div><div class="sidebar-section-children"><a href="module-Helper.html">Helper</a></div><div class="sidebar-section-children"><a href="module-Hook.html">Hook</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#TConfig">TConfig</a></div><div class="sidebar-section-children"><a href="global.html#boot">boot</a></div><div class="sidebar-section-children"><a href="global.html#package%25C2%25B7json">package·json</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|