@js-recon/js-recon 1.4.3 → 2.0.1-alpha.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/.claude-sync/sync.sh +1 -1
- package/.github/workflows/build-and-prettify.yaml +55 -25
- package/.github/workflows/codeql.yml +33 -0
- package/.github/workflows/exploit-smoke-test.yaml +160 -0
- package/.github/workflows/framework-detection-smoke-test.yaml +135 -0
- package/.github/workflows/plumber.yml +20 -0
- package/.github/workflows/promote-js-recon.yml +5 -3
- package/.github/workflows/publish-js-recon.yml +6 -1
- package/.github/workflows/rules-smoke-test.yaml +15 -7
- package/.nvmrc +1 -0
- package/.plumber.yaml +151 -0
- package/CHANGELOG.md +54 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +1 -0
- package/README.md +55 -2
- package/SECURITY.md +1 -1
- package/build/analyze/engine/astEngine.js +10 -9
- package/build/analyze/engine/astEngine.js.map +1 -1
- package/build/analyze/engine/csMastSEngine.js +6 -6
- package/build/analyze/engine/csMastSEngine.js.map +1 -1
- package/build/analyze/engine/index.js +1 -1
- package/build/analyze/engine/index.js.map +1 -1
- package/build/analyze/engine/requestEngine.js +6 -6
- package/build/analyze/engine/requestEngine.js.map +1 -1
- package/build/analyze/helpers/determineCompatibleVersion.js +70 -0
- package/build/analyze/helpers/determineCompatibleVersion.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +9 -3
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
- package/build/analyze/helpers/initRules.js +42 -24
- package/build/analyze/helpers/initRules.js.map +1 -1
- package/build/analyze/helpers/outputHelper.js +3 -3
- package/build/analyze/helpers/outputHelper.js.map +1 -1
- package/build/analyze/helpers/schemas.js +1 -0
- package/build/analyze/helpers/schemas.js.map +1 -1
- package/build/analyze/helpers/validate.js +9 -5
- package/build/analyze/helpers/validate.js.map +1 -1
- package/build/analyze/index.js +26 -16
- package/build/analyze/index.js.map +1 -1
- package/build/cliProgram.js +710 -0
- package/build/cliProgram.js.map +1 -0
- package/build/completion/index.js +245 -339
- package/build/completion/index.js.map +1 -1
- package/build/completion/introspect.js +17 -0
- package/build/completion/introspect.js.map +1 -0
- package/build/config/applicationConfig.js +494 -0
- package/build/config/applicationConfig.js.map +1 -0
- package/build/cs_mast/index.js +18 -17
- package/build/cs_mast/index.js.map +1 -1
- package/build/endpoints/gen_report/gen_json.js +2 -2
- package/build/endpoints/gen_report/gen_json.js.map +1 -1
- package/build/endpoints/gen_report/utility/iterate_n_store.js +1 -1
- package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -1
- package/build/endpoints/index.js +12 -12
- package/build/endpoints/index.js.map +1 -1
- package/build/endpoints/next_js/client_jsFilesHref.js +3 -3
- package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
- package/build/endpoints/next_js/client_jsonParse.js +4 -4
- package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
- package/build/endpoints/next_js/client_mappedJsonFile.js +6 -6
- package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
- package/build/endpoints/next_js/client_subsequentRequests.js +5 -5
- package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
- package/build/exploit/angular/cve-2026-68945.js +61 -0
- package/build/exploit/angular/cve-2026-68945.js.map +1 -0
- package/build/exploit/index.js +60 -0
- package/build/exploit/index.js.map +1 -0
- package/build/exploit/next/cve-2025-29927.js +65 -0
- package/build/exploit/next/cve-2025-29927.js.map +1 -0
- package/build/exploit/next/cve-2026-64645.js +51 -0
- package/build/exploit/next/cve-2026-64645.js.map +1 -0
- package/build/exploit/nuxt/cve-2026-71315.js +47 -0
- package/build/exploit/nuxt/cve-2026-71315.js.map +1 -0
- package/build/exploit/nuxt/cve-2026-71320.js +114 -0
- package/build/exploit/nuxt/cve-2026-71320.js.map +1 -0
- package/build/exploit/react/cve-2025-55182.js +116 -0
- package/build/exploit/react/cve-2025-55182.js.map +1 -0
- package/build/exploit/registry/cveRegistry.js +115 -0
- package/build/exploit/registry/cveRegistry.js.map +1 -0
- package/build/exploit/types.js +2 -0
- package/build/exploit/types.js.map +1 -0
- package/build/exploit/utility/compareResponses.js +29 -0
- package/build/exploit/utility/compareResponses.js.map +1 -0
- package/build/exploit/utility/outputHelper.js +22 -0
- package/build/exploit/utility/outputHelper.js.map +1 -0
- package/build/exploit/utility/rawRequest.js +54 -0
- package/build/exploit/utility/rawRequest.js.map +1 -0
- package/build/exploit/utility/sandboxRce.js +49 -0
- package/build/exploit/utility/sandboxRce.js.map +1 -0
- package/build/exploit/utility/toEngineOutput.js +28 -0
- package/build/exploit/utility/toEngineOutput.js.map +1 -0
- package/build/exploit/utility/wsClient.js +78 -0
- package/build/exploit/utility/wsClient.js.map +1 -0
- package/build/exploit/vite/cve-2025-30208.js +44 -0
- package/build/exploit/vite/cve-2025-30208.js.map +1 -0
- package/build/exploit/vite/cve-2026-39363.js +60 -0
- package/build/exploit/vite/cve-2026-39363.js.map +1 -0
- package/build/fingerprint/index.js +11 -21
- package/build/fingerprint/index.js.map +1 -1
- package/build/globalConfig.js +2 -2
- package/build/globalConfig.js.map +1 -1
- package/build/index.js +16 -555
- package/build/index.js.map +1 -1
- package/build/lazyLoad/angular/angular_getFromPageSource.js +3 -3
- package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/downloadFilesUtil.js +51 -40
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/downloadQueue.js +154 -50
- package/build/lazyLoad/downloadQueue.js.map +1 -1
- package/build/lazyLoad/downloadResponse.js +113 -0
- package/build/lazyLoad/downloadResponse.js.map +1 -0
- package/build/lazyLoad/generic/generic_crawlPages.js +186 -0
- package/build/lazyLoad/generic/generic_crawlPages.js.map +1 -0
- package/build/lazyLoad/generic/generic_downloadFiles.js +81 -0
- package/build/lazyLoad/generic/generic_downloadFiles.js.map +1 -0
- package/build/lazyLoad/generic/generic_extractLinks.js +79 -0
- package/build/lazyLoad/generic/generic_extractLinks.js.map +1 -0
- package/build/lazyLoad/generic/generic_getScriptTags.js +152 -0
- package/build/lazyLoad/generic/generic_getScriptTags.js.map +1 -0
- package/build/lazyLoad/generic/generic_importMapDiscovery.js +87 -0
- package/build/lazyLoad/generic/generic_importMapDiscovery.js.map +1 -0
- package/build/lazyLoad/generic/generic_resolveScope.js +61 -0
- package/build/lazyLoad/generic/generic_resolveScope.js.map +1 -0
- package/build/lazyLoad/generic/generic_scanAttributesForJs.js +122 -0
- package/build/lazyLoad/generic/generic_scanAttributesForJs.js.map +1 -0
- package/build/lazyLoad/generic/generic_stringsDiscovery.js +103 -0
- package/build/lazyLoad/generic/generic_stringsDiscovery.js.map +1 -0
- package/build/lazyLoad/generic/generic_webpackChunkPaths.js +56 -0
- package/build/lazyLoad/generic/generic_webpackChunkPaths.js.map +1 -0
- package/build/lazyLoad/globals.js +35 -0
- package/build/lazyLoad/globals.js.map +1 -1
- package/build/lazyLoad/index.js +311 -175
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/methodFilter.js +2 -0
- package/build/lazyLoad/methodFilter.js.map +1 -1
- package/build/lazyLoad/next_js/NextJsCrawler.js +39 -14
- package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetJSScript.js +3 -3
- package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +4 -4
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +21 -20
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +100 -99
- package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -1
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +1 -1
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -1
- package/build/lazyLoad/next_js/next_buildId.js +2 -2
- package/build/lazyLoad/next_js/next_buildId.js.map +1 -1
- package/build/lazyLoad/next_js/next_getClientSidePaths.js +2 -2
- package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/next_js/next_parseLayoutJs.js +6 -6
- package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
- package/build/lazyLoad/next_js/next_routerStateForge.js +341 -0
- package/build/lazyLoad/next_js/next_routerStateForge.js.map +1 -0
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +1 -1
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -1
- package/build/lazyLoad/next_js/next_serverActionIdScan.js +77 -0
- package/build/lazyLoad/next_js/next_serverActionIdScan.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js +15 -13
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +2 -2
- package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -3
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +2 -2
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/outputPath.js +92 -0
- package/build/lazyLoad/outputPath.js.map +1 -0
- package/build/lazyLoad/react/react_followImports.js +15 -5
- package/build/lazyLoad/react/react_followImports.js.map +1 -1
- package/build/lazyLoad/react/react_getScriptTags.js +11 -6
- package/build/lazyLoad/react/react_getScriptTags.js.map +1 -1
- package/build/lazyLoad/react/react_sourcemapUrls.js +3 -2
- package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -1
- package/build/lazyLoad/react/react_webpackChunkPaths.js +12 -203
- package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
- package/build/lazyLoad/researchUtils.js +15 -0
- package/build/lazyLoad/researchUtils.js.map +1 -0
- package/build/lazyLoad/shared/webpackChunkParsers.js +218 -0
- package/build/lazyLoad/shared/webpackChunkParsers.js.map +1 -0
- package/build/lazyLoad/stagnation/stagnationMonitor.js +63 -0
- package/build/lazyLoad/stagnation/stagnationMonitor.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js +5 -5
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_getVersionJson.js +2 -2
- package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +6 -6
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +2 -2
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkNuxtJS.js +3 -3
- package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkSvelte.js +0 -1
- package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
- package/build/lazyLoad/techDetect/checkVueJS.js +6 -6
- package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -1
- package/build/lazyLoad/techDetect/index.js +106 -60
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_RuntimeJs.js +20 -15
- package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +10 -5
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +20 -17
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +70 -46
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/vue/vue_jsImports.js +3 -2
- package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js +3 -2
- package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +6 -5
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +10 -21
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js +5 -4
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_stringJsFiles.js +28 -25
- package/build/lazyLoad/vue/vue_stringJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_viteMapDeps.js +8 -2
- package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -1
- package/build/load/index.js +8 -7
- package/build/load/index.js.map +1 -1
- package/build/map/angular_js/getAngularConnections.js +6 -6
- package/build/map/angular_js/getAngularConnections.js.map +1 -1
- package/build/map/graphql/resolveGraphql.js +6 -6
- package/build/map/graphql/resolveGraphql.js.map +1 -1
- package/build/map/index.js +17 -17
- package/build/map/index.js.map +1 -1
- package/build/map/interactive-mode/commandHandler.js +278 -0
- package/build/map/interactive-mode/commandHandler.js.map +1 -0
- package/build/map/interactive-mode/commandHelpers.js +189 -0
- package/build/map/interactive-mode/commandHelpers.js.map +1 -0
- package/build/map/interactive-mode/esqueryGen.js.map +1 -0
- package/build/map/interactive-mode/helpMenu.js +11 -0
- package/build/map/interactive-mode/helpMenu.js.map +1 -0
- package/build/map/interactive-mode/inputPatch.js.map +1 -0
- package/build/map/interactive-mode/interactive.js +71 -0
- package/build/map/interactive-mode/interactive.js.map +1 -0
- package/build/map/interactive-mode/keybindings.js.map +1 -0
- package/build/map/interactive-mode/printer.js.map +1 -0
- package/build/map/interactive-mode/ui.js.map +1 -0
- package/build/map/next_js/getAxiosInstances.js +5 -5
- package/build/map/next_js/getAxiosInstances.js.map +1 -1
- package/build/map/next_js/getExports.js +4 -4
- package/build/map/next_js/getExports.js.map +1 -1
- package/build/map/next_js/getFetchInstances.js +10 -10
- package/build/map/next_js/getFetchInstances.js.map +1 -1
- package/build/map/next_js/getTurbopackConnections.js +8 -8
- package/build/map/next_js/getTurbopackConnections.js.map +1 -1
- package/build/map/next_js/getWebpackConnections.js +27 -16
- package/build/map/next_js/getWebpackConnections.js.map +1 -1
- package/build/map/next_js/interactive.js +3 -65
- package/build/map/next_js/interactive.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHandler.js +38 -290
- package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHelpers.js +0 -184
- package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
- package/build/map/next_js/interactive_helpers/helpMenu.js +2 -10
- package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -1
- package/build/map/next_js/resolveAxios.js +6 -6
- package/build/map/next_js/resolveAxios.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +4 -4
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -2
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +5 -5
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +10 -10
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +13 -9
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +12 -8
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +12 -8
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +11 -11
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +16 -16
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
- package/build/map/next_js/resolveFetch.js +23 -23
- package/build/map/next_js/resolveFetch.js.map +1 -1
- package/build/map/next_js/resolveNewRequest.js +10 -10
- package/build/map/next_js/resolveNewRequest.js.map +1 -1
- package/build/map/next_js/resolveServerActions.js +4 -4
- package/build/map/next_js/resolveServerActions.js.map +1 -1
- package/build/map/next_js/utils.js +8 -2
- package/build/map/next_js/utils.js.map +1 -1
- package/build/map/react_js/getReactConnections.js +21 -14
- package/build/map/react_js/getReactConnections.js.map +1 -1
- package/build/map/svelte_js/interactive.js +3 -54
- package/build/map/svelte_js/interactive.js.map +1 -1
- package/build/map/vue_js/getViteConnections.js +23 -16
- package/build/map/vue_js/getViteConnections.js.map +1 -1
- package/build/map/vue_js/interactive.js +3 -63
- package/build/map/vue_js/interactive.js.map +1 -1
- package/build/map/vue_js/interactive_helpers/commandHandler.js +34 -283
- package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -1
- package/build/map/vue_js/interactive_helpers/helpMenu.js +2 -10
- package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -1
- package/build/map/vue_js/taint_utils.js +1 -1
- package/build/map/vue_js/taint_utils.js.map +1 -1
- package/build/map/vue_js/vue_resolveFetch.js +12 -12
- package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
- package/build/map/vue_js/vue_resolveHttpClient.js +18 -18
- package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
- package/build/map/vue_js/vue_resolveXhr.js +11 -11
- package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
- package/build/mcp/chatOneShot.js +7 -7
- package/build/mcp/chatOneShot.js.map +1 -1
- package/build/mcp/claudeCodeCreds.js +5 -5
- package/build/mcp/claudeCodeCreds.js.map +1 -1
- package/build/mcp/cli.js +36 -35
- package/build/mcp/cli.js.map +1 -1
- package/build/mcp/config.js +4 -4
- package/build/mcp/config.js.map +1 -1
- package/build/mcp/index.js +7 -7
- package/build/mcp/index.js.map +1 -1
- package/build/mcp/mcpServer.js +3 -2
- package/build/mcp/mcpServer.js.map +1 -1
- package/build/mcp/skills.js +1 -0
- package/build/mcp/skills.js.map +1 -1
- package/build/mcp/tools.js +5 -4
- package/build/mcp/tools.js.map +1 -1
- package/build/proxy/checkFeasibility.js +8 -4
- package/build/proxy/checkFeasibility.js.map +1 -1
- package/build/proxy/checkFireWallBlocking.js +23 -13
- package/build/proxy/checkFireWallBlocking.js.map +1 -1
- package/build/proxy/detectBlockedResponse.js +205 -0
- package/build/proxy/detectBlockedResponse.js.map +1 -0
- package/build/proxy/genReq.js +434 -127
- package/build/proxy/genReq.js.map +1 -1
- package/build/proxy/index.js +3 -3
- package/build/proxy/index.js.map +1 -1
- package/build/proxy/oxylabsFallback.js +110 -0
- package/build/proxy/oxylabsFallback.js.map +1 -0
- package/build/proxy/proxyFeasibilityRequest.js +11 -9
- package/build/proxy/proxyFeasibilityRequest.js.map +1 -1
- package/build/refactor/index.js +83 -79
- package/build/refactor/index.js.map +1 -1
- package/build/refactor/next/index.js +69 -26
- package/build/refactor/next/index.js.map +1 -1
- package/build/refactor/next/transform.js +11 -4
- package/build/refactor/next/transform.js.map +1 -1
- package/build/refactor/next/validator.js +7 -7
- package/build/refactor/next/validator.js.map +1 -1
- package/build/refactor/react/index.js +13 -13
- package/build/refactor/react/index.js.map +1 -1
- package/build/refactor/react/validator.js +7 -7
- package/build/refactor/react/validator.js.map +1 -1
- package/build/refactor/react-vite/index.js +3 -3
- package/build/refactor/react-vite/index.js.map +1 -1
- package/build/refactor/remote/hf-client.js +1 -0
- package/build/refactor/remote/hf-client.js.map +1 -1
- package/build/refactor/remote/version-detect.js +12 -12
- package/build/refactor/remote/version-detect.js.map +1 -1
- package/build/refactor/vue/index.js +6 -6
- package/build/refactor/vue/index.js.map +1 -1
- package/build/refactor/vue/vite.js +6 -6
- package/build/refactor/vue/vite.js.map +1 -1
- package/build/report/index.js +30 -8
- package/build/report/index.js.map +1 -1
- package/build/report/swaggerJacker.js +63 -0
- package/build/report/swaggerJacker.js.map +1 -0
- package/build/report/utility/genHtml.js +7 -7
- package/build/report/utility/genHtml.js.map +1 -1
- package/build/report/utility/populateDb/populateAnalysisFindings.js +2 -2
- package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -1
- package/build/report/utility/populateDb/populateEndpoints.js +3 -3
- package/build/report/utility/populateDb/populateEndpoints.js.map +1 -1
- package/build/report/utility/populateDb/populateMappedJson.js +2 -2
- package/build/report/utility/populateDb/populateMappedJson.js.map +1 -1
- package/build/report/utility/populateDb/populateMappedOpenapi.js +3 -3
- package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -1
- package/build/run/bundler-detect.js +45 -9
- package/build/run/bundler-detect.js.map +1 -1
- package/build/run/cancellableStep.js +27 -0
- package/build/run/cancellableStep.js.map +1 -0
- package/build/run/dashboard/dashboardHtml.js +150 -0
- package/build/run/dashboard/dashboardHtml.js.map +1 -0
- package/build/run/dashboard/fsBrowser.js +43 -0
- package/build/run/dashboard/fsBrowser.js.map +1 -0
- package/build/run/dashboard/server.js +123 -0
- package/build/run/dashboard/server.js.map +1 -0
- package/build/run/dashboard/state.js +97 -0
- package/build/run/dashboard/state.js.map +1 -0
- package/build/run/index.js +239 -204
- package/build/run/index.js.map +1 -1
- package/build/run/interruptHandler.js +18 -0
- package/build/run/interruptHandler.js.map +1 -1
- package/build/run/outputDirectory.js +377 -0
- package/build/run/outputDirectory.js.map +1 -0
- package/build/sourcemaps/index.js +116 -29
- package/build/sourcemaps/index.js.map +1 -1
- package/build/strings/index.js +38 -28
- package/build/strings/index.js.map +1 -1
- package/build/strings/openapi.js +4 -4
- package/build/strings/openapi.js.map +1 -1
- package/build/strings/permutate.js +4 -4
- package/build/strings/permutate.js.map +1 -1
- package/build/strings/secrets.js +1 -0
- package/build/strings/secrets.js.map +1 -1
- package/build/strings/trufflehog.js +66 -19
- package/build/strings/trufflehog.js.map +1 -1
- package/build/strings/trufflehogConfig.js +36 -0
- package/build/strings/trufflehogConfig.js.map +1 -0
- package/build/strings/trufflehogDownload.js +115 -0
- package/build/strings/trufflehogDownload.js.map +1 -0
- package/build/utility/ai.js +33 -4
- package/build/utility/ai.js.map +1 -1
- package/build/utility/banner.js +4 -3
- package/build/utility/banner.js.map +1 -1
- package/build/utility/configureSandbox.js +2 -2
- package/build/utility/configureSandbox.js.map +1 -1
- package/build/utility/downloadProgress.js +99 -0
- package/build/utility/downloadProgress.js.map +1 -0
- package/build/utility/globals.js +19 -11
- package/build/utility/globals.js.map +1 -1
- package/build/utility/heap.js +2 -1
- package/build/utility/heap.js.map +1 -1
- package/build/utility/makeReq.js +490 -257
- package/build/utility/makeReq.js.map +1 -1
- package/build/utility/openapiGenerator.js +2 -2
- package/build/utility/openapiGenerator.js.map +1 -1
- package/build/utility/printMsg.js +53 -0
- package/build/utility/printMsg.js.map +1 -0
- package/build/utility/progressLog.js +68 -7
- package/build/utility/progressLog.js.map +1 -1
- package/build/utility/resolvePath.js +2 -1
- package/build/utility/resolvePath.js.map +1 -1
- package/build/utility/ruleVersionMap.js +73 -0
- package/build/utility/ruleVersionMap.js.map +1 -0
- package/build/utility/targetInputs.js +177 -0
- package/build/utility/targetInputs.js.map +1 -0
- package/build/utility/urlUtils.js +37 -1
- package/build/utility/urlUtils.js.map +1 -1
- package/config.dist.yaml +251 -0
- package/contributing/testing.md +106 -0
- package/eslint.config.js +24 -0
- package/package.json +22 -5
- package/scripts/exploit-smoke-test.js +82 -0
- package/scripts/framework-detect-smoke-test.js +64 -0
- package/scripts/postinstall-completion.mjs +40 -0
- package/scripts/smoke-test.js +12 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js +0 -98
- package/build/lazyLoad/downloadLoadedJsUtil.js.map +0 -1
- package/build/map/next_js/interactive_helpers/esqueryGen.js.map +0 -1
- package/build/map/next_js/interactive_helpers/inputPatch.js.map +0 -1
- package/build/map/next_js/interactive_helpers/keybindings.js.map +0 -1
- package/build/map/next_js/interactive_helpers/printer.js.map +0 -1
- package/build/map/next_js/interactive_helpers/ui.js.map +0 -1
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/esqueryGen.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/inputPatch.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/keybindings.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/printer.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/ui.js +0 -0
package/build/lazyLoad/index.js
CHANGED
|
@@ -10,13 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
var _a;
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import fs from "fs";
|
|
13
|
-
import frameworkDetect from "./techDetect/index.js";
|
|
14
|
-
import CONFIG from "../globalConfig.js";
|
|
13
|
+
import frameworkDetect, { getLastInterceptedUrls } from "./techDetect/index.js";
|
|
15
14
|
import _traverse from "@babel/traverse";
|
|
16
15
|
const traverse = ((_a = _traverse.default) !== null && _a !== void 0 ? _a : _traverse);
|
|
17
16
|
import { URL } from "url";
|
|
18
17
|
// Next.js
|
|
19
18
|
import NextJsCrawler from "./next_js/NextJsCrawler.js";
|
|
19
|
+
import next_serverActionIdScan from "./next_js/next_serverActionIdScan.js";
|
|
20
20
|
import { next_buildId_RSC } from "./next_js/next_buildId.js";
|
|
21
21
|
// Nuxt.js
|
|
22
22
|
import nuxt_getFromPageSource from "./nuxt_js/nuxt_getFromPageSource.js";
|
|
@@ -41,8 +41,9 @@ import react_getScriptTags from "./react/react_getScriptTags.js";
|
|
|
41
41
|
import react_webpackChunkPaths from "./react/react_webpackChunkPaths.js";
|
|
42
42
|
import react_sourcemapUrls from "./react/react_sourcemapUrls.js";
|
|
43
43
|
import react_followImports from "./react/react_followImports.js";
|
|
44
|
-
import downloadLoadedJs from "./downloadLoadedJsUtil.js";
|
|
45
44
|
import { DownloadQueue } from "./downloadQueue.js";
|
|
45
|
+
import generic_crawlPages from "./generic/generic_crawlPages.js";
|
|
46
|
+
import resolveGenericScope from "./generic/generic_resolveScope.js";
|
|
46
47
|
import path from "path";
|
|
47
48
|
import { join } from "path";
|
|
48
49
|
import { extractSourceMaps } from "../sourcemaps/index.js";
|
|
@@ -50,6 +51,13 @@ import { extractSourceMaps } from "../sourcemaps/index.js";
|
|
|
50
51
|
import * as lazyLoadGlobals from "./globals.js";
|
|
51
52
|
import * as globals from "../utility/globals.js";
|
|
52
53
|
import { shouldRunMethod } from "./methodFilter.js";
|
|
54
|
+
import DownloadProgress from "../utility/downloadProgress.js";
|
|
55
|
+
import { progressLog, progressWarn } from "../utility/progressLog.js";
|
|
56
|
+
import { resolveHostOutputDirectory } from "./outputPath.js";
|
|
57
|
+
import { withRequestSignal } from "../utility/makeReq.js";
|
|
58
|
+
import { resolveTargetInputs } from "../utility/targetInputs.js";
|
|
59
|
+
import { accumulateTechnique, createTechniqueRecorder } from "./researchUtils.js";
|
|
60
|
+
import { printMsg, MSG } from "../utility/printMsg.js";
|
|
53
61
|
/**
|
|
54
62
|
* Downloads the required JavaScript files for a given URL
|
|
55
63
|
* @param {string} url The URL to download the JS files from
|
|
@@ -62,19 +70,46 @@ import { shouldRunMethod } from "./methodFilter.js";
|
|
|
62
70
|
* @param {boolean} insecure If true, then disable SSL certificate verification
|
|
63
71
|
* @returns {Promise<void>} A Promise that resolves when the download is complete
|
|
64
72
|
*/
|
|
65
|
-
const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1) => __awaiter(void 0, [url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1], void 0, function* (url, output, strictScope, inputScope, threads, subsequentRequestsFlag, urlsFile, insecure, buildId, sourcemapDir, research, researchOutput, maxIterations, maxJsSizeMb = 2, hardTimeoutMs = 30 * 60 * 1000, maxPageVisits = 200, includeMethods = [], excludeMethods = [], detectionTimeoutMs = 30 * 1000) {
|
|
73
|
+
const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1) => __awaiter(void 0, [url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1], void 0, function* (url, output, strictScope, inputScope, threads, subsequentRequestsFlag, urlsFile, insecure, buildId, sourcemapDir, research, researchOutput, maxIterations, maxJsSizeMb = 2, hardTimeoutMs = 30 * 60 * 1000, maxPageVisits = 200, includeMethods = [], excludeMethods = [], detectionTimeoutMs = 30 * 1000, cancellationSignal, isBatch = false, maxRedirects = 20, stringsEnabled = false, stringsMaxIterations = 5, stagnationTimeinMs = 0, stagnationPercentage = 80, stagnationMonitorMs = 60 * 1000, rscParamBruteforceLimit = 20) {
|
|
74
|
+
const resolvedTargets = resolveTargetInputs(url);
|
|
66
75
|
// Hoisted so the timeout handler can stop discovery and drain downloads.
|
|
67
76
|
let activeCrawler = null;
|
|
68
77
|
let activeQueue = null;
|
|
78
|
+
let activeDownloadProgress = null;
|
|
79
|
+
let activeDetectionController = null;
|
|
80
|
+
let hardTimeoutReached = false;
|
|
81
|
+
const workController = new AbortController();
|
|
82
|
+
const requestCancellation = () => {
|
|
83
|
+
hardTimeoutReached = true;
|
|
84
|
+
workController.abort();
|
|
85
|
+
activeDetectionController === null || activeDetectionController === void 0 ? void 0 : activeDetectionController.abort();
|
|
86
|
+
activeCrawler === null || activeCrawler === void 0 ? void 0 : activeCrawler.stop();
|
|
87
|
+
activeDownloadProgress === null || activeDownloadProgress === void 0 ? void 0 : activeDownloadProgress.stop();
|
|
88
|
+
activeDownloadProgress = null;
|
|
89
|
+
};
|
|
90
|
+
const enqueue = (queue, urls) => {
|
|
91
|
+
if (!hardTimeoutReached)
|
|
92
|
+
queue.push(urls);
|
|
93
|
+
};
|
|
94
|
+
const handleExternalCancellation = () => requestCancellation();
|
|
95
|
+
const cleanupActiveWork = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
|
+
activeDownloadProgress === null || activeDownloadProgress === void 0 ? void 0 : activeDownloadProgress.stop();
|
|
97
|
+
activeDownloadProgress = null;
|
|
98
|
+
if (hardTimeoutReached)
|
|
99
|
+
yield (activeQueue === null || activeQueue === void 0 ? void 0 : activeQueue.drain().catch(() => undefined));
|
|
100
|
+
});
|
|
101
|
+
cancellationSignal === null || cancellationSignal === void 0 ? void 0 : cancellationSignal.addEventListener("abort", handleExternalCancellation, { once: true });
|
|
102
|
+
if (cancellationSignal === null || cancellationSignal === void 0 ? void 0 : cancellationSignal.aborted)
|
|
103
|
+
requestCancellation();
|
|
69
104
|
const work = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
|
-
|
|
105
|
+
printMsg(MSG.Header, "[i] Loading 'Lazy Load' module");
|
|
71
106
|
if (globals.getDisableSandbox()) {
|
|
72
|
-
|
|
107
|
+
printMsg(MSG.Warn, "[!] Browser sandbox disabled");
|
|
73
108
|
}
|
|
74
109
|
globals.setInsecure(insecure);
|
|
75
110
|
if (insecure) {
|
|
76
111
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
77
|
-
|
|
112
|
+
printMsg(MSG.Warn, "[!] Running in insecure mode. SSL certificate verification disabled");
|
|
78
113
|
}
|
|
79
114
|
// if cache enabled, check if the cache file exists or not. If no, then create a new one
|
|
80
115
|
if (!globals.getDisableCache()) {
|
|
@@ -82,52 +117,51 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
82
117
|
fs.writeFileSync(globals.getRespCacheFile(), "{}");
|
|
83
118
|
}
|
|
84
119
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
else if (url.match(/https?:\/\/[a-zA-Z0-9\-_\.:]+/)) {
|
|
93
|
-
urls = [url];
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
console.error(chalk.red("[!] Invalid URL or file path"));
|
|
97
|
-
process.exit(3);
|
|
98
|
-
}
|
|
99
|
-
for (const url of urls) {
|
|
100
|
-
console.log(chalk.cyan(`[i] Processing ${url}`));
|
|
120
|
+
for (const url of resolvedTargets.targets) {
|
|
121
|
+
if (hardTimeoutReached)
|
|
122
|
+
break;
|
|
123
|
+
printMsg(MSG.Header, `[i] Processing ${url}`);
|
|
124
|
+
lazyLoadGlobals.clearJsUrls();
|
|
125
|
+
lazyLoadGlobals.clearJsonUrls();
|
|
126
|
+
lazyLoadGlobals.clearCrawledUrls();
|
|
101
127
|
if (strictScope) {
|
|
102
|
-
lazyLoadGlobals.
|
|
128
|
+
lazyLoadGlobals.setScope([new URL(url).host]);
|
|
103
129
|
}
|
|
104
130
|
else {
|
|
105
|
-
lazyLoadGlobals.setScope(inputScope);
|
|
131
|
+
lazyLoadGlobals.setScope([...inputScope]);
|
|
106
132
|
}
|
|
107
133
|
lazyLoadGlobals.setMaxReqQueue(threads);
|
|
134
|
+
globals.setTech("");
|
|
108
135
|
let tech;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
136
|
+
const detectionController = new AbortController();
|
|
137
|
+
activeDetectionController = detectionController;
|
|
138
|
+
let detectionTimedOut = false;
|
|
139
|
+
const detectionTimeoutHandle = detectionTimeoutMs > 0
|
|
140
|
+
? setTimeout(() => {
|
|
141
|
+
detectionTimedOut = true;
|
|
142
|
+
detectionController.abort();
|
|
143
|
+
}, detectionTimeoutMs)
|
|
144
|
+
: undefined;
|
|
145
|
+
try {
|
|
146
|
+
tech = yield frameworkDetect(url, detectionController.signal);
|
|
121
147
|
}
|
|
122
|
-
|
|
123
|
-
|
|
148
|
+
finally {
|
|
149
|
+
if (detectionTimeoutHandle !== undefined)
|
|
150
|
+
clearTimeout(detectionTimeoutHandle);
|
|
151
|
+
if (activeDetectionController === detectionController)
|
|
152
|
+
activeDetectionController = null;
|
|
153
|
+
}
|
|
154
|
+
if (detectionTimedOut) {
|
|
155
|
+
printMsg(MSG.Warn, `[!] Framework detection timed out after ${detectionTimeoutMs}ms; treating as not detected`);
|
|
124
156
|
}
|
|
157
|
+
if (hardTimeoutReached)
|
|
158
|
+
break;
|
|
125
159
|
globals.setTech(tech ? tech.name : "");
|
|
126
160
|
if (tech) {
|
|
127
161
|
if (tech.name === "next") {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
activeQueue = new DownloadQueue(output, threads);
|
|
162
|
+
printMsg(MSG.Run, "[✓] Next.js detected");
|
|
163
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
164
|
+
activeQueue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
131
165
|
const crawler = new NextJsCrawler({
|
|
132
166
|
url,
|
|
133
167
|
output,
|
|
@@ -137,91 +171,142 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
137
171
|
research,
|
|
138
172
|
maxIterations,
|
|
139
173
|
maxPageVisits,
|
|
140
|
-
|
|
174
|
+
rscParamBruteforceLimit,
|
|
175
|
+
onUrlsDiscovered: (urls) => enqueue(activeQueue, urls),
|
|
141
176
|
includeMethods,
|
|
142
177
|
excludeMethods,
|
|
178
|
+
isBatch,
|
|
143
179
|
});
|
|
144
180
|
activeCrawler = crawler;
|
|
145
|
-
|
|
146
|
-
|
|
181
|
+
try {
|
|
182
|
+
yield crawler.crawl();
|
|
183
|
+
}
|
|
184
|
+
finally {
|
|
185
|
+
activeCrawler = null; // done — prevent timeout handler from calling stop()
|
|
186
|
+
}
|
|
187
|
+
if (hardTimeoutReached)
|
|
188
|
+
return;
|
|
147
189
|
yield activeQueue.drain();
|
|
190
|
+
if (hardTimeoutReached)
|
|
191
|
+
return;
|
|
148
192
|
activeQueue.printSummary();
|
|
149
193
|
activeQueue = null;
|
|
194
|
+
if (shouldRunMethod("next_serverActionIdScan", includeMethods, excludeMethods)) {
|
|
195
|
+
const scanDir = resolveHostOutputDirectory(output, new URL(url).host, isBatch);
|
|
196
|
+
const scanResult = yield next_serverActionIdScan(scanDir);
|
|
197
|
+
if (scanResult.allActionIds.length > 0) {
|
|
198
|
+
printMsg(MSG.Run, `[✓] Found ${scanResult.allActionIds.length} Server Action ID(s) referenced in downloaded chunks (disclosure only — not invoked)`);
|
|
199
|
+
fs.writeFileSync(path.join(scanDir, "server_action_ids.json"), JSON.stringify(scanResult, null, 4));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
150
202
|
if (buildId) {
|
|
151
203
|
// get the buildId
|
|
152
204
|
// the directory is the output <output>/<host.replace(":", "_")>/___subsequent_requests
|
|
153
|
-
const
|
|
205
|
+
const targetOutputDir = resolveHostOutputDirectory(output, new URL(url).host, isBatch);
|
|
206
|
+
const buildId = yield next_buildId_RSC(path.join(targetOutputDir, "___subsequent_requests"));
|
|
207
|
+
if (hardTimeoutReached)
|
|
208
|
+
return;
|
|
154
209
|
if (buildId) {
|
|
155
|
-
|
|
210
|
+
printMsg(MSG.Header, "[+] Found buildId: " + buildId);
|
|
156
211
|
// now, write it to a file
|
|
157
|
-
fs.writeFileSync(path.join(
|
|
212
|
+
fs.writeFileSync(path.join(targetOutputDir, "BUILD_ID"), buildId);
|
|
158
213
|
}
|
|
159
214
|
}
|
|
160
215
|
// if the research mode is enabled, then write the technique efficiency to a file
|
|
161
216
|
if (research) {
|
|
162
217
|
// prettify the JSON and write
|
|
163
218
|
fs.writeFileSync(researchOutput, JSON.stringify(crawler.techniqueEfficiencyMapping, null, 4));
|
|
164
|
-
|
|
219
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
165
220
|
}
|
|
166
221
|
// extract the source maps
|
|
167
222
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
168
223
|
}
|
|
169
224
|
else if (tech.name === "vue") {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
activeQueue = new DownloadQueue(output, threads);
|
|
225
|
+
printMsg(MSG.Run, "[✓] Vue.js detected");
|
|
226
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
227
|
+
activeQueue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
173
228
|
const queue = activeQueue;
|
|
174
|
-
const onFilesDiscovered = (files) => queue
|
|
229
|
+
const onFilesDiscovered = (files) => enqueue(queue, files);
|
|
230
|
+
const vueResearchMap = {};
|
|
231
|
+
const vueOnTechnique = research ? createTechniqueRecorder(vueResearchMap) : undefined;
|
|
175
232
|
// run the full discovery pipeline against the entry URL
|
|
176
|
-
const { clientSidePaths } = yield vue_discoverJsFiles(url, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods, threads);
|
|
233
|
+
const { clientSidePaths } = yield vue_discoverJsFiles(url, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods, threads, true, true, vueOnTechnique);
|
|
234
|
+
if (hardTimeoutReached)
|
|
235
|
+
return;
|
|
177
236
|
// recurse the same pipeline through every client-side path we found
|
|
178
|
-
yield vue_recursiveClientSidePathDownload(clientSidePaths, threads, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods);
|
|
237
|
+
yield vue_recursiveClientSidePathDownload(clientSidePaths, threads, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods, vueOnTechnique);
|
|
238
|
+
if (hardTimeoutReached)
|
|
239
|
+
return;
|
|
179
240
|
yield queue.drain();
|
|
241
|
+
if (hardTimeoutReached)
|
|
242
|
+
return;
|
|
180
243
|
queue.printSummary();
|
|
244
|
+
if (research) {
|
|
245
|
+
fs.writeFileSync(researchOutput, JSON.stringify(vueResearchMap, null, 4));
|
|
246
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
247
|
+
}
|
|
181
248
|
// extract the source maps
|
|
182
249
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
183
250
|
}
|
|
184
251
|
else if (tech.name === "nuxt") {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const queue = new DownloadQueue(output, threads);
|
|
252
|
+
printMsg(MSG.Run, "[✓] Nuxt.js detected");
|
|
253
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
254
|
+
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
188
255
|
activeQueue = queue;
|
|
256
|
+
const nuxtResearchMap = {};
|
|
189
257
|
// find the files from the page source
|
|
190
258
|
const jsFilesFromPageSource = shouldRunMethod("nuxt_getFromPageSource", includeMethods, excludeMethods)
|
|
191
259
|
? yield nuxt_getFromPageSource(url)
|
|
192
260
|
: [];
|
|
193
|
-
queue
|
|
261
|
+
enqueue(queue, jsFilesFromPageSource);
|
|
262
|
+
if (research)
|
|
263
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_getFromPageSource", jsFilesFromPageSource);
|
|
194
264
|
const jsFilesFromStringAnalysis = shouldRunMethod("nuxt_stringAnalysisJSFiles", includeMethods, excludeMethods)
|
|
195
265
|
? yield nuxt_stringAnalysisJSFiles(url, threads)
|
|
196
266
|
: [];
|
|
197
|
-
queue
|
|
267
|
+
enqueue(queue, jsFilesFromStringAnalysis);
|
|
268
|
+
if (research)
|
|
269
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_stringAnalysisJSFiles", jsFilesFromStringAnalysis);
|
|
198
270
|
const firstBatch = [...new Set([...jsFilesFromPageSource, ...jsFilesFromStringAnalysis])];
|
|
199
|
-
|
|
271
|
+
const jsFilesFromAST = [];
|
|
200
272
|
if (shouldRunMethod("nuxt_astParse", includeMethods, excludeMethods)) {
|
|
201
|
-
|
|
273
|
+
printMsg(MSG.Header, "[i] Analyzing functions in the files found");
|
|
202
274
|
for (const jsFile of firstBatch) {
|
|
203
275
|
jsFilesFromAST.push(...(yield nuxt_astParse(jsFile)));
|
|
204
276
|
}
|
|
205
277
|
}
|
|
206
|
-
queue
|
|
207
|
-
|
|
278
|
+
enqueue(queue, jsFilesFromAST);
|
|
279
|
+
if (research)
|
|
280
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_astParse", jsFilesFromAST);
|
|
281
|
+
enqueue(queue, lazyLoadGlobals.getJsUrls());
|
|
208
282
|
const buildsManifestFiles = shouldRunMethod("nuxt_getBuildsManifest", includeMethods, excludeMethods)
|
|
209
283
|
? yield nuxt_getBuildsManifest(url)
|
|
210
284
|
: [];
|
|
211
|
-
queue
|
|
285
|
+
enqueue(queue, buildsManifestFiles);
|
|
286
|
+
if (research)
|
|
287
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_getBuildsManifest", buildsManifestFiles);
|
|
212
288
|
yield queue.drain();
|
|
289
|
+
if (hardTimeoutReached)
|
|
290
|
+
return;
|
|
213
291
|
queue.printSummary();
|
|
292
|
+
if (research) {
|
|
293
|
+
fs.writeFileSync(researchOutput, JSON.stringify(nuxtResearchMap, null, 4));
|
|
294
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
295
|
+
}
|
|
214
296
|
}
|
|
215
297
|
else if (tech.name === "svelte") {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const queue = new DownloadQueue(output, threads);
|
|
298
|
+
printMsg(MSG.Run, "[✓] Svelte detected");
|
|
299
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
300
|
+
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
219
301
|
activeQueue = queue;
|
|
302
|
+
const svelteResearchMap = {};
|
|
220
303
|
// find the files from the page source
|
|
221
304
|
const jsFilesFromPageSource = shouldRunMethod("svelte_getFromPageSource", includeMethods, excludeMethods)
|
|
222
305
|
? yield svelte_getFromPageSource(url)
|
|
223
306
|
: [];
|
|
224
|
-
queue
|
|
307
|
+
enqueue(queue, jsFilesFromPageSource);
|
|
308
|
+
if (research)
|
|
309
|
+
accumulateTechnique(svelteResearchMap, "svelte_getFromPageSource", jsFilesFromPageSource);
|
|
225
310
|
// probe /<appDir>/version.json — SvelteKit serves this for the `updated` store
|
|
226
311
|
// but never references it from HTML or JS, so it is invisible to all other steps
|
|
227
312
|
const appDir = (() => {
|
|
@@ -239,8 +324,10 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
239
324
|
? yield svelte_getVersionJson(url, appDir)
|
|
240
325
|
: [];
|
|
241
326
|
if (versionJsonFiles.length > 0) {
|
|
242
|
-
queue
|
|
327
|
+
enqueue(queue, versionJsonFiles);
|
|
243
328
|
}
|
|
329
|
+
if (research)
|
|
330
|
+
accumulateTechnique(svelteResearchMap, "svelte_getVersionJson", versionJsonFiles);
|
|
244
331
|
// analyze the strings now
|
|
245
332
|
let jsFilesFromStringAnalysis = [];
|
|
246
333
|
let mapFilesFromStringAnalysis = [];
|
|
@@ -248,27 +335,36 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
248
335
|
const result = yield svelte_stringAnalysisJSFiles(url, threads);
|
|
249
336
|
jsFilesFromStringAnalysis = result.jsFiles;
|
|
250
337
|
mapFilesFromStringAnalysis = result.mapFiles;
|
|
251
|
-
queue
|
|
338
|
+
enqueue(queue, jsFilesFromStringAnalysis);
|
|
252
339
|
if (mapFilesFromStringAnalysis.length > 0) {
|
|
253
|
-
queue
|
|
340
|
+
enqueue(queue, mapFilesFromStringAnalysis);
|
|
341
|
+
}
|
|
342
|
+
if (research) {
|
|
343
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", jsFilesFromStringAnalysis);
|
|
344
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", mapFilesFromStringAnalysis);
|
|
254
345
|
}
|
|
255
346
|
}
|
|
256
347
|
// recursively follow ESM static imports (import ... from "./chunk.js")
|
|
348
|
+
// svelte_followImports reuses react_followImports — tracked under react_followImports key
|
|
257
349
|
const visited = new Set();
|
|
258
350
|
let toFollow = [...new Set([...jsFilesFromPageSource, ...jsFilesFromStringAnalysis])];
|
|
259
351
|
while (toFollow.length > 0) {
|
|
260
352
|
const newFiles = yield react_followImports(toFollow, maxJsSizeMb, url, visited, threads);
|
|
261
353
|
if (newFiles.length === 0)
|
|
262
354
|
break;
|
|
263
|
-
|
|
264
|
-
queue
|
|
355
|
+
printMsg(MSG.Run, `[✓] Discovered ${newFiles.length} more JS file(s) via imports`);
|
|
356
|
+
enqueue(queue, newFiles);
|
|
357
|
+
if (research)
|
|
358
|
+
accumulateTechnique(svelteResearchMap, "react_followImports", newFiles);
|
|
265
359
|
toFollow = newFiles;
|
|
266
360
|
}
|
|
267
361
|
// crawl same-origin HTML pages found via <a href> and <link href>,
|
|
268
362
|
// running the full JS-discovery pipeline on each
|
|
269
363
|
const jsFilesFromPageCrawl = shouldRunMethod("svelte_recursivePageCrawl", includeMethods, excludeMethods)
|
|
270
|
-
? yield svelte_recursivePageCrawl(url, maxJsSizeMb, (files) => queue
|
|
364
|
+
? yield svelte_recursivePageCrawl(url, maxJsSizeMb, (files) => enqueue(queue, files))
|
|
271
365
|
: [];
|
|
366
|
+
if (research)
|
|
367
|
+
accumulateTechnique(svelteResearchMap, "svelte_recursivePageCrawl", jsFilesFromPageCrawl);
|
|
272
368
|
// Svelte/Astro apps use client-side routing — the home page rarely has
|
|
273
369
|
// <a href> links in its server-rendered HTML. Scan downloaded JS for
|
|
274
370
|
// embedded page path strings (e.g. "/admin", "/debug") and visit each
|
|
@@ -278,31 +374,46 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
278
374
|
? yield svelte_discoverPagesFromJs(url, threads)
|
|
279
375
|
: [];
|
|
280
376
|
if (jsFilesFromPathScan.length > 0) {
|
|
281
|
-
queue
|
|
377
|
+
enqueue(queue, jsFilesFromPathScan);
|
|
282
378
|
}
|
|
379
|
+
if (research)
|
|
380
|
+
accumulateTechnique(svelteResearchMap, "svelte_discoverPagesFromJs", jsFilesFromPathScan);
|
|
283
381
|
// run string analysis once more to catch JS files discovered during page crawl
|
|
284
382
|
if ((jsFilesFromPageCrawl.length > 0 || jsFilesFromPathScan.length > 0) &&
|
|
285
383
|
shouldRunMethod("svelte_stringAnalysisJSFiles", includeMethods, excludeMethods)) {
|
|
286
384
|
const { jsFiles: jsFilesFromStringAnalysis2, mapFiles: mapFilesFromStringAnalysis2 } = yield svelte_stringAnalysisJSFiles(url, threads);
|
|
287
|
-
queue
|
|
385
|
+
enqueue(queue, jsFilesFromStringAnalysis2);
|
|
288
386
|
if (mapFilesFromStringAnalysis2.length > 0) {
|
|
289
|
-
queue
|
|
387
|
+
enqueue(queue, mapFilesFromStringAnalysis2);
|
|
388
|
+
}
|
|
389
|
+
if (research) {
|
|
390
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", jsFilesFromStringAnalysis2);
|
|
391
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", mapFilesFromStringAnalysis2);
|
|
290
392
|
}
|
|
291
393
|
}
|
|
292
394
|
yield queue.drain();
|
|
395
|
+
if (hardTimeoutReached)
|
|
396
|
+
return;
|
|
293
397
|
queue.printSummary();
|
|
398
|
+
if (research) {
|
|
399
|
+
fs.writeFileSync(researchOutput, JSON.stringify(svelteResearchMap, null, 4));
|
|
400
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
401
|
+
}
|
|
294
402
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
295
403
|
}
|
|
296
404
|
else if (tech.name === "angular") {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const queue = new DownloadQueue(output, threads);
|
|
405
|
+
printMsg(MSG.Run, "[✓] Angular detected");
|
|
406
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
407
|
+
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
300
408
|
activeQueue = queue;
|
|
409
|
+
const angularResearchMap = {};
|
|
301
410
|
// find the files from the page source
|
|
302
411
|
const jsFilesFromPageSource = shouldRunMethod("angular_getFromPageSource", includeMethods, excludeMethods)
|
|
303
412
|
? yield angular_getFromPageSource(url)
|
|
304
413
|
: [];
|
|
305
|
-
queue
|
|
414
|
+
enqueue(queue, jsFilesFromPageSource);
|
|
415
|
+
if (research)
|
|
416
|
+
accumulateTechnique(angularResearchMap, "angular_getFromPageSource", jsFilesFromPageSource);
|
|
306
417
|
// files using the main.js
|
|
307
418
|
if (shouldRunMethod("angular_getFromMainJs", includeMethods, excludeMethods)) {
|
|
308
419
|
let mainJsUrl;
|
|
@@ -314,130 +425,155 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
314
425
|
}
|
|
315
426
|
if (mainJsUrl) {
|
|
316
427
|
const jsFilesFromMainJs = yield angular_getFromMainJs(mainJsUrl);
|
|
317
|
-
queue
|
|
428
|
+
enqueue(queue, jsFilesFromMainJs);
|
|
429
|
+
if (research)
|
|
430
|
+
accumulateTechnique(angularResearchMap, "angular_getFromMainJs", jsFilesFromMainJs);
|
|
318
431
|
// recursively follow chunk-to-chunk imports beyond the first hop
|
|
319
432
|
if (shouldRunMethod("angular_recursiveChunkImports", includeMethods, excludeMethods)) {
|
|
320
433
|
const transitiveChunks = yield angular_recursiveChunkImports(jsFilesFromMainJs, threads);
|
|
321
|
-
queue
|
|
434
|
+
enqueue(queue, transitiveChunks);
|
|
435
|
+
if (research)
|
|
436
|
+
accumulateTechnique(angularResearchMap, "angular_recursiveChunkImports", transitiveChunks);
|
|
322
437
|
}
|
|
323
438
|
}
|
|
324
439
|
}
|
|
325
440
|
yield queue.drain();
|
|
441
|
+
if (hardTimeoutReached)
|
|
442
|
+
return;
|
|
326
443
|
queue.printSummary();
|
|
444
|
+
if (research) {
|
|
445
|
+
fs.writeFileSync(researchOutput, JSON.stringify(angularResearchMap, null, 4));
|
|
446
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
447
|
+
}
|
|
327
448
|
}
|
|
328
449
|
else if (tech.name === "react") {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const queue = new DownloadQueue(output, threads
|
|
450
|
+
printMsg(MSG.Run, "[✓] React detected");
|
|
451
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
452
|
+
const queue = new DownloadQueue(output, threads, {
|
|
453
|
+
compactOutput: true,
|
|
454
|
+
onProgress: (progress) => activeDownloadProgress === null || activeDownloadProgress === void 0 ? void 0 : activeDownloadProgress.update(progress),
|
|
455
|
+
alreadyBatchTargetRoot: isBatch,
|
|
456
|
+
});
|
|
332
457
|
activeQueue = queue;
|
|
458
|
+
const reactResearchMap = {};
|
|
333
459
|
// Seed: <script src> tags + <link rel="modulepreload"> (Vite vendor chunks)
|
|
334
460
|
const jsFilesFromPageSource = shouldRunMethod("react_getScriptTags", includeMethods, excludeMethods)
|
|
335
|
-
? yield react_getScriptTags(url, maxJsSizeMb, output)
|
|
461
|
+
? yield react_getScriptTags(url, maxJsSizeMb, output, isBatch)
|
|
336
462
|
: [];
|
|
337
|
-
|
|
463
|
+
if (hardTimeoutReached)
|
|
464
|
+
return;
|
|
465
|
+
enqueue(queue, jsFilesFromPageSource);
|
|
466
|
+
if (research)
|
|
467
|
+
accumulateTechnique(reactResearchMap, "react_getScriptTags", jsFilesFromPageSource);
|
|
338
468
|
// webpack-style chunk path builders (CRA / custom webpack configs)
|
|
339
469
|
const webpackChunkPaths = shouldRunMethod("react_webpackChunkPaths", includeMethods, excludeMethods)
|
|
340
470
|
? yield react_webpackChunkPaths(url, maxJsSizeMb, jsFilesFromPageSource, threads)
|
|
341
471
|
: [];
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
toFollow =
|
|
472
|
+
if (hardTimeoutReached)
|
|
473
|
+
return;
|
|
474
|
+
activeDownloadProgress = new DownloadProgress();
|
|
475
|
+
activeDownloadProgress.update(queue.progress);
|
|
476
|
+
try {
|
|
477
|
+
enqueue(queue, webpackChunkPaths);
|
|
478
|
+
if (research)
|
|
479
|
+
accumulateTechnique(reactResearchMap, "react_webpackChunkPaths", webpackChunkPaths);
|
|
480
|
+
// Recursively follow ESM imports and Vite __vite_mapDeps references.
|
|
481
|
+
// visited starts empty so the seed files are fetched and parsed in the first round.
|
|
482
|
+
const visited = new Set();
|
|
483
|
+
if (shouldRunMethod("react_followImports", includeMethods, excludeMethods)) {
|
|
484
|
+
let toFollow = [...new Set([...jsFilesFromPageSource, ...webpackChunkPaths])];
|
|
485
|
+
while (toFollow.length > 0 && !hardTimeoutReached) {
|
|
486
|
+
const newFiles = yield react_followImports(toFollow, maxJsSizeMb, url, visited, threads, true);
|
|
487
|
+
if (hardTimeoutReached)
|
|
488
|
+
break;
|
|
489
|
+
if (newFiles.length === 0)
|
|
490
|
+
break;
|
|
491
|
+
progressLog(chalk.green(`[✓] Discovered ${newFiles.length} more JS file(s) via imports`));
|
|
492
|
+
enqueue(queue, newFiles);
|
|
493
|
+
if (research)
|
|
494
|
+
accumulateTechnique(reactResearchMap, "react_followImports", newFiles);
|
|
495
|
+
toFollow = newFiles;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// Sourcemaps for everything discovered
|
|
499
|
+
if (!hardTimeoutReached &&
|
|
500
|
+
shouldRunMethod("react_sourcemapUrls", includeMethods, excludeMethods)) {
|
|
501
|
+
const sourcemapUrls = yield react_sourcemapUrls([...visited], threads);
|
|
502
|
+
enqueue(queue, sourcemapUrls);
|
|
503
|
+
if (research)
|
|
504
|
+
accumulateTechnique(reactResearchMap, "react_sourcemapUrls", sourcemapUrls);
|
|
355
505
|
}
|
|
506
|
+
yield queue.drain();
|
|
356
507
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
queue.push(sourcemapUrls);
|
|
508
|
+
finally {
|
|
509
|
+
activeDownloadProgress === null || activeDownloadProgress === void 0 ? void 0 : activeDownloadProgress.stop();
|
|
510
|
+
activeDownloadProgress = null;
|
|
361
511
|
}
|
|
362
|
-
|
|
512
|
+
if (hardTimeoutReached)
|
|
513
|
+
return;
|
|
363
514
|
queue.printSummary();
|
|
364
|
-
|
|
515
|
+
if (research) {
|
|
516
|
+
fs.writeFileSync(researchOutput, JSON.stringify(reactResearchMap, null, 4));
|
|
517
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
518
|
+
}
|
|
519
|
+
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
365
520
|
}
|
|
366
521
|
}
|
|
367
522
|
else {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
secondChanceEvidence = u;
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (secondChanceTech) {
|
|
397
|
-
console.log(chalk.green(`[✓] Detected ${secondChanceTech} from downloaded file paths (evidence: ${secondChanceEvidence})`));
|
|
398
|
-
globals.setTech(secondChanceTech);
|
|
399
|
-
}
|
|
400
|
-
const queue = new DownloadQueue(output, threads);
|
|
401
|
-
queue.push(js_urls);
|
|
402
|
-
yield queue.drain();
|
|
403
|
-
queue.printSummary();
|
|
523
|
+
printMsg(MSG.Warn, "[i] Framework not detected — falling back to generic JS extraction");
|
|
524
|
+
globals.setTech("generic");
|
|
525
|
+
// If the caller didn't customize scope (still the "*" default) and isn't
|
|
526
|
+
// using --strict-scope, default the generic crawl's scope to the origin
|
|
527
|
+
// reached after following redirects, rather than crawling the whole web.
|
|
528
|
+
if (!strictScope && inputScope.length === 1 && inputScope[0] === "*") {
|
|
529
|
+
const resolvedScope = yield resolveGenericScope(url, maxRedirects);
|
|
530
|
+
lazyLoadGlobals.setScope(resolvedScope);
|
|
531
|
+
}
|
|
532
|
+
// Downloads JS incrementally as pages are crawled (see generic_crawlPages.ts) —
|
|
533
|
+
// the returned list is only used for the final summary count.
|
|
534
|
+
const genericResearchMap = {};
|
|
535
|
+
const allUrls = yield generic_crawlPages(url, maxJsSizeMb, output, maxPageVisits, threads, research ? genericResearchMap : undefined, stringsEnabled, stringsMaxIterations, getLastInterceptedUrls(), stagnationTimeinMs, stagnationPercentage, stagnationMonitorMs);
|
|
536
|
+
if (hardTimeoutReached)
|
|
537
|
+
return;
|
|
538
|
+
if (allUrls.length > 0) {
|
|
539
|
+
printMsg(MSG.Run, `[✓] Found ${allUrls.length} JS file(s)`);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
printMsg(MSG.Warn, "[i] No JS files discovered");
|
|
543
|
+
}
|
|
544
|
+
if (research) {
|
|
545
|
+
fs.writeFileSync(researchOutput, JSON.stringify(genericResearchMap, null, 4));
|
|
546
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
404
547
|
}
|
|
405
548
|
}
|
|
406
549
|
}
|
|
407
550
|
});
|
|
408
551
|
if (hardTimeoutMs === 0) {
|
|
409
|
-
|
|
410
|
-
|
|
552
|
+
try {
|
|
553
|
+
yield withRequestSignal(workController.signal, work);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
finally {
|
|
557
|
+
cancellationSignal === null || cancellationSignal === void 0 ? void 0 : cancellationSignal.removeEventListener("abort", handleExternalCancellation);
|
|
558
|
+
yield cleanupActiveWork();
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const timeoutHandle = setTimeout(() => {
|
|
562
|
+
requestCancellation();
|
|
563
|
+
const timeoutLabel = hardTimeoutMs >= 60000 ? `${hardTimeoutMs / 60000} min` : `${hardTimeoutMs}ms`;
|
|
564
|
+
progressWarn(chalk.yellow(`[!] Lazyload hard timeout reached (${timeoutLabel}). Stopping discovery and waiting for in-flight work...`));
|
|
565
|
+
}, hardTimeoutMs);
|
|
566
|
+
try {
|
|
567
|
+
// Never return while work() can still mutate files, globals, or terminal
|
|
568
|
+
// state. The timeout requests cooperative cancellation, then this await
|
|
569
|
+
// provides the lifecycle boundary for all in-flight framework work.
|
|
570
|
+
yield withRequestSignal(workController.signal, work);
|
|
571
|
+
}
|
|
572
|
+
finally {
|
|
573
|
+
clearTimeout(timeoutHandle);
|
|
574
|
+
cancellationSignal === null || cancellationSignal === void 0 ? void 0 : cancellationSignal.removeEventListener("abort", handleExternalCancellation);
|
|
575
|
+
yield cleanupActiveWork();
|
|
411
576
|
}
|
|
412
|
-
let timeoutHandle;
|
|
413
|
-
yield Promise.race([
|
|
414
|
-
work().finally(() => {
|
|
415
|
-
// work() finished before the timeout — cancel the timer so it never
|
|
416
|
-
// fires orphaned and doesn't hold the event loop open.
|
|
417
|
-
if (timeoutHandle !== undefined)
|
|
418
|
-
clearTimeout(timeoutHandle);
|
|
419
|
-
}),
|
|
420
|
-
new Promise((resolve) => {
|
|
421
|
-
timeoutHandle = setTimeout(() => {
|
|
422
|
-
console.error(chalk.yellow(`[!] Lazyload hard timeout reached (${hardTimeoutMs / 60000} min). Draining discovered files before moving on...`));
|
|
423
|
-
// Signal the crawler to stop at its next iteration boundary.
|
|
424
|
-
activeCrawler === null || activeCrawler === void 0 ? void 0 : activeCrawler.stop();
|
|
425
|
-
const q = activeQueue;
|
|
426
|
-
if (q) {
|
|
427
|
-
// Wait for already-queued downloads to finish, then move on.
|
|
428
|
-
q.drain()
|
|
429
|
-
.then(() => {
|
|
430
|
-
q.printSummary();
|
|
431
|
-
resolve();
|
|
432
|
-
})
|
|
433
|
-
.catch(() => resolve());
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
resolve();
|
|
437
|
-
}
|
|
438
|
-
}, hardTimeoutMs);
|
|
439
|
-
}),
|
|
440
|
-
]);
|
|
441
577
|
});
|
|
442
578
|
export default lazyLoad;
|
|
443
579
|
//# sourceMappingURL=index.js.map
|