jopijs 0.0.1
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/README.md +134 -0
- package/bin/jopib.js +4 -0
- package/bin/jopin.js +4 -0
- package/dist/@bundler/_logs.d.ts +2 -0
- package/dist/@bundler/_logs.js +4 -0
- package/dist/@bundler/_logs.js.map +1 -0
- package/dist/@bundler/core.d.ts +1 -0
- package/dist/@bundler/core.js +34 -0
- package/dist/@bundler/core.js.map +1 -0
- package/dist/@bundler/esbuild.d.ts +6 -0
- package/dist/@bundler/esbuild.js +111 -0
- package/dist/@bundler/esbuild.js.map +1 -0
- package/dist/@bundler/index.d.ts +2 -0
- package/dist/@bundler/index.js +3 -0
- package/dist/@bundler/index.js.map +1 -0
- package/dist/@bundler/plugins.d.ts +13 -0
- package/dist/@bundler/plugins.js +145 -0
- package/dist/@bundler/plugins.js.map +1 -0
- package/dist/@bundler/tailwind.d.ts +3 -0
- package/dist/@bundler/tailwind.js +119 -0
- package/dist/@bundler/tailwind.js.map +1 -0
- package/dist/@core/PageComponent.d.ts +6 -0
- package/dist/@core/PageComponent.js +10 -0
- package/dist/@core/PageComponent.js.map +1 -0
- package/dist/@core/_logs.d.ts +7 -0
- package/dist/@core/_logs.js +9 -0
- package/dist/@core/_logs.js.map +1 -0
- package/dist/@core/automaticStartStop.d.ts +25 -0
- package/dist/@core/automaticStartStop.js +106 -0
- package/dist/@core/automaticStartStop.js.map +1 -0
- package/dist/@core/browserCacheControl.d.ts +21 -0
- package/dist/@core/browserCacheControl.js +17 -0
- package/dist/@core/browserCacheControl.js.map +1 -0
- package/dist/@core/bundler/bundler.d.ts +22 -0
- package/dist/@core/bundler/bundler.js +90 -0
- package/dist/@core/bundler/bundler.js.map +1 -0
- package/dist/@core/bundler/common.d.ts +2 -0
- package/dist/@core/bundler/common.js +17 -0
- package/dist/@core/bundler/common.js.map +1 -0
- package/dist/@core/bundler/config.d.ts +20 -0
- package/dist/@core/bundler/config.js +11 -0
- package/dist/@core/bundler/config.js.map +1 -0
- package/dist/@core/bundler/extraContent.d.ts +6 -0
- package/dist/@core/bundler/extraContent.js +27 -0
- package/dist/@core/bundler/extraContent.js.map +1 -0
- package/dist/@core/bundler/pagesGenerator.d.ts +1 -0
- package/dist/@core/bundler/pagesGenerator.js +173 -0
- package/dist/@core/bundler/pagesGenerator.js.map +1 -0
- package/dist/@core/bundler/server.d.ts +8 -0
- package/dist/@core/bundler/server.js +35 -0
- package/dist/@core/bundler/server.js.map +1 -0
- package/dist/@core/caches/InMemoryCache.d.ts +35 -0
- package/dist/@core/caches/InMemoryCache.js +353 -0
- package/dist/@core/caches/InMemoryCache.js.map +1 -0
- package/dist/@core/caches/SimpleFileCache.d.ts +18 -0
- package/dist/@core/caches/SimpleFileCache.js +171 -0
- package/dist/@core/caches/SimpleFileCache.js.map +1 -0
- package/dist/@core/caches/cache.d.ts +36 -0
- package/dist/@core/caches/cache.js +33 -0
- package/dist/@core/caches/cache.js.map +1 -0
- package/dist/@core/caches/webSiteMirrorCache.d.ts +16 -0
- package/dist/@core/caches/webSiteMirrorCache.js +81 -0
- package/dist/@core/caches/webSiteMirrorCache.js.map +1 -0
- package/dist/@core/gzip.d.ts +4 -0
- package/dist/@core/gzip.js +31 -0
- package/dist/@core/gzip.js.map +1 -0
- package/dist/@core/index.d.ts +18 -0
- package/dist/@core/index.js +19 -0
- package/dist/@core/index.js.map +1 -0
- package/dist/@core/internalTools.d.ts +14 -0
- package/dist/@core/internalTools.js +79 -0
- package/dist/@core/internalTools.js.map +1 -0
- package/dist/@core/jQuery.d.ts +5 -0
- package/dist/@core/jQuery.js +18 -0
- package/dist/@core/jQuery.js.map +1 -0
- package/dist/@core/jopiEasy.d.ts +287 -0
- package/dist/@core/jopiEasy.js +983 -0
- package/dist/@core/jopiEasy.js.map +1 -0
- package/dist/@core/jopiRequest.d.ts +269 -0
- package/dist/@core/jopiRequest.js +1060 -0
- package/dist/@core/jopiRequest.js.map +1 -0
- package/dist/@core/jopiServer.d.ts +77 -0
- package/dist/@core/jopiServer.js +100 -0
- package/dist/@core/jopiServer.js.map +1 -0
- package/dist/@core/jopiWebSite.d.ts +319 -0
- package/dist/@core/jopiWebSite.js +653 -0
- package/dist/@core/jopiWebSite.js.map +1 -0
- package/dist/@core/letsEncrypt.d.ts +25 -0
- package/dist/@core/letsEncrypt.js +189 -0
- package/dist/@core/letsEncrypt.js.map +1 -0
- package/dist/@core/linker.d.ts +4 -0
- package/dist/@core/linker.js +37 -0
- package/dist/@core/linker.js.map +1 -0
- package/dist/@core/loadBalancing.d.ts +18 -0
- package/dist/@core/loadBalancing.js +126 -0
- package/dist/@core/loadBalancing.js.map +1 -0
- package/dist/@core/middlewares/CorsMiddleware.d.ts +5 -0
- package/dist/@core/middlewares/CorsMiddleware.js +15 -0
- package/dist/@core/middlewares/CorsMiddleware.js.map +1 -0
- package/dist/@core/middlewares/DdosProtection.d.ts +42 -0
- package/dist/@core/middlewares/DdosProtection.js +62 -0
- package/dist/@core/middlewares/DdosProtection.js.map +1 -0
- package/dist/@core/middlewares/index.d.ts +10 -0
- package/dist/@core/middlewares/index.js +14 -0
- package/dist/@core/middlewares/index.js.map +1 -0
- package/dist/@core/publicTools.d.ts +8 -0
- package/dist/@core/publicTools.js +11 -0
- package/dist/@core/publicTools.js.map +1 -0
- package/dist/@core/routeConfig.d.ts +48 -0
- package/dist/@core/routeConfig.js +102 -0
- package/dist/@core/routeConfig.js.map +1 -0
- package/dist/@core/searchParamFilter.d.ts +70 -0
- package/dist/@core/searchParamFilter.js +212 -0
- package/dist/@core/searchParamFilter.js.map +1 -0
- package/dist/@core/serverFetch.d.ts +122 -0
- package/dist/@core/serverFetch.js +312 -0
- package/dist/@core/serverFetch.js.map +1 -0
- package/dist/@core/serverImpl/server_bunjs.d.ts +29 -0
- package/dist/@core/serverImpl/server_bunjs.js +180 -0
- package/dist/@core/serverImpl/server_bunjs.js.map +1 -0
- package/dist/@core/serverImpl/server_nodejs.d.ts +22 -0
- package/dist/@core/serverImpl/server_nodejs.js +235 -0
- package/dist/@core/serverImpl/server_nodejs.js.map +1 -0
- package/dist/@core/serverInstanceBuilder.d.ts +17 -0
- package/dist/@core/serverInstanceBuilder.js +14 -0
- package/dist/@core/serverInstanceBuilder.js.map +1 -0
- package/dist/@core/userStores.d.ts +13 -0
- package/dist/@core/userStores.js +20 -0
- package/dist/@core/userStores.js.map +1 -0
- package/dist/@crawler/common.d.ts +203 -0
- package/dist/@crawler/common.js +68 -0
- package/dist/@crawler/common.js.map +1 -0
- package/dist/@crawler/core.d.ts +87 -0
- package/dist/@crawler/core.js +586 -0
- package/dist/@crawler/core.js.map +1 -0
- package/dist/@crawler/directFileCache.d.ts +10 -0
- package/dist/@crawler/directFileCache.js +60 -0
- package/dist/@crawler/directFileCache.js.map +1 -0
- package/dist/@crawler/index.d.ts +4 -0
- package/dist/@crawler/index.js +5 -0
- package/dist/@crawler/index.js.map +1 -0
- package/dist/@crawler/urlMapping.d.ts +21 -0
- package/dist/@crawler/urlMapping.js +52 -0
- package/dist/@crawler/urlMapping.js.map +1 -0
- package/dist/@crawler/utils.d.ts +6 -0
- package/dist/@crawler/utils.js +13 -0
- package/dist/@crawler/utils.js.map +1 -0
- package/dist/@generated/index.d.ts +29 -0
- package/dist/@generated/index.js +93 -0
- package/dist/@generated/index.js.map +1 -0
- package/dist/@linker/arobaseTypes.d.ts +50 -0
- package/dist/@linker/arobaseTypes.js +235 -0
- package/dist/@linker/arobaseTypes.js.map +1 -0
- package/dist/@linker/changeProof.d.ts +5 -0
- package/dist/@linker/changeProof.js +50 -0
- package/dist/@linker/changeProof.js.map +1 -0
- package/dist/@linker/config.d.ts +2 -0
- package/dist/@linker/config.js +40 -0
- package/dist/@linker/config.js.map +1 -0
- package/dist/@linker/engine.d.ts +156 -0
- package/dist/@linker/engine.js +665 -0
- package/dist/@linker/engine.js.map +1 -0
- package/dist/@linker/index.d.ts +3 -0
- package/dist/@linker/index.js +4 -0
- package/dist/@linker/index.js.map +1 -0
- package/dist/@linker/install.d.ts +4 -0
- package/dist/@linker/install.js +42 -0
- package/dist/@linker/install.js.map +1 -0
- package/dist/@linker/modInstaller.d.ts +10 -0
- package/dist/@linker/modInstaller.js +38 -0
- package/dist/@linker/modInstaller.js.map +1 -0
- package/dist/@linker/typeEvents.d.ts +9 -0
- package/dist/@linker/typeEvents.js +48 -0
- package/dist/@linker/typeEvents.js.map +1 -0
- package/dist/@linker/typeRoutes.d.ts +23 -0
- package/dist/@linker/typeRoutes.js +197 -0
- package/dist/@linker/typeRoutes.js.map +1 -0
- package/dist/@linker/typeUiComposite.d.ts +6 -0
- package/dist/@linker/typeUiComposite.js +16 -0
- package/dist/@linker/typeUiComposite.js.map +1 -0
- package/dist/@loader/index.d.ts +1 -0
- package/dist/@loader/index.js +17 -0
- package/dist/@loader/index.js.map +1 -0
- package/dist/@loader/nodeJsLoader.d.ts +2 -0
- package/dist/@loader/nodeJsLoader.js +19 -0
- package/dist/@loader/nodeJsLoader.js.map +1 -0
- package/dist/@loader-client/index.d.ts +33 -0
- package/dist/@loader-client/index.js +98 -0
- package/dist/@loader-client/index.js.map +1 -0
- package/dist/@loader-tools/bunJsLoader.d.ts +1 -0
- package/dist/@loader-tools/bunJsLoader.js +28 -0
- package/dist/@loader-tools/bunJsLoader.js.map +1 -0
- package/dist/@loader-tools/config.d.ts +49 -0
- package/dist/@loader-tools/config.js +79 -0
- package/dist/@loader-tools/config.js.map +1 -0
- package/dist/@loader-tools/cssModuleCompiler.d.ts +5 -0
- package/dist/@loader-tools/cssModuleCompiler.js +65 -0
- package/dist/@loader-tools/cssModuleCompiler.js.map +1 -0
- package/dist/@loader-tools/esBuildPlugin.d.ts +5 -0
- package/dist/@loader-tools/esBuildPlugin.js +113 -0
- package/dist/@loader-tools/esBuildPlugin.js.map +1 -0
- package/dist/@loader-tools/index.d.ts +9 -0
- package/dist/@loader-tools/index.js +10 -0
- package/dist/@loader-tools/index.js.map +1 -0
- package/dist/@loader-tools/jopin.d.ts +10 -0
- package/dist/@loader-tools/jopin.js +331 -0
- package/dist/@loader-tools/jopin.js.map +1 -0
- package/dist/@loader-tools/nodeJsLoader.d.ts +13 -0
- package/dist/@loader-tools/nodeJsLoader.js +101 -0
- package/dist/@loader-tools/nodeJsLoader.js.map +1 -0
- package/dist/@loader-tools/nodeJsResolver.d.ts +2 -0
- package/dist/@loader-tools/nodeJsResolver.js +117 -0
- package/dist/@loader-tools/nodeJsResolver.js.map +1 -0
- package/dist/@loader-tools/rules.d.ts +3 -0
- package/dist/@loader-tools/rules.js +33 -0
- package/dist/@loader-tools/rules.js.map +1 -0
- package/dist/@loader-tools/sourceChangesWatcher.d.ts +39 -0
- package/dist/@loader-tools/sourceChangesWatcher.js +182 -0
- package/dist/@loader-tools/sourceChangesWatcher.js.map +1 -0
- package/dist/@loader-tools/tools.d.ts +21 -0
- package/dist/@loader-tools/tools.js +113 -0
- package/dist/@loader-tools/tools.js.map +1 -0
- package/dist/@loader-tools/transform.d.ts +5 -0
- package/dist/@loader-tools/transform.js +114 -0
- package/dist/@loader-tools/transform.js.map +1 -0
- package/dist/@loader-tools/virtualUrl.d.ts +9 -0
- package/dist/@loader-tools/virtualUrl.js +40 -0
- package/dist/@loader-tools/virtualUrl.js.map +1 -0
- package/dist/@tool-jopinb/index.d.ts +1 -0
- package/dist/@tool-jopinb/index.js +9 -0
- package/dist/@tool-jopinb/index.js.map +1 -0
- package/dist/@ui/components.d.ts +27 -0
- package/dist/@ui/components.js +42 -0
- package/dist/@ui/components.js.map +1 -0
- package/dist/@ui/cssModules.d.ts +11 -0
- package/dist/@ui/cssModules.js +17 -0
- package/dist/@ui/cssModules.js.map +1 -0
- package/dist/@ui/hooks.d.ts +31 -0
- package/dist/@ui/hooks.js +71 -0
- package/dist/@ui/hooks.js.map +1 -0
- package/dist/@ui/index.d.ts +9 -0
- package/dist/@ui/index.js +11 -0
- package/dist/@ui/index.js.map +1 -0
- package/dist/@ui/internal.d.ts +4 -0
- package/dist/@ui/internal.js +10 -0
- package/dist/@ui/internal.js.map +1 -0
- package/dist/@ui/modules.d.ts +41 -0
- package/dist/@ui/modules.js +74 -0
- package/dist/@ui/modules.js.map +1 -0
- package/dist/@ui/objectRegistry.d.ts +12 -0
- package/dist/@ui/objectRegistry.js +35 -0
- package/dist/@ui/objectRegistry.js.map +1 -0
- package/dist/@ui/pageController.d.ts +61 -0
- package/dist/@ui/pageController.js +166 -0
- package/dist/@ui/pageController.js.map +1 -0
- package/dist/@ui/tools.d.ts +24 -0
- package/dist/@ui/tools.js +78 -0
- package/dist/@ui/tools.js.map +1 -0
- package/dist/@uikit/core/UiKitModule.d.ts +6 -0
- package/dist/@uikit/core/UiKitModule.js +18 -0
- package/dist/@uikit/core/UiKitModule.js.map +1 -0
- package/dist/@uikit/core/index.d.ts +1 -0
- package/dist/@uikit/core/index.js +4 -0
- package/dist/@uikit/core/index.js.map +1 -0
- package/dist/@uikit/core/jBundler_ifBrowser.d.ts +1 -0
- package/dist/@uikit/core/jBundler_ifBrowser.js +5 -0
- package/dist/@uikit/core/jBundler_ifBrowser.js.map +1 -0
- package/dist/@uikit/core/jBundler_ifServer.d.ts +6 -0
- package/dist/@uikit/core/jBundler_ifServer.js +17 -0
- package/dist/@uikit/core/jBundler_ifServer.js.map +1 -0
- package/dist/@uikit/forms/components.d.ts +18 -0
- package/dist/@uikit/forms/components.js +69 -0
- package/dist/@uikit/forms/components.js.map +1 -0
- package/dist/@uikit/forms/hooks.d.ts +4 -0
- package/dist/@uikit/forms/hooks.js +31 -0
- package/dist/@uikit/forms/hooks.js.map +1 -0
- package/dist/@uikit/forms/index.d.ts +3 -0
- package/dist/@uikit/forms/index.js +4 -0
- package/dist/@uikit/forms/index.js.map +1 -0
- package/dist/@uikit/forms/interfaces.d.ts +101 -0
- package/dist/@uikit/forms/interfaces.js +4 -0
- package/dist/@uikit/forms/interfaces.js.map +1 -0
- package/dist/@uikit/forms/private.d.ts +40 -0
- package/dist/@uikit/forms/private.js +307 -0
- package/dist/@uikit/forms/private.js.map +1 -0
- package/dist/@uikit/helpers/hooks.d.ts +33 -0
- package/dist/@uikit/helpers/hooks.js +107 -0
- package/dist/@uikit/helpers/hooks.js.map +1 -0
- package/dist/@uikit/helpers/index.d.ts +2 -0
- package/dist/@uikit/helpers/index.js +3 -0
- package/dist/@uikit/helpers/index.js.map +1 -0
- package/dist/@uikit/helpers/tools.d.ts +8 -0
- package/dist/@uikit/helpers/tools.js +35 -0
- package/dist/@uikit/helpers/tools.js.map +1 -0
- package/dist/@uikit/index.d.ts +10 -0
- package/dist/@uikit/index.js +13 -0
- package/dist/@uikit/index.js.map +1 -0
- package/dist/@uikit/menu/core.d.ts +21 -0
- package/dist/@uikit/menu/core.js +191 -0
- package/dist/@uikit/menu/core.js.map +1 -0
- package/dist/@uikit/menu/hooks.d.ts +5 -0
- package/dist/@uikit/menu/hooks.js +24 -0
- package/dist/@uikit/menu/hooks.js.map +1 -0
- package/dist/@uikit/menu/index.d.ts +3 -0
- package/dist/@uikit/menu/index.js +4 -0
- package/dist/@uikit/menu/index.js.map +1 -0
- package/dist/@uikit/menu/interfaces.d.ts +20 -0
- package/dist/@uikit/menu/interfaces.js +8 -0
- package/dist/@uikit/menu/interfaces.js.map +1 -0
- package/dist/@uikit/menu/internal.d.ts +40 -0
- package/dist/@uikit/menu/internal.js +191 -0
- package/dist/@uikit/menu/internal.js.map +1 -0
- package/dist/@uikit/reactRouter/hooks/jBundler_ifBrowser.d.ts +18 -0
- package/dist/@uikit/reactRouter/hooks/jBundler_ifBrowser.js +40 -0
- package/dist/@uikit/reactRouter/hooks/jBundler_ifBrowser.js.map +1 -0
- package/dist/@uikit/reactRouter/hooks/jBundler_ifServer.d.ts +28 -0
- package/dist/@uikit/reactRouter/hooks/jBundler_ifServer.js +35 -0
- package/dist/@uikit/reactRouter/hooks/jBundler_ifServer.js.map +1 -0
- package/dist/@uikit/reactRouter/index.d.ts +1 -0
- package/dist/@uikit/reactRouter/index.js +2 -0
- package/dist/@uikit/reactRouter/index.js.map +1 -0
- package/dist/@uikit/users/hooks.d.ts +10 -0
- package/dist/@uikit/users/hooks.js +39 -0
- package/dist/@uikit/users/hooks.js.map +1 -0
- package/dist/@uikit/users/index.d.ts +1 -0
- package/dist/@uikit/users/index.js +2 -0
- package/dist/@uikit/users/index.js.map +1 -0
- package/dist/@uikit/variants/index.d.ts +7 -0
- package/dist/@uikit/variants/index.js +16 -0
- package/dist/@uikit/variants/index.js.map +1 -0
- package/package.json +115 -0
- package/src/@bundler/README.md +1 -0
- package/src/@bundler/_logs.ts +4 -0
- package/src/@bundler/core.ts +41 -0
- package/src/@bundler/esbuild.ts +141 -0
- package/src/@bundler/index.ts +3 -0
- package/src/@bundler/plugins.ts +163 -0
- package/src/@bundler/tailwind.ts +139 -0
- package/src/@core/PageComponent.tsx +25 -0
- package/src/@core/README.md +1 -0
- package/src/@core/_logs.ts +11 -0
- package/src/@core/automaticStartStop.ts +132 -0
- package/src/@core/browserCacheControl.ts +40 -0
- package/src/@core/bundler/bundler.ts +128 -0
- package/src/@core/bundler/common.ts +18 -0
- package/src/@core/bundler/config.ts +37 -0
- package/src/@core/bundler/extraContent.ts +30 -0
- package/src/@core/bundler/pagesGenerator.ts +194 -0
- package/src/@core/bundler/server.ts +41 -0
- package/src/@core/caches/InMemoryCache.ts +483 -0
- package/src/@core/caches/SimpleFileCache.ts +205 -0
- package/src/@core/caches/cache.ts +77 -0
- package/src/@core/caches/webSiteMirrorCache.ts +90 -0
- package/src/@core/cheerio.d.ts +332 -0
- package/src/@core/gzip.ts +33 -0
- package/src/@core/index.ts +23 -0
- package/src/@core/internalTools.ts +95 -0
- package/src/@core/jQuery.ts +22 -0
- package/src/@core/jopiEasy.ts +1285 -0
- package/src/@core/jopiRequest.tsx +1279 -0
- package/src/@core/jopiServer.ts +188 -0
- package/src/@core/jopiWebSite.tsx +1027 -0
- package/src/@core/letsEncrypt.ts +243 -0
- package/src/@core/linker.ts +42 -0
- package/src/@core/loadBalancing.ts +152 -0
- package/src/@core/middlewares/CorsMiddleware.ts +23 -0
- package/src/@core/middlewares/DdosProtection.ts +120 -0
- package/src/@core/middlewares/index.ts +16 -0
- package/src/@core/publicTools.ts +14 -0
- package/src/@core/routeConfig.ts +104 -0
- package/src/@core/searchParamFilter.ts +315 -0
- package/src/@core/serverFetch.ts +454 -0
- package/src/@core/serverImpl/server_bunjs.tsx +230 -0
- package/src/@core/serverImpl/server_nodejs.ts +312 -0
- package/src/@core/serverInstanceBuilder.ts +36 -0
- package/src/@core/userStores.ts +34 -0
- package/src/@crawler/README.md +1 -0
- package/src/@crawler/common.ts +275 -0
- package/src/@crawler/core.ts +678 -0
- package/src/@crawler/directFileCache.ts +69 -0
- package/src/@crawler/index.ts +4 -0
- package/src/@crawler/urlMapping.ts +67 -0
- package/src/@crawler/utils.ts +13 -0
- package/src/@generated/index.ts +134 -0
- package/src/@linker/arobaseTypes.ts +325 -0
- package/src/@linker/changeProof.ts +53 -0
- package/src/@linker/config.ts +46 -0
- package/src/@linker/engine.ts +865 -0
- package/src/@linker/index.ts +3 -0
- package/src/@linker/install.ts +39 -0
- package/src/@linker/modInstaller.ts +50 -0
- package/src/@linker/typeEvents.ts +58 -0
- package/src/@linker/typeRoutes.ts +255 -0
- package/src/@linker/typeUiComposite.ts +19 -0
- package/src/@loader/README.md +4 -0
- package/src/@loader/bunHtmlCompiler.mjs +27 -0
- package/src/@loader/index.ts +19 -0
- package/src/@loader/loader.mjs +7 -0
- package/src/@loader/nodeJsLoader.ts +21 -0
- package/src/@loader-client/README.md +2 -0
- package/src/@loader-client/index.ts +108 -0
- package/src/@loader-tools/README.md +6 -0
- package/src/@loader-tools/bunJsLoader.ts +33 -0
- package/src/@loader-tools/config.ts +142 -0
- package/src/@loader-tools/cssModuleCompiler.ts +76 -0
- package/src/@loader-tools/esBuildPlugin.ts +142 -0
- package/src/@loader-tools/index.ts +11 -0
- package/src/@loader-tools/jopin.ts +403 -0
- package/src/@loader-tools/nodeJsLoader.ts +119 -0
- package/src/@loader-tools/nodeJsResolver.ts +140 -0
- package/src/@loader-tools/rules.ts +45 -0
- package/src/@loader-tools/sourceChangesWatcher.ts +225 -0
- package/src/@loader-tools/tools.ts +139 -0
- package/src/@loader-tools/transform.ts +138 -0
- package/src/@loader-tools/virtualUrl.ts +57 -0
- package/src/@loader-types/README.md +15 -0
- package/src/@loader-types/extensions.d.ts +65 -0
- package/src/@tool-jopinb/README.md +1 -0
- package/src/@tool-jopinb/index.ts +11 -0
- package/src/@ui/README.md +3 -0
- package/src/@ui/components.tsx +49 -0
- package/src/@ui/cssModules.tsx +27 -0
- package/src/@ui/hooks.tsx +95 -0
- package/src/@ui/index.ts +13 -0
- package/src/@ui/internal.ts +12 -0
- package/src/@ui/modules.ts +100 -0
- package/src/@ui/objectRegistry.ts +50 -0
- package/src/@ui/pageController.ts +203 -0
- package/src/@ui/tools.ts +116 -0
- package/src/@uikit/README.md +1 -0
- package/src/@uikit/core/UiKitModule.ts +20 -0
- package/src/@uikit/core/index.ts +4 -0
- package/src/@uikit/core/jBundler_ifBrowser.ts +4 -0
- package/src/@uikit/core/jBundler_ifServer.ts +18 -0
- package/src/@uikit/forms/components.tsx +97 -0
- package/src/@uikit/forms/hooks.ts +38 -0
- package/src/@uikit/forms/index.ts +3 -0
- package/src/@uikit/forms/interfaces.ts +159 -0
- package/src/@uikit/forms/private.ts +365 -0
- package/src/@uikit/helpers/hooks.ts +133 -0
- package/src/@uikit/helpers/index.ts +2 -0
- package/src/@uikit/helpers/tools.ts +39 -0
- package/src/@uikit/index.ts +15 -0
- package/src/@uikit/menu/core.ts +227 -0
- package/src/@uikit/menu/hooks.ts +28 -0
- package/src/@uikit/menu/index.ts +3 -0
- package/src/@uikit/menu/interfaces.ts +26 -0
- package/src/@uikit/menu/internal.ts +218 -0
- package/src/@uikit/package.json +15 -0
- package/src/@uikit/reactRouter/hooks/jBundler_ifBrowser.tsx +59 -0
- package/src/@uikit/reactRouter/hooks/jBundler_ifServer.tsx +51 -0
- package/src/@uikit/reactRouter/index.ts +1 -0
- package/src/@uikit/users/hooks.ts +50 -0
- package/src/@uikit/users/index.ts +1 -0
- package/src/@uikit/variants/index.tsx +20 -0
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ServerFetch } from "./serverFetch.js";
|
|
3
|
+
import React, {} from "react";
|
|
4
|
+
import { PageController_ExposePrivate } from "jopijs/ui";
|
|
5
|
+
import * as ReactServer from "react-dom/server";
|
|
6
|
+
import * as cheerio from "cheerio";
|
|
7
|
+
import * as jk_schema from "jopi-toolkit/jk_schema";
|
|
8
|
+
import * as jk_what from "jopi-toolkit/jk_what";
|
|
9
|
+
import * as jk_fs from "jopi-toolkit/jk_fs";
|
|
10
|
+
import Page from "./PageComponent.js";
|
|
11
|
+
import { initCheerio } from "./jQuery.js";
|
|
12
|
+
import {} from "./caches/cache.js";
|
|
13
|
+
import { SBPE_DirectSendThisResponseException, SBPE_NotAuthorizedException, WebSiteImpl } from "./jopiWebSite.js";
|
|
14
|
+
import { parseCookies } from "./internalTools.js";
|
|
15
|
+
import * as jk_term from "jopi-toolkit/jk_term";
|
|
16
|
+
import { isNodeJS } from "jopi-toolkit/jk_what";
|
|
17
|
+
import { isSinglePageMode } from "jopijs/loader-client";
|
|
18
|
+
import { createBundleForPage } from "./bundler/bundler.js";
|
|
19
|
+
import {} from "./browserCacheControl.js";
|
|
20
|
+
import { WebSiteMirrorCache } from "./caches/webSiteMirrorCache.js";
|
|
21
|
+
export class JopiRequest {
|
|
22
|
+
webSite;
|
|
23
|
+
_urlInfos;
|
|
24
|
+
coreRequest;
|
|
25
|
+
coreServer;
|
|
26
|
+
routeInfos;
|
|
27
|
+
cache;
|
|
28
|
+
mainCache;
|
|
29
|
+
cookies;
|
|
30
|
+
_headers;
|
|
31
|
+
constructor(webSite, _urlInfos, coreRequest, coreServer, routeInfos) {
|
|
32
|
+
this.webSite = webSite;
|
|
33
|
+
this._urlInfos = _urlInfos;
|
|
34
|
+
this.coreRequest = coreRequest;
|
|
35
|
+
this.coreServer = coreServer;
|
|
36
|
+
this.routeInfos = routeInfos;
|
|
37
|
+
this.cache = webSite.mainCache;
|
|
38
|
+
this.mainCache = this.cache;
|
|
39
|
+
this._headers = this.coreRequest.headers;
|
|
40
|
+
}
|
|
41
|
+
//region Properties
|
|
42
|
+
_customData;
|
|
43
|
+
get urlInfos() {
|
|
44
|
+
if (!this._urlInfos) {
|
|
45
|
+
this._urlInfos = new URL(this.coreRequest.url);
|
|
46
|
+
this._urlInfos.hash = "";
|
|
47
|
+
}
|
|
48
|
+
return this._urlInfos;
|
|
49
|
+
}
|
|
50
|
+
get customData() {
|
|
51
|
+
if (!this._customData)
|
|
52
|
+
this._customData = {};
|
|
53
|
+
return this._customData;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Return the verb used for the request (GET, POST, PUT, DELETE, ...)
|
|
57
|
+
*/
|
|
58
|
+
get method() {
|
|
59
|
+
return this.coreRequest.method;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Return the content type of the request.
|
|
63
|
+
*/
|
|
64
|
+
get reqContentType() {
|
|
65
|
+
return this.coreRequest.headers.get("content-type");
|
|
66
|
+
}
|
|
67
|
+
get url() {
|
|
68
|
+
return this.coreRequest.url;
|
|
69
|
+
}
|
|
70
|
+
get body() {
|
|
71
|
+
return this.coreRequest.body;
|
|
72
|
+
}
|
|
73
|
+
get headers() {
|
|
74
|
+
return this._headers;
|
|
75
|
+
}
|
|
76
|
+
set headers(value) {
|
|
77
|
+
this._headers = value;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The part of the url.
|
|
81
|
+
* if : https://mywebsite/product-name/list
|
|
82
|
+
* and route http://mywebsite/:product/list
|
|
83
|
+
* then urlParts contains {product: "product-name"}
|
|
84
|
+
*/
|
|
85
|
+
urlParts;
|
|
86
|
+
/**
|
|
87
|
+
* Returns the url search params.
|
|
88
|
+
* For "https://my-site/?sort=asc&filter=jopi", it returns {sort: "asc", filter: "jopi"}.
|
|
89
|
+
*/
|
|
90
|
+
get urlSearchParams() {
|
|
91
|
+
const sp = this.urlInfos.searchParams;
|
|
92
|
+
if (!sp.size)
|
|
93
|
+
return {};
|
|
94
|
+
const res = {};
|
|
95
|
+
sp.forEach((value, key) => res[key] = value);
|
|
96
|
+
return res;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Returns information on the caller IP.
|
|
100
|
+
*/
|
|
101
|
+
get requestIP() {
|
|
102
|
+
return this.coreServer.requestIP(this.coreRequest);
|
|
103
|
+
}
|
|
104
|
+
get isFromLocalhost() {
|
|
105
|
+
const ip = this.requestIP;
|
|
106
|
+
if (!ip)
|
|
107
|
+
return false;
|
|
108
|
+
const address = ip.address;
|
|
109
|
+
switch (address) {
|
|
110
|
+
case "::1":
|
|
111
|
+
case "127.0.0.1":
|
|
112
|
+
case "::ffff:127.0.0.1":
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
//endregion
|
|
118
|
+
//region Body transforming
|
|
119
|
+
/**
|
|
120
|
+
* Returns all the data about the request.
|
|
121
|
+
* It's concat all data source.
|
|
122
|
+
*
|
|
123
|
+
* - The url parts.
|
|
124
|
+
* - The search param (query string).
|
|
125
|
+
* - The POST/PUT data if available.
|
|
126
|
+
*/
|
|
127
|
+
async req_getData(options) {
|
|
128
|
+
let res = {};
|
|
129
|
+
if (!(options && options.ignoreUrl)) {
|
|
130
|
+
const searchParams = this.urlInfos.searchParams;
|
|
131
|
+
if (searchParams.size) {
|
|
132
|
+
searchParams.forEach((value, key) => res[key] = value);
|
|
133
|
+
}
|
|
134
|
+
if (this.urlParts) {
|
|
135
|
+
res = { ...res, ...this.urlParts };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (this.req_isBodyJson) {
|
|
139
|
+
try {
|
|
140
|
+
const asJson = await this.req_bodyAsJson();
|
|
141
|
+
if (asJson)
|
|
142
|
+
res = { ...res, ...asJson };
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// If JSON is invalid.
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if (this.req_isBodyXFormUrlEncoded) {
|
|
149
|
+
try {
|
|
150
|
+
let data = await this.req_bodyAsText();
|
|
151
|
+
new URLSearchParams(data).forEach((value, key) => res[key] = value);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// If invalid.
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (this.req_isBodyFormData) {
|
|
158
|
+
try {
|
|
159
|
+
const asFormData = await this.req_bodyAsFormData();
|
|
160
|
+
asFormData.forEach((value, key) => res[key] = value);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// If FormData is invalid.
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (options && options.dataSchema) {
|
|
167
|
+
this.tool_validateDataSchema(res, options.dataSchema);
|
|
168
|
+
}
|
|
169
|
+
return res;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get the request body and decode it properly.
|
|
173
|
+
*/
|
|
174
|
+
async req_getBodyData(options) {
|
|
175
|
+
let res = {};
|
|
176
|
+
if (this.req_isBodyJson) {
|
|
177
|
+
try {
|
|
178
|
+
const asJson = await this.req_bodyAsJson();
|
|
179
|
+
if (asJson)
|
|
180
|
+
res = { ...res, ...asJson };
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// If JSON is invalid.
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (this.req_isBodyXFormUrlEncoded) {
|
|
187
|
+
try {
|
|
188
|
+
let data = await this.req_bodyAsText();
|
|
189
|
+
new URLSearchParams(data).forEach((value, key) => res[key] = value);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// If invalid.
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else if (this.req_isBodyFormData) {
|
|
196
|
+
try {
|
|
197
|
+
const asFormData = await this.req_bodyAsFormData();
|
|
198
|
+
asFormData.forEach((value, key) => res[key] = value);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// If FormData is invalid.
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (options && options.dataSchema) {
|
|
205
|
+
this.tool_validateDataSchema(res, options.dataSchema);
|
|
206
|
+
}
|
|
207
|
+
return res;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Returns all the data about the request, organized by category.
|
|
211
|
+
*/
|
|
212
|
+
async req_getDataInfos() {
|
|
213
|
+
let res = {};
|
|
214
|
+
const searchParams = this.urlInfos.searchParams;
|
|
215
|
+
if (searchParams.size) {
|
|
216
|
+
const t = res.searchParams = {};
|
|
217
|
+
searchParams.forEach((value, key) => t[key] = value);
|
|
218
|
+
}
|
|
219
|
+
if (this.urlParts) {
|
|
220
|
+
res.urlParts = { ...this.urlParts };
|
|
221
|
+
}
|
|
222
|
+
if (this.req_isBodyJson) {
|
|
223
|
+
try {
|
|
224
|
+
res.body = await this.req_bodyAsJson();
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// If JSON is invalid.
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else if (this.req_isBodyFormData) {
|
|
231
|
+
try {
|
|
232
|
+
const t = res.formData = {};
|
|
233
|
+
const asFormData = await this.req_bodyAsFormData();
|
|
234
|
+
asFormData.forEach((value, key) => t[key] = value);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// If FormData is invalid.
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else if (this.req_isBodyXFormUrlEncoded) {
|
|
241
|
+
try {
|
|
242
|
+
let data = await this.req_bodyAsText();
|
|
243
|
+
const t = res.formUrlEncoded = {};
|
|
244
|
+
new URLSearchParams(data).forEach((value, key) => t[key] = value);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// If invalid.
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return res;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Request/bodyUsed
|
|
254
|
+
*/
|
|
255
|
+
get req_isBodyUsed() {
|
|
256
|
+
return this.coreRequest.bodyUsed;
|
|
257
|
+
}
|
|
258
|
+
get req_isBodyJson() {
|
|
259
|
+
const ct = this.reqContentType;
|
|
260
|
+
if (ct === null)
|
|
261
|
+
return false;
|
|
262
|
+
return ct.startsWith("application/json");
|
|
263
|
+
}
|
|
264
|
+
get req_isBodyFormData() {
|
|
265
|
+
const ct = this.reqContentType;
|
|
266
|
+
if (ct === null)
|
|
267
|
+
return false;
|
|
268
|
+
return ct.startsWith("multipart/form-data");
|
|
269
|
+
}
|
|
270
|
+
get req_isBodyXFormUrlEncoded() {
|
|
271
|
+
const ct = this.reqContentType;
|
|
272
|
+
if (ct === null)
|
|
273
|
+
return false;
|
|
274
|
+
return ct.startsWith("application/x-www-form-urlencoded");
|
|
275
|
+
}
|
|
276
|
+
req_bodyAsText() {
|
|
277
|
+
return this.coreRequest.text();
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Validate the data Schema.
|
|
281
|
+
* If invalid, throw a special exception allowing
|
|
282
|
+
* to directly send a response to the caller.
|
|
283
|
+
*/
|
|
284
|
+
tool_validateDataSchema(data, schema) {
|
|
285
|
+
let error = jk_schema.validateSchema(data, schema);
|
|
286
|
+
if (error) {
|
|
287
|
+
throw new SBPE_DirectSendThisResponseException(() => {
|
|
288
|
+
return this.res_returnError400_BadRequest("Invalid data");
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async req_bodyAsJson(dataSchema) {
|
|
293
|
+
if (dataSchema) {
|
|
294
|
+
const data = await this.req_bodyAsJson();
|
|
295
|
+
this.tool_validateDataSchema(data, dataSchema);
|
|
296
|
+
return data;
|
|
297
|
+
}
|
|
298
|
+
return await this.coreRequest.json();
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Request/arrayBuffer
|
|
302
|
+
*/
|
|
303
|
+
req_bodyAsArrayBuffer() {
|
|
304
|
+
return this.coreRequest.arrayBuffer();
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Request/blob
|
|
308
|
+
*/
|
|
309
|
+
req_bodyAsBlob() {
|
|
310
|
+
return this.coreRequest.blob();
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Request/bytes
|
|
314
|
+
*/
|
|
315
|
+
req_bodyAsBytes() {
|
|
316
|
+
return this.coreRequest.bytes();
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Request/formData
|
|
320
|
+
*/
|
|
321
|
+
req_bodyAsFormData() {
|
|
322
|
+
return this.coreRequest.formData();
|
|
323
|
+
}
|
|
324
|
+
//endregion
|
|
325
|
+
//region Request timeout
|
|
326
|
+
/**
|
|
327
|
+
* When DDOS protection is enabled, the request has a timeout of 60 seconds.
|
|
328
|
+
* Here it'd allow you to extend this time for a request you knew was slow.
|
|
329
|
+
*/
|
|
330
|
+
req_extendTimeout_sec(sec) {
|
|
331
|
+
this.coreServer.timeout(this.coreRequest, sec);
|
|
332
|
+
}
|
|
333
|
+
//endregion
|
|
334
|
+
//region Response helpers
|
|
335
|
+
res_redirectResponse(permanent = false, url) {
|
|
336
|
+
if (!url)
|
|
337
|
+
url = this.urlInfos;
|
|
338
|
+
return new Response(null, { status: permanent ? 301 : 302, headers: { "location": url.toString() } });
|
|
339
|
+
}
|
|
340
|
+
res_textResponse(text, statusCode = 200) {
|
|
341
|
+
return new Response(text, { status: statusCode, headers: { "content-type": "text/plain;charset=utf-8" } });
|
|
342
|
+
}
|
|
343
|
+
res_returnResultMessage(isOk, message) {
|
|
344
|
+
return this.res_jsonResponse({ isOk, message });
|
|
345
|
+
}
|
|
346
|
+
res_htmlResponse(html, statusCode = 200) {
|
|
347
|
+
return new Response(html, { status: statusCode, headers: { "content-type": "text/html;charset=utf-8" } });
|
|
348
|
+
}
|
|
349
|
+
res_jsonResponse(json, statusCode = 200) {
|
|
350
|
+
return new Response(JSON.stringify(json), {
|
|
351
|
+
status: statusCode,
|
|
352
|
+
headers: { "content-type": "application/json;charset=utf-8" }
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
res_jsonStringResponse(json, statusCode = 200) {
|
|
356
|
+
return new Response(json, { status: statusCode, headers: { "content-type": "application/json;charset=utf-8" } });
|
|
357
|
+
}
|
|
358
|
+
res_returnError404_NotFound() {
|
|
359
|
+
return this.webSite.return404(this);
|
|
360
|
+
}
|
|
361
|
+
res_returnError500_ServerError(error) {
|
|
362
|
+
return this.webSite.return500(this, error);
|
|
363
|
+
}
|
|
364
|
+
res_returnError401_Unauthorized(error) {
|
|
365
|
+
return this.webSite.return401(this, error);
|
|
366
|
+
}
|
|
367
|
+
res_returnError400_BadRequest(error) {
|
|
368
|
+
return Promise.resolve(new Response(error ? error.toString() : "Bad request", { status: 400 }));
|
|
369
|
+
}
|
|
370
|
+
//endregion
|
|
371
|
+
//region Fetch / Proxy
|
|
372
|
+
proxy_directProxyToServer() {
|
|
373
|
+
return this.webSite.loadBalancer.directProxy(this);
|
|
374
|
+
}
|
|
375
|
+
proxy_proxyRequestTo(server) {
|
|
376
|
+
return server.directProxy(this);
|
|
377
|
+
}
|
|
378
|
+
proxy_directProxyWith(server) {
|
|
379
|
+
return server.directProxy(this);
|
|
380
|
+
}
|
|
381
|
+
proxy_fetchServer(headers, method = "GET", url, body) {
|
|
382
|
+
if (!url)
|
|
383
|
+
url = this.urlInfos;
|
|
384
|
+
return this.webSite.loadBalancer.fetch(method, url, body, headers);
|
|
385
|
+
}
|
|
386
|
+
//endregion
|
|
387
|
+
//region Cache
|
|
388
|
+
_isAddedToCache = false;
|
|
389
|
+
/**
|
|
390
|
+
* Get from the cache the entry corresponding to the current url.
|
|
391
|
+
*/
|
|
392
|
+
async cache_getFromCache() {
|
|
393
|
+
return await this.cache.getFromCache(this, this.urlInfos);
|
|
394
|
+
}
|
|
395
|
+
async cache_hasInCache() {
|
|
396
|
+
return await this.cache.hasInCache(this.urlInfos);
|
|
397
|
+
}
|
|
398
|
+
cache_removeFromCache(url) {
|
|
399
|
+
// Avoid double.
|
|
400
|
+
//
|
|
401
|
+
if (!url) {
|
|
402
|
+
url = this.urlInfos;
|
|
403
|
+
url.hostname = url.hostname.toLowerCase();
|
|
404
|
+
url.pathname = url.pathname.toLowerCase();
|
|
405
|
+
}
|
|
406
|
+
return this.cache.removeFromCache(url || this.urlInfos);
|
|
407
|
+
}
|
|
408
|
+
cache_addToCache(response) {
|
|
409
|
+
// Avoid adding two times in the same request.
|
|
410
|
+
// This is required with automatic add functionnality.
|
|
411
|
+
//
|
|
412
|
+
if (this._isAddedToCache)
|
|
413
|
+
return;
|
|
414
|
+
this._isAddedToCache = false;
|
|
415
|
+
return this.cache.addToCache(this, this.urlInfos, response, this.webSite.getHeadersToCache());
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Allow using a sub-cache.
|
|
419
|
+
* For example, a cache dedicated per user.
|
|
420
|
+
*/
|
|
421
|
+
cache_useCache(cache) {
|
|
422
|
+
this.cache = cache;
|
|
423
|
+
}
|
|
424
|
+
cache_getSubCache(name) {
|
|
425
|
+
return this.cache.createSubCache(name);
|
|
426
|
+
}
|
|
427
|
+
cache_getCacheEntryIterator() {
|
|
428
|
+
return this.cache.getCacheEntryIterator();
|
|
429
|
+
}
|
|
430
|
+
//endregion
|
|
431
|
+
//region Test type / React on type
|
|
432
|
+
resValue_getContentTypeOf(response) {
|
|
433
|
+
return response.headers.get("content-type");
|
|
434
|
+
}
|
|
435
|
+
resValue_getContentTypeCategory(response) {
|
|
436
|
+
const contentType = response.headers.get("content-type");
|
|
437
|
+
if (!contentType)
|
|
438
|
+
return ContentTypeCategory.OTHER;
|
|
439
|
+
if (contentType.startsWith("text/")) {
|
|
440
|
+
if (contentType.startsWith("html", 5)) {
|
|
441
|
+
return ContentTypeCategory.TEXT_HTML;
|
|
442
|
+
}
|
|
443
|
+
else if (contentType.startsWith("css")) {
|
|
444
|
+
return ContentTypeCategory.TEXT_CSS;
|
|
445
|
+
}
|
|
446
|
+
else if (contentType.startsWith("javascript", 5)) {
|
|
447
|
+
return ContentTypeCategory.TEXT_JAVASCRIPT;
|
|
448
|
+
}
|
|
449
|
+
else if (contentType.startsWith("json")) {
|
|
450
|
+
return ContentTypeCategory.TEXT_JSON;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
else if (contentType.startsWith("image")) {
|
|
454
|
+
return ContentTypeCategory.IMAGE;
|
|
455
|
+
}
|
|
456
|
+
else if (contentType.startsWith("application")) {
|
|
457
|
+
if (contentType.startsWith("x-www-form-urlencoded", 12)) {
|
|
458
|
+
return ContentTypeCategory.FORM_URL_ENCODED;
|
|
459
|
+
}
|
|
460
|
+
else if (contentType.startsWith("json", 12)) {
|
|
461
|
+
return ContentTypeCategory.TEXT_JSON;
|
|
462
|
+
}
|
|
463
|
+
else if (contentType.startsWith("javascript", 12)) {
|
|
464
|
+
return ContentTypeCategory.TEXT_JAVASCRIPT;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
else if (contentType.startsWith("multipart/form-data")) {
|
|
468
|
+
return ContentTypeCategory.FORM_MULTIPART;
|
|
469
|
+
}
|
|
470
|
+
return ContentTypeCategory.OTHER;
|
|
471
|
+
}
|
|
472
|
+
resValue_isHtml(response) {
|
|
473
|
+
const contentType = response.headers.get("content-type");
|
|
474
|
+
if (contentType === null)
|
|
475
|
+
return false;
|
|
476
|
+
return contentType.startsWith("text/html");
|
|
477
|
+
}
|
|
478
|
+
resValue_isCss(response) {
|
|
479
|
+
const contentType = response.headers.get("content-type");
|
|
480
|
+
if (contentType === null)
|
|
481
|
+
return false;
|
|
482
|
+
return contentType.startsWith("text/css");
|
|
483
|
+
}
|
|
484
|
+
resValue_isJavascript(response) {
|
|
485
|
+
const contentType = response.headers.get("content-type");
|
|
486
|
+
if (contentType === null)
|
|
487
|
+
return false;
|
|
488
|
+
return contentType.startsWith("application/javascript") || contentType.startsWith("text/javascript");
|
|
489
|
+
}
|
|
490
|
+
resValue_isJson(response) {
|
|
491
|
+
const contentType = response.headers.get("content-type");
|
|
492
|
+
if (contentType === null)
|
|
493
|
+
return false;
|
|
494
|
+
return contentType.startsWith("application/json");
|
|
495
|
+
}
|
|
496
|
+
resValue_isXFormUrlEncoded(response) {
|
|
497
|
+
const contentType = response.headers.get("content-type");
|
|
498
|
+
if (contentType === null)
|
|
499
|
+
return false;
|
|
500
|
+
return contentType.startsWith("x-www-form-urlencoded");
|
|
501
|
+
}
|
|
502
|
+
async resValue_hookIfHtml(res, ...hooks) {
|
|
503
|
+
if (this.resValue_isHtml(res)) {
|
|
504
|
+
if (isNodeJS) {
|
|
505
|
+
let headers = new Headers(res.headers);
|
|
506
|
+
headers.delete("content-length");
|
|
507
|
+
headers.delete("content-encoding");
|
|
508
|
+
let newHTML = await this.resValue_applyTextModifiers(res, hooks);
|
|
509
|
+
return new Response(newHTML, { status: res.status, headers });
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
res.headers.delete("content-length");
|
|
513
|
+
res.headers.delete("content-encoding");
|
|
514
|
+
return new Response(await this.resValue_applyTextModifiers(res, hooks), { status: res.status, headers: res.headers });
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return Promise.resolve(res);
|
|
518
|
+
}
|
|
519
|
+
async resValue_hookIfCss(res, ...hooks) {
|
|
520
|
+
if (this.resValue_isCss(res)) {
|
|
521
|
+
return new Response(await this.resValue_applyTextModifiers(res, hooks), { status: res.status, headers: res.headers });
|
|
522
|
+
}
|
|
523
|
+
return Promise.resolve(res);
|
|
524
|
+
}
|
|
525
|
+
async resValue_hookIfJavascript(res, ...hooks) {
|
|
526
|
+
if (this.resValue_isJavascript(res)) {
|
|
527
|
+
return new Response(await this.resValue_applyTextModifiers(res, hooks), { status: res.status, headers: res.headers });
|
|
528
|
+
}
|
|
529
|
+
return Promise.resolve(res);
|
|
530
|
+
}
|
|
531
|
+
async resValue_applyTextModifiers(res, hooks) {
|
|
532
|
+
let text = await res.text();
|
|
533
|
+
for (const hook of hooks) {
|
|
534
|
+
const hRes = hook(text, this);
|
|
535
|
+
text = hRes instanceof Promise ? await hRes : hRes;
|
|
536
|
+
}
|
|
537
|
+
return text;
|
|
538
|
+
}
|
|
539
|
+
async resValue_executeModifiers(res, hooks) {
|
|
540
|
+
for (const hook of hooks) {
|
|
541
|
+
const hRes = hook(res, this);
|
|
542
|
+
res = hRes instanceof Promise ? await hRes : hRes;
|
|
543
|
+
}
|
|
544
|
+
return res;
|
|
545
|
+
}
|
|
546
|
+
async resValue_replaceWebSiteOrigin(res, toReplace, redirectionCode) {
|
|
547
|
+
let location = res.headers.get("location");
|
|
548
|
+
if (location) {
|
|
549
|
+
const thisOrigin = this.webSite.getWelcomeUrl();
|
|
550
|
+
location = location.replace(toReplace, thisOrigin);
|
|
551
|
+
if (location.startsWith("/"))
|
|
552
|
+
location = thisOrigin + location;
|
|
553
|
+
res = Response.redirect(location, redirectionCode ? redirectionCode : res.status);
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
// It's a helper function that allows decoding
|
|
557
|
+
// and re-encoding a response if his content is of type HTML.
|
|
558
|
+
//
|
|
559
|
+
res = await this.resValue_hookIfHtml(res, (html) => {
|
|
560
|
+
const thisOrigin = this.webSite.getWelcomeUrl();
|
|
561
|
+
return html.replaceAll(toReplace, thisOrigin);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return res;
|
|
565
|
+
}
|
|
566
|
+
//endregion
|
|
567
|
+
//region Tools
|
|
568
|
+
async tool_duplicateReadableStream(stream) {
|
|
569
|
+
if (!stream)
|
|
570
|
+
return [null, null];
|
|
571
|
+
return stream.tee();
|
|
572
|
+
}
|
|
573
|
+
async tool_duplicateRawRequest(raw) {
|
|
574
|
+
const [str1, str2] = await this.tool_duplicateReadableStream(raw.body);
|
|
575
|
+
const res1 = new Request(raw.url, {
|
|
576
|
+
body: str1,
|
|
577
|
+
headers: raw.headers,
|
|
578
|
+
method: raw.method
|
|
579
|
+
});
|
|
580
|
+
const res2 = new Request(raw.url, {
|
|
581
|
+
body: str2,
|
|
582
|
+
headers: raw.headers,
|
|
583
|
+
method: raw.method
|
|
584
|
+
});
|
|
585
|
+
return [res1, res2];
|
|
586
|
+
}
|
|
587
|
+
async tool_duplicateResponse(raw) {
|
|
588
|
+
const [str1, str2] = await this.tool_duplicateReadableStream(raw.body);
|
|
589
|
+
const res1 = new Response(str1, {
|
|
590
|
+
status: raw.status,
|
|
591
|
+
headers: raw.headers
|
|
592
|
+
});
|
|
593
|
+
const res2 = new Response(str2, {
|
|
594
|
+
status: raw.status,
|
|
595
|
+
headers: raw.headers
|
|
596
|
+
});
|
|
597
|
+
return [res1, res2];
|
|
598
|
+
}
|
|
599
|
+
async tool_spyRequest(handleRequest) {
|
|
600
|
+
return this.tool_spyRequestData(handleRequest, (data) => {
|
|
601
|
+
this.tool_printSpyRequestData(data);
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
async tool_printSpyRequestData(data) {
|
|
605
|
+
const headerColor = jk_term.buildWriter(jk_term.C_RED);
|
|
606
|
+
const titleColor = jk_term.buildWriter(jk_term.C_ORANGE);
|
|
607
|
+
let resAsText = "";
|
|
608
|
+
//
|
|
609
|
+
try {
|
|
610
|
+
if (data.res) {
|
|
611
|
+
let res = data.res();
|
|
612
|
+
if (!res)
|
|
613
|
+
resAsText = "[NO SET]";
|
|
614
|
+
else
|
|
615
|
+
resAsText = await res.text();
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
resAsText = "[NO SET]";
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
catch {
|
|
622
|
+
}
|
|
623
|
+
console.log();
|
|
624
|
+
console.log(headerColor(this.method, this.url));
|
|
625
|
+
console.log(titleColor("|- referer: "), data.reqReferer);
|
|
626
|
+
console.log(titleColor("|- reqContentType:"), data.reqContentType);
|
|
627
|
+
console.log(titleColor("|- reqData:"), data.reqData);
|
|
628
|
+
console.log(titleColor("|- reqCookie:"), data.reqCookies);
|
|
629
|
+
console.log(titleColor("|- resContentType:"), data.resContentType);
|
|
630
|
+
console.log(titleColor("|- resCookieSet:"), data.resCookieSet);
|
|
631
|
+
console.log(titleColor("|- resHeaders:"), data.resHeaders);
|
|
632
|
+
console.log(titleColor("|- resData:"), resAsText);
|
|
633
|
+
}
|
|
634
|
+
async tool_spyRequestData(handleRequest, onSpy) {
|
|
635
|
+
const [bunNewReq, spyReq] = await this.tool_duplicateRawRequest(this.coreRequest);
|
|
636
|
+
// Required because the body is already consumed.
|
|
637
|
+
this.coreRequest = bunNewReq;
|
|
638
|
+
let res = await handleRequest(this);
|
|
639
|
+
const [bunNewRes, spyRes] = await this.tool_duplicateResponse(res);
|
|
640
|
+
// Required because the body is already consumed.
|
|
641
|
+
this.coreRequest = spyReq;
|
|
642
|
+
onSpy({
|
|
643
|
+
method: this.method,
|
|
644
|
+
res: () => spyRes,
|
|
645
|
+
reqUrl: this.url,
|
|
646
|
+
reqReferer: this.headers.get("referer"),
|
|
647
|
+
reqContentType: this.reqContentType,
|
|
648
|
+
reqData: await this.req_getDataInfos(),
|
|
649
|
+
resContentType: res.headers.get("content-type"),
|
|
650
|
+
resContentTypeCat: this.resValue_getContentTypeCategory(res),
|
|
651
|
+
reqCookies: this.headers.get("cookie"),
|
|
652
|
+
resCookieSet: spyRes.headers.getSetCookie(),
|
|
653
|
+
resStatus: spyRes.status,
|
|
654
|
+
resLocation: spyRes.headers.get("location"),
|
|
655
|
+
resHeaders: spyRes.headers
|
|
656
|
+
}, this);
|
|
657
|
+
return bunNewRes;
|
|
658
|
+
}
|
|
659
|
+
tool_filterSearchParams(filter) {
|
|
660
|
+
if (filter) {
|
|
661
|
+
filter(this.urlInfos);
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
if (this.routeInfos.searchParamFilter) {
|
|
665
|
+
this.routeInfos.searchParamFilter(this.urlInfos);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
//endregion
|
|
670
|
+
//region Post process
|
|
671
|
+
postProcess;
|
|
672
|
+
_applyPostProcess(res) {
|
|
673
|
+
if (!this.postProcess)
|
|
674
|
+
return res;
|
|
675
|
+
this.postProcess.forEach(hook => res = hook(res));
|
|
676
|
+
return res;
|
|
677
|
+
}
|
|
678
|
+
//endregion
|
|
679
|
+
//region Cookies
|
|
680
|
+
cookie_reqHasCookie(name, value) {
|
|
681
|
+
if (!this.cookies)
|
|
682
|
+
this.cookies = parseCookies(this.coreRequest.headers);
|
|
683
|
+
if (value)
|
|
684
|
+
return this.cookies[name] === value;
|
|
685
|
+
return this.cookies[name] !== undefined;
|
|
686
|
+
}
|
|
687
|
+
cookie_getReqCookie(name) {
|
|
688
|
+
if (!this.cookies)
|
|
689
|
+
this.cookies = parseCookies(this.coreRequest.headers);
|
|
690
|
+
return this.cookies[name];
|
|
691
|
+
}
|
|
692
|
+
async cookie_hookIfResHasCookie(res, name, testCookieValue, ...hooks) {
|
|
693
|
+
const cookieValue = this.cookie_getReqCookie(name);
|
|
694
|
+
if (cookieValue) {
|
|
695
|
+
if (testCookieValue && !testCookieValue(cookieValue)) {
|
|
696
|
+
return Promise.resolve(res);
|
|
697
|
+
}
|
|
698
|
+
return this.res_htmlResponse(await this.resValue_applyTextModifiers(res, hooks));
|
|
699
|
+
}
|
|
700
|
+
return Promise.resolve(res);
|
|
701
|
+
}
|
|
702
|
+
cookie_addCookieToRes(cookieName, cookieValue, options) {
|
|
703
|
+
let cookie = `${cookieName}=${cookieValue};`;
|
|
704
|
+
if (options) {
|
|
705
|
+
if (options.maxAge) {
|
|
706
|
+
cookie += ` Max-Age=${options.maxAge};`;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
if (!this.postProcess)
|
|
710
|
+
this.postProcess = [];
|
|
711
|
+
this.postProcess.push((res) => {
|
|
712
|
+
let current = res.headers.get("set-cookie");
|
|
713
|
+
if (current)
|
|
714
|
+
cookie = current + cookie;
|
|
715
|
+
// With node, res.headers is immutable.
|
|
716
|
+
// And a Response object is also immutable.
|
|
717
|
+
// It's why we need to create a new response.
|
|
718
|
+
//
|
|
719
|
+
if (jk_what.isNodeJS) {
|
|
720
|
+
const headers = new Headers(res.headers);
|
|
721
|
+
headers.append("set-cookie", cookie);
|
|
722
|
+
res = new Response(res.body, {
|
|
723
|
+
headers: headers,
|
|
724
|
+
status: res.status
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
res.headers.append("set-cookie", cookie);
|
|
729
|
+
}
|
|
730
|
+
return res;
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
//endregion
|
|
734
|
+
//region ReactJS
|
|
735
|
+
/**
|
|
736
|
+
* Allow rendering a document fully formed from a React component.
|
|
737
|
+
*/
|
|
738
|
+
react_toResponse(E) {
|
|
739
|
+
return this.res_htmlResponse(ReactServer.renderToStaticMarkup(E));
|
|
740
|
+
}
|
|
741
|
+
react_toString(element) {
|
|
742
|
+
return ReactServer.renderToStaticMarkup(element);
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* The new render function.
|
|
746
|
+
* Used while refactoring the renderer.
|
|
747
|
+
* Used while refactoring the renderer.
|
|
748
|
+
*/
|
|
749
|
+
async react_fromPage(pageKey, C) {
|
|
750
|
+
try {
|
|
751
|
+
let bundlePath = "/_bundle/";
|
|
752
|
+
// When dev-mode (JOPI_DEV or JOPI_DEV_UI) then we compile the page one by one.
|
|
753
|
+
//
|
|
754
|
+
if (gIsSinglePageMode) {
|
|
755
|
+
await createBundleForPage(pageKey, this.routeInfos.route);
|
|
756
|
+
bundlePath += pageKey + "/";
|
|
757
|
+
}
|
|
758
|
+
// What we will include in our HTML.
|
|
759
|
+
const options = {
|
|
760
|
+
head: [_jsx("link", { rel: "stylesheet", type: "text/css", href: bundlePath + pageKey + ".css" }, "jopi.mainBundle")],
|
|
761
|
+
bodyEnd: [_jsx("script", { type: "module", src: bundlePath + pageKey + ".js" }, "jopi.mainSript")]
|
|
762
|
+
};
|
|
763
|
+
// Allow faking the environment of the page.
|
|
764
|
+
const controller = new PageController_ExposePrivate(false, this.webSite.mustRemoveTrailingSlashs, options);
|
|
765
|
+
controller.setServerRequest(this);
|
|
766
|
+
this.webSite.executeBrowserInstall(controller);
|
|
767
|
+
const params = this.urlParts;
|
|
768
|
+
const searchParams = this.urlInfos.searchParams;
|
|
769
|
+
const html = ReactServer.renderToStaticMarkup(_jsx(Page, { controller: controller, children: _jsx(C, { params: params, searchParams: searchParams }) }));
|
|
770
|
+
return new Response(html, { status: 200, headers: { "content-type": "text/html;charset=utf-8" } });
|
|
771
|
+
}
|
|
772
|
+
catch (e) {
|
|
773
|
+
console.error(e);
|
|
774
|
+
return await this.res_returnError500_ServerError(e);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
//endregion
|
|
778
|
+
//region JQuery
|
|
779
|
+
jquery_htmlToJquery(html) {
|
|
780
|
+
const res = cheerio.load(html);
|
|
781
|
+
initCheerio(res);
|
|
782
|
+
return res;
|
|
783
|
+
}
|
|
784
|
+
//endregion
|
|
785
|
+
//region JWT Tokens
|
|
786
|
+
/**
|
|
787
|
+
* Create a JWT token with the data.
|
|
788
|
+
*/
|
|
789
|
+
user_createJwtToken(data) {
|
|
790
|
+
return this.userJwtToken = this.webSite.createJwtToken(data);
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Extract the JWT token from the Authorization header.
|
|
794
|
+
*/
|
|
795
|
+
user_getJwtToken() {
|
|
796
|
+
if (this.userJwtToken) {
|
|
797
|
+
return this.userJwtToken;
|
|
798
|
+
}
|
|
799
|
+
if (this.hasNoUserInfos) {
|
|
800
|
+
return undefined;
|
|
801
|
+
}
|
|
802
|
+
let authHeader = this.headers.get("authorization");
|
|
803
|
+
if (authHeader) {
|
|
804
|
+
if (authHeader.startsWith("Bearer ")) {
|
|
805
|
+
return this.userJwtToken = authHeader.slice(7);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
let authCookie = this.cookie_getReqCookie("authorization");
|
|
809
|
+
if (authCookie) {
|
|
810
|
+
if (authCookie.startsWith("jwt ")) {
|
|
811
|
+
return this.userJwtToken = authCookie.slice(4);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return undefined;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Try to sign in the user with information you provide.
|
|
818
|
+
* Return true if he is signed in, false otherwise.
|
|
819
|
+
*
|
|
820
|
+
* If signed in, then it automatically adds the Authorization header.
|
|
821
|
+
*
|
|
822
|
+
* @param loginInfo
|
|
823
|
+
* Information with things like login/password-hash/...
|
|
824
|
+
* Must match with you have used with webSite.setUserLoginManager.
|
|
825
|
+
*/
|
|
826
|
+
async user_tryAuthWithJWT(loginInfo) {
|
|
827
|
+
const authResult = await this.webSite.tryAuthUser(loginInfo);
|
|
828
|
+
if (authResult.isOk) {
|
|
829
|
+
if (!authResult.authToken) {
|
|
830
|
+
authResult.authToken = this.user_createJwtToken(authResult.userInfos);
|
|
831
|
+
}
|
|
832
|
+
// The token will be added to cookie "authorization" in the post-process step.
|
|
833
|
+
this.userJwtToken = authResult.authToken;
|
|
834
|
+
this.userInfos = authResult.userInfos;
|
|
835
|
+
this.webSite.storeJwtToken(this);
|
|
836
|
+
return authResult;
|
|
837
|
+
}
|
|
838
|
+
this.userInfos = undefined;
|
|
839
|
+
this.userJwtToken = undefined;
|
|
840
|
+
return authResult;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Verify and decode the JWT token.
|
|
844
|
+
* Once done, the data is saved and can be read through req.userTokenData.
|
|
845
|
+
*/
|
|
846
|
+
user_decodeJwtToken() {
|
|
847
|
+
if (this.isFakingNoUsers)
|
|
848
|
+
return undefined;
|
|
849
|
+
const token = this.user_getJwtToken();
|
|
850
|
+
if (!token)
|
|
851
|
+
return undefined;
|
|
852
|
+
return this.webSite.decodeJwtToken(token);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Allow faking a state where there is no user connected.
|
|
856
|
+
* Is mainly used by the automatic cache to generate
|
|
857
|
+
* a generic anonymous page.
|
|
858
|
+
*/
|
|
859
|
+
user_fakeNoUsers() {
|
|
860
|
+
let fakeNoUser;
|
|
861
|
+
if (this._onFakeNoUser) {
|
|
862
|
+
fakeNoUser = this._onFakeNoUser;
|
|
863
|
+
}
|
|
864
|
+
else if (this.webSite.fakeNoUser) {
|
|
865
|
+
fakeNoUser = this.webSite.fakeNoUser;
|
|
866
|
+
}
|
|
867
|
+
if (fakeNoUser) {
|
|
868
|
+
let r = fakeNoUser(this);
|
|
869
|
+
if (r === false)
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
this.isFakingNoUsers = true;
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Allows setting a listener which is call when `fakeNoUsers`is called.
|
|
876
|
+
* If this listener explicitly returns false, then the call to fakeNoUsers is ignored.
|
|
877
|
+
*/
|
|
878
|
+
user_onFakeNoUser(handler) {
|
|
879
|
+
this._onFakeNoUser = handler;
|
|
880
|
+
}
|
|
881
|
+
user_getUserInfos() {
|
|
882
|
+
if (this.isFakingNoUsers)
|
|
883
|
+
return undefined;
|
|
884
|
+
if (this.userInfos)
|
|
885
|
+
return this.userInfos;
|
|
886
|
+
if (this.hasNoUserInfos)
|
|
887
|
+
return undefined;
|
|
888
|
+
const userInfos = this.user_decodeJwtToken();
|
|
889
|
+
if (userInfos) {
|
|
890
|
+
this.userInfos = userInfos;
|
|
891
|
+
return userInfos;
|
|
892
|
+
}
|
|
893
|
+
this.hasNoUserInfos = true;
|
|
894
|
+
return undefined;
|
|
895
|
+
}
|
|
896
|
+
use_requireUserInfos() {
|
|
897
|
+
let userInfos = this.user_getUserInfos();
|
|
898
|
+
if (!userInfos)
|
|
899
|
+
throw new SBPE_NotAuthorizedException();
|
|
900
|
+
return userInfos;
|
|
901
|
+
}
|
|
902
|
+
isFakingNoUsers = false;
|
|
903
|
+
_onFakeNoUser;
|
|
904
|
+
hasNoUserInfos = false;
|
|
905
|
+
userInfos;
|
|
906
|
+
userJwtToken;
|
|
907
|
+
//endregion
|
|
908
|
+
//region User roles
|
|
909
|
+
/**
|
|
910
|
+
* Returns the roles of the user.
|
|
911
|
+
*/
|
|
912
|
+
role_getUserRoles() {
|
|
913
|
+
const userInfos = this.user_getUserInfos();
|
|
914
|
+
if (!userInfos || !userInfos.roles)
|
|
915
|
+
return [];
|
|
916
|
+
return userInfos.roles;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Check if the user has all these roles.
|
|
920
|
+
* Return true if ok, false otherwise.
|
|
921
|
+
*/
|
|
922
|
+
role_userHasRoles(requiredRoles) {
|
|
923
|
+
const userInfos = this.user_getUserInfos();
|
|
924
|
+
if (!userInfos)
|
|
925
|
+
return false;
|
|
926
|
+
const userRoles = userInfos.roles;
|
|
927
|
+
if (!userRoles)
|
|
928
|
+
return false;
|
|
929
|
+
for (let role of requiredRoles) {
|
|
930
|
+
if (!userRoles.includes(role))
|
|
931
|
+
return false;
|
|
932
|
+
}
|
|
933
|
+
return true;
|
|
934
|
+
}
|
|
935
|
+
role_assertUserHasRoles(requiredRoles) {
|
|
936
|
+
if (!this.role_userHasRoles(requiredRoles)) {
|
|
937
|
+
throw new SBPE_NotAuthorizedException();
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
//endregion
|
|
941
|
+
//region File Serving
|
|
942
|
+
async file_returnFile(filePath, params) {
|
|
943
|
+
const res = await this.file_tryReturnFile(filePath, params);
|
|
944
|
+
if (res)
|
|
945
|
+
return res;
|
|
946
|
+
return this.res_returnError404_NotFound();
|
|
947
|
+
}
|
|
948
|
+
async file_tryReturnFile(filePath, params) {
|
|
949
|
+
let cacheValidationInfos = await this.file_validateCacheHeaders(filePath);
|
|
950
|
+
// Mean that the file doesn't exist.
|
|
951
|
+
if (cacheValidationInfos === undefined)
|
|
952
|
+
return undefined;
|
|
953
|
+
// Mean that the browser cache is valid. Returns code 304.
|
|
954
|
+
if (cacheValidationInfos instanceof Response)
|
|
955
|
+
return cacheValidationInfos;
|
|
956
|
+
// Will return the file and add the browser cache headers.
|
|
957
|
+
return this.webSite.tryReturnFile({
|
|
958
|
+
req: this,
|
|
959
|
+
filePath,
|
|
960
|
+
contentEncoding: params?.contentEncoding,
|
|
961
|
+
validationInfos: cacheValidationInfos
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Allow serving a file as a response.
|
|
966
|
+
* Automatically get the file from the url and a root dir.
|
|
967
|
+
*/
|
|
968
|
+
async file_serveFromDir(filesRootPath, options) {
|
|
969
|
+
options = options || gEmptyObject;
|
|
970
|
+
if (options.replaceIndexHtml !== false) {
|
|
971
|
+
if (this.urlInfos.pathname.endsWith("/index.html")) {
|
|
972
|
+
this.urlInfos.pathname = this.urlInfos.pathname.slice(0, -10);
|
|
973
|
+
return this.res_redirectResponse(false);
|
|
974
|
+
}
|
|
975
|
+
if (this.urlInfos.pathname.endsWith("/")) {
|
|
976
|
+
this.urlInfos.pathname += "index.html";
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
const sfc = new WebSiteMirrorCache(filesRootPath);
|
|
980
|
+
const fromCache = await sfc.getFromCache(this, this.urlInfos);
|
|
981
|
+
if (fromCache)
|
|
982
|
+
return fromCache;
|
|
983
|
+
if (options.onNotFound) {
|
|
984
|
+
return options.onNotFound(this);
|
|
985
|
+
}
|
|
986
|
+
return this.res_returnError404_NotFound();
|
|
987
|
+
}
|
|
988
|
+
file_calcFileEtag(filePath) {
|
|
989
|
+
return jk_fs.calcFileHash(filePath);
|
|
990
|
+
}
|
|
991
|
+
file_validateCacheHeadersWith(headers) {
|
|
992
|
+
let reqEtag = this.headers.get("if-none-match");
|
|
993
|
+
let myEtag = headers["etag"];
|
|
994
|
+
if (reqEtag && (reqEtag === myEtag)) {
|
|
995
|
+
return new Response(null, {
|
|
996
|
+
status: 304,
|
|
997
|
+
headers: { "etag": myEtag }
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
let reqLastModifiedSince = this.headers.get("if-modified-since");
|
|
1001
|
+
let myLastModifiedSince = headers["if-modified-since"];
|
|
1002
|
+
if (myLastModifiedSince && reqLastModifiedSince) {
|
|
1003
|
+
const dMyLastModifiedSince = new Date(myLastModifiedSince).getTime();
|
|
1004
|
+
const dReqLastModifiedSince = new Date(reqLastModifiedSince).getTime();
|
|
1005
|
+
if (dReqLastModifiedSince < dMyLastModifiedSince) {
|
|
1006
|
+
return new Response(null, {
|
|
1007
|
+
status: 304,
|
|
1008
|
+
headers: { "last-modified": myLastModifiedSince }
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
async file_validateCacheHeaders(filePath) {
|
|
1014
|
+
let fileState = await jk_fs.getFileStat(filePath);
|
|
1015
|
+
if (!fileState)
|
|
1016
|
+
return undefined;
|
|
1017
|
+
let lastModifiedSince = this.headers.get("if-modified-since");
|
|
1018
|
+
if (lastModifiedSince) {
|
|
1019
|
+
const fileModifiedTime = new Date(fileState.mtimeMs).getTime();
|
|
1020
|
+
const clientModifiedTime = new Date(lastModifiedSince).getTime();
|
|
1021
|
+
if (fileModifiedTime <= clientModifiedTime) {
|
|
1022
|
+
return new Response(null, {
|
|
1023
|
+
status: 304,
|
|
1024
|
+
headers: { "last-modified": new Date(fileState.mtimeMs).toUTCString() }
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
let etag = this.headers.get("if-none-match");
|
|
1029
|
+
let calcEtag;
|
|
1030
|
+
if (etag) {
|
|
1031
|
+
calcEtag = await jk_fs.calcFileHash(filePath);
|
|
1032
|
+
if (etag === calcEtag) {
|
|
1033
|
+
return new Response(null, {
|
|
1034
|
+
status: 304,
|
|
1035
|
+
headers: { "etag": etag }
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
if (!calcEtag)
|
|
1040
|
+
calcEtag = await jk_fs.calcFileHash(filePath);
|
|
1041
|
+
return { etag: calcEtag, fileState: fileState };
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
export var ContentTypeCategory;
|
|
1045
|
+
(function (ContentTypeCategory) {
|
|
1046
|
+
ContentTypeCategory[ContentTypeCategory["OTHER"] = 0] = "OTHER";
|
|
1047
|
+
ContentTypeCategory[ContentTypeCategory["_TEXT_"] = 10] = "_TEXT_";
|
|
1048
|
+
ContentTypeCategory[ContentTypeCategory["TEXT_HTML"] = 11] = "TEXT_HTML";
|
|
1049
|
+
ContentTypeCategory[ContentTypeCategory["TEXT_CSS"] = 12] = "TEXT_CSS";
|
|
1050
|
+
ContentTypeCategory[ContentTypeCategory["TEXT_JAVASCRIPT"] = 13] = "TEXT_JAVASCRIPT";
|
|
1051
|
+
ContentTypeCategory[ContentTypeCategory["TEXT_JSON"] = 14] = "TEXT_JSON";
|
|
1052
|
+
ContentTypeCategory[ContentTypeCategory["_FORM_"] = 20] = "_FORM_";
|
|
1053
|
+
ContentTypeCategory[ContentTypeCategory["FORM_MULTIPART"] = 20] = "FORM_MULTIPART";
|
|
1054
|
+
ContentTypeCategory[ContentTypeCategory["FORM_URL_ENCODED"] = 21] = "FORM_URL_ENCODED";
|
|
1055
|
+
ContentTypeCategory[ContentTypeCategory["_BINARY_"] = 30] = "_BINARY_";
|
|
1056
|
+
ContentTypeCategory[ContentTypeCategory["IMAGE"] = 31] = "IMAGE";
|
|
1057
|
+
})(ContentTypeCategory || (ContentTypeCategory = {}));
|
|
1058
|
+
const gEmptyObject = {};
|
|
1059
|
+
const gIsSinglePageMode = isSinglePageMode();
|
|
1060
|
+
//# sourceMappingURL=jopiRequest.js.map
|