@js-recon/js-recon 1.4.4 → 2.0.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-sync/sync.sh +1 -1
- package/.github/dependabot.yml +50 -0
- package/.github/workflows/build-and-prettify.yaml +49 -19
- 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 +31 -2
- package/.github/workflows/rules-smoke-test.yaml +13 -5
- package/.nvmrc +1 -0
- package/.plumber.yaml +151 -0
- package/CHANGELOG.md +55 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +1 -0
- package/README.md +3 -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 +9 -9
- 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 +733 -0
- package/build/cliProgram.js.map +1 -0
- package/build/completion/index.js +247 -382
- 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 +3 -2
- package/build/config/applicationConfig.js.map +1 -1
- 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 +56 -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 +3 -2
- 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 +5 -596
- 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 +14 -11
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/downloadQueue.js +9 -1
- package/build/lazyLoad/downloadQueue.js.map +1 -1
- package/build/lazyLoad/downloadResponse.js +1 -0
- package/build/lazyLoad/downloadResponse.js.map +1 -1
- 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 +66 -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 +31 -0
- package/build/lazyLoad/globals.js.map +1 -1
- package/build/lazyLoad/index.js +172 -75
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/methodFilter.js +9 -1
- package/build/lazyLoad/methodFilter.js.map +1 -1
- package/build/lazyLoad/next_js/NextJsCrawler.js +98 -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 +17 -11
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +7 -6
- 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 +407 -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 +29 -5
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/react/react_sourcemapUrls.js +7 -28
- package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -1
- package/build/lazyLoad/react/react_webpackChunkPaths.js +10 -202
- 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/sourcemap.js +120 -0
- package/build/lazyLoad/sourcemap.js.map +1 -1
- 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 +15 -6
- 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 +17 -1
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -2
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +13 -11
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +12 -3
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js +3 -3
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
- package/build/load/index.js +28 -38
- 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 +4 -3
- 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 +6 -5
- package/build/mcp/tools.js.map +1 -1
- package/build/proxy/detectBlockedResponse.js +2 -0
- package/build/proxy/detectBlockedResponse.js.map +1 -1
- package/build/proxy/index.js +3 -3
- package/build/proxy/index.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/dataTables/genDataTablesPage.js +2 -1
- package/build/report/utility/dataTables/genDataTablesPage.js.map +1 -1
- package/build/report/utility/genHtml.js +316 -25
- package/build/report/utility/genHtml.js.map +1 -1
- package/build/report/utility/markdownGen/addAnalyze.js +2 -1
- package/build/report/utility/markdownGen/addAnalyze.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/report/utility/severityColors.js +35 -0
- package/build/report/utility/severityColors.js.map +1 -0
- package/build/run/bundler-detect.js +45 -9
- package/build/run/bundler-detect.js.map +1 -1
- 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 +177 -110
- 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/sourcemaps/index.js +7 -6
- package/build/sourcemaps/index.js.map +1 -1
- package/build/strings/index.js +27 -24
- 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/cacheDb.js +78 -0
- package/build/utility/cacheDb.js.map +1 -0
- package/build/utility/configureSandbox.js +2 -2
- package/build/utility/configureSandbox.js.map +1 -1
- package/build/utility/customHeaders.js +30 -0
- package/build/utility/customHeaders.js.map +1 -0
- package/build/utility/globals.js +37 -12
- 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 +38 -87
- 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 +4 -3
- 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/config.dist.yaml +3 -3
- package/contributing/testing.md +106 -0
- package/eslint.config.js +24 -0
- package/package.json +22 -6
- 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
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as cheerio from "cheerio";
|
|
2
|
+
const resolvePageUrl = (rawValue, baseUrl) => {
|
|
3
|
+
if (!rawValue)
|
|
4
|
+
return null;
|
|
5
|
+
const trimmed = rawValue.trim();
|
|
6
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
7
|
+
return null;
|
|
8
|
+
if (/^(mailto|tel|javascript|data|blob):/i.test(trimmed))
|
|
9
|
+
return null;
|
|
10
|
+
let resolved;
|
|
11
|
+
try {
|
|
12
|
+
resolved = new URL(trimmed, baseUrl);
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (resolved.protocol !== "http:" && resolved.protocol !== "https:")
|
|
18
|
+
return null;
|
|
19
|
+
resolved.hash = "";
|
|
20
|
+
return resolved.href;
|
|
21
|
+
};
|
|
22
|
+
// Matches an absolute http(s) URL embedded anywhere in a string — e.g. inside an
|
|
23
|
+
// onclick handler's JS: onclick="return powerpress_pinw('https://site/?pinw=123')".
|
|
24
|
+
// Deliberately not tied to a specific function name (window.open, a plugin helper,
|
|
25
|
+
// etc.) — popup/widget links are triggered through all sorts of call shapes, but the
|
|
26
|
+
// URL argument itself is always a plain quoted absolute URL, which this catches
|
|
27
|
+
// regardless of what function it's passed to.
|
|
28
|
+
const EMBEDDED_URL_RE = /https?:\/\/[^\s'"<>)]+/g;
|
|
29
|
+
/**
|
|
30
|
+
* Extracts every absolute http(s) URL substring embedded in a string value (typically
|
|
31
|
+
* an onclick handler or other inline JS attribute). See EMBEDDED_URL_RE for why this
|
|
32
|
+
* isn't tied to a specific JS call pattern like window.open(...).
|
|
33
|
+
*/
|
|
34
|
+
export const extractEmbeddedUrls = (attrValue) => [...attrValue.matchAll(EMBEDDED_URL_RE)].map((m) => m[0]);
|
|
35
|
+
/**
|
|
36
|
+
* Extracts navigable page URLs from <a href>/<iframe src> tags and absolute URLs
|
|
37
|
+
* embedded in any other attribute value (typically an onclick handler) — not JS
|
|
38
|
+
* files. Used to recursively discover more HTML pages to scan for JS, per
|
|
39
|
+
* internal#66. <iframe src> and onclick-embedded URLs are included alongside
|
|
40
|
+
* <a href> because embedded widgets (a podcast player, a survey, a booking form) are
|
|
41
|
+
* commonly reachable only via an iframe or a JS-driven popup, never a plain link —
|
|
42
|
+
* WordPress's PowerPress podcast plugin is one real example: its "pop out player"
|
|
43
|
+
* link is `onclick="return powerpress_pinw('https://site/?powerpress_pinw=123-podcast')"`,
|
|
44
|
+
* invisible to href-only or iframe-only crawling. Filters out fragment-only links,
|
|
45
|
+
* non-http(s) schemes (mailto/tel/javascript/data/blob), and strips the hash so
|
|
46
|
+
* #section variants of the same page dedupe to one entry.
|
|
47
|
+
*/
|
|
48
|
+
export const extractPageLinks = (html, baseUrl) => {
|
|
49
|
+
const $ = cheerio.load(html);
|
|
50
|
+
const links = new Set();
|
|
51
|
+
$("a[href], iframe[src]").each((_, elem) => {
|
|
52
|
+
var _a;
|
|
53
|
+
const rawValue = (_a = $(elem).attr("href")) !== null && _a !== void 0 ? _a : $(elem).attr("src");
|
|
54
|
+
const resolved = resolvePageUrl(rawValue, baseUrl);
|
|
55
|
+
if (resolved)
|
|
56
|
+
links.add(resolved);
|
|
57
|
+
});
|
|
58
|
+
$("*").each((_, elem) => {
|
|
59
|
+
const attribs = elem.attribs;
|
|
60
|
+
if (!attribs)
|
|
61
|
+
return;
|
|
62
|
+
for (const [attrName, value] of Object.entries(attribs)) {
|
|
63
|
+
// href/src already handled above via cheerio's typed accessors; re-scanning
|
|
64
|
+
// them here would just re-add the same URL, which the Set dedupes anyway,
|
|
65
|
+
// but skipping is cheaper and avoids false "embedded URL" matches inside a
|
|
66
|
+
// long querystring value that itself contains another URL as a parameter.
|
|
67
|
+
if (attrName === "href" || attrName === "src" || !value)
|
|
68
|
+
continue;
|
|
69
|
+
for (const embeddedUrl of extractEmbeddedUrls(value)) {
|
|
70
|
+
const resolved = resolvePageUrl(embeddedUrl, baseUrl);
|
|
71
|
+
if (resolved)
|
|
72
|
+
links.add(resolved);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return [...links];
|
|
77
|
+
};
|
|
78
|
+
export default extractPageLinks;
|
|
79
|
+
//# sourceMappingURL=generic_extractLinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic_extractLinks.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_extractLinks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import makeRequest from "../../utility/makeReq.js";
|
|
11
|
+
import * as cheerio from "cheerio";
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import crypto from "crypto";
|
|
15
|
+
import * as lazyLoadGlobals from "../globals.js";
|
|
16
|
+
import { printMsg, MSG } from "../../utility/printMsg.js";
|
|
17
|
+
// <script type="..."> values known to hold non-JS content. Browsers never execute
|
|
18
|
+
// these as script — WordPress/plugins routinely stash JSON-LD structured data or
|
|
19
|
+
// browser resource-hint configs in a bare <script> tag with no src, and saving
|
|
20
|
+
// that content as a .js file breaks any JS parser later run against it (Babel
|
|
21
|
+
// can't parse a top-level JSON object as a JS Program).
|
|
22
|
+
const NON_JS_SCRIPT_TYPES = [
|
|
23
|
+
"application/ld+json",
|
|
24
|
+
"application/json",
|
|
25
|
+
"speculationrules",
|
|
26
|
+
"importmap",
|
|
27
|
+
"text/template",
|
|
28
|
+
"text/x-template",
|
|
29
|
+
"text/x-handlebars-template",
|
|
30
|
+
"text/x-jquery-tmpl",
|
|
31
|
+
"text/ng-template",
|
|
32
|
+
"text/html",
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Whether a <script type="..."> value indicates the tag's content should be
|
|
36
|
+
* treated as JS. Missing/empty type defaults to JS per the HTML spec. Deliberately
|
|
37
|
+
* permissive for unrecognized types (e.g. Cloudflare Rocket Loader rewrites
|
|
38
|
+
* type="text/javascript" to a randomized "<hash>-text/javascript" to defer
|
|
39
|
+
* execution — still real JS) — only the known non-JS types above are excluded.
|
|
40
|
+
*/
|
|
41
|
+
export const isLikelyJsScriptType = (type) => {
|
|
42
|
+
if (!type)
|
|
43
|
+
return true;
|
|
44
|
+
const normalized = type.trim().toLowerCase();
|
|
45
|
+
if (!normalized)
|
|
46
|
+
return true;
|
|
47
|
+
if (normalized.includes("javascript") || normalized === "module" || normalized.includes("ecmascript")) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return !NON_JS_SCRIPT_TYPES.some((t) => normalized.includes(t));
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Decodes a data: URI script src (e.g. `data:text/javascript;base64,...`) into
|
|
54
|
+
* its JS source text. Returns null if the URI doesn't match the expected shape
|
|
55
|
+
* or the payload can't be decoded.
|
|
56
|
+
*/
|
|
57
|
+
export const decodeDataUriScript = (dataUri) => {
|
|
58
|
+
const match = /^data:([^,]*),([\s\S]*)$/.exec(dataUri);
|
|
59
|
+
if (!match)
|
|
60
|
+
return null;
|
|
61
|
+
const [, meta, payload] = match;
|
|
62
|
+
const isBase64 = /;base64$/i.test(meta);
|
|
63
|
+
try {
|
|
64
|
+
return isBase64 ? Buffer.from(payload, "base64").toString("utf-8") : decodeURIComponent(payload);
|
|
65
|
+
}
|
|
66
|
+
catch (_a) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Extracts JS chunk URLs from <script src> and <link rel="modulepreload"> tags,
|
|
72
|
+
* and saves inline <script> bodies (inline text and decoded data: URIs) to disk.
|
|
73
|
+
* Every saved file carries a `// File Source: <url>` header — this is what lets
|
|
74
|
+
* generic_stringsDiscovery.ts later resolve string-literal JS paths found inside
|
|
75
|
+
* these files against the URL they actually came from. Mirrors react_getScriptTags.ts
|
|
76
|
+
* — the same seeding pattern applies to any site regardless of framework.
|
|
77
|
+
*/
|
|
78
|
+
const generic_getScriptTags = (url, maxJsSizeMb, outputDir) => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
let toReturn = [];
|
|
80
|
+
const req = yield makeRequest(url);
|
|
81
|
+
const pageSource = req ? yield req.text() : "";
|
|
82
|
+
const $ = cheerio.load(pageSource);
|
|
83
|
+
const host = new URL(url).host.replace(":", "_");
|
|
84
|
+
// Mirrors the page's own path, not just its host — so inline scripts from
|
|
85
|
+
// different pages of a multi-page generic crawl (internal#66) land in
|
|
86
|
+
// separate directories instead of colliding on inline-0.js, inline-1.js, etc.
|
|
87
|
+
const pageDir = new URL(url).pathname;
|
|
88
|
+
let inlineIndex = 0;
|
|
89
|
+
$("script").each((_, elem) => {
|
|
90
|
+
const src = $(elem).attr("src");
|
|
91
|
+
if (src) {
|
|
92
|
+
let resolved;
|
|
93
|
+
try {
|
|
94
|
+
resolved = new URL(src, url);
|
|
95
|
+
}
|
|
96
|
+
catch (_a) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// A data: URI script src embeds the JS source directly — it isn't a
|
|
100
|
+
// network-fetchable URL, so pushing it to toReturn would make the
|
|
101
|
+
// downloader try (and fail) to request/save it as a file.
|
|
102
|
+
if (resolved.protocol === "data:") {
|
|
103
|
+
if (!outputDir)
|
|
104
|
+
return;
|
|
105
|
+
const content = decodeDataUriScript(resolved.href);
|
|
106
|
+
if (!content)
|
|
107
|
+
return;
|
|
108
|
+
const hostDir = path.join(outputDir, host, pageDir);
|
|
109
|
+
fs.mkdirSync(hostDir, { recursive: true });
|
|
110
|
+
const filename = `inline-${inlineIndex++}.js`;
|
|
111
|
+
const filePath = path.join(hostDir, filename);
|
|
112
|
+
fs.writeFileSync(filePath, `// File Source: ${url} (data URI script #${inlineIndex - 1})\n${content}`);
|
|
113
|
+
lazyLoadGlobals.recordJsFileHash(crypto.createHash("sha256").update(content).digest("hex"));
|
|
114
|
+
printMsg(MSG.Run, `[✓] Saved data URI script to ${filePath}`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// blob:, javascript:, etc — not something we can fetch over the network either.
|
|
118
|
+
if (resolved.protocol !== "http:" && resolved.protocol !== "https:")
|
|
119
|
+
return;
|
|
120
|
+
toReturn.push(resolved.href);
|
|
121
|
+
}
|
|
122
|
+
else if (outputDir) {
|
|
123
|
+
if (!isLikelyJsScriptType($(elem).attr("type")))
|
|
124
|
+
return;
|
|
125
|
+
const content = $(elem).text().trim();
|
|
126
|
+
if (!content)
|
|
127
|
+
return;
|
|
128
|
+
const hostDir = path.join(outputDir, host, pageDir);
|
|
129
|
+
fs.mkdirSync(hostDir, { recursive: true });
|
|
130
|
+
const filename = `inline-${inlineIndex++}.js`;
|
|
131
|
+
const filePath = path.join(hostDir, filename);
|
|
132
|
+
fs.writeFileSync(filePath, `// File Source: ${url} (inline script #${inlineIndex - 1})\n${content}`);
|
|
133
|
+
lazyLoadGlobals.recordJsFileHash(crypto.createHash("sha256").update(content).digest("hex"));
|
|
134
|
+
printMsg(MSG.Run, `[✓] Saved inline script to ${filePath}`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
$("link[rel='modulepreload']").each((_, elem) => {
|
|
138
|
+
const href = $(elem).attr("href");
|
|
139
|
+
if (href) {
|
|
140
|
+
try {
|
|
141
|
+
toReturn.push(new URL(href, url).href);
|
|
142
|
+
}
|
|
143
|
+
catch (_a) {
|
|
144
|
+
/* not a resolvable URL — skip */
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
toReturn = [...new Set(toReturn)];
|
|
149
|
+
return { urls: toReturn, pageSource };
|
|
150
|
+
});
|
|
151
|
+
export default generic_getScriptTags;
|
|
152
|
+
//# sourceMappingURL=generic_getScriptTags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic_getScriptTags.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_getScriptTags.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import { confirmJsContentType } from "./generic_scanAttributesForJs.js";
|
|
13
|
+
/**
|
|
14
|
+
* Parses a downloaded file's content for a Webpack Module Federation "import map"
|
|
15
|
+
* manifest shape:
|
|
16
|
+
* { "microFrontends": { "<scope>/<name>": [{ "url": "https://.../remote-entry.js", ... }] } }
|
|
17
|
+
* and returns every remote-entry-style URL it lists. Tolerates the
|
|
18
|
+
* `// File Source: <url>\n` header `generic_downloadFiles.ts` prefixes onto every
|
|
19
|
+
* downloaded file — these manifests are typically referenced via a literal
|
|
20
|
+
* `<script src="...prod.json">` tag (picked up like any other script by
|
|
21
|
+
* `generic_getScriptTags.ts` regardless of extension) and saved under a synthesized
|
|
22
|
+
* `.js` filename despite being JSON (see `generic_downloadFiles.ts::synthesizeFilename`),
|
|
23
|
+
* so the header must be stripped before `JSON.parse`.
|
|
24
|
+
*/
|
|
25
|
+
export const extractMicroFrontendUrls = (content) => {
|
|
26
|
+
const withoutHeader = content.replace(/^\/\/ File Source: \S+\n/, "");
|
|
27
|
+
let data;
|
|
28
|
+
try {
|
|
29
|
+
data = JSON.parse(withoutHeader);
|
|
30
|
+
}
|
|
31
|
+
catch (_a) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
if (typeof data !== "object" || data === null || !("microFrontends" in data))
|
|
35
|
+
return [];
|
|
36
|
+
const microFrontends = data.microFrontends;
|
|
37
|
+
if (typeof microFrontends !== "object" || microFrontends === null)
|
|
38
|
+
return [];
|
|
39
|
+
const urls = new Set();
|
|
40
|
+
for (const entries of Object.values(microFrontends)) {
|
|
41
|
+
if (!Array.isArray(entries))
|
|
42
|
+
continue;
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const url = entry === null || entry === void 0 ? void 0 : entry.url;
|
|
45
|
+
if (typeof url === "string" && /^https?:\/\//i.test(url) && url.toLowerCase().endsWith(".js")) {
|
|
46
|
+
urls.add(url);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return [...urls];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Scans every file `generic` tech has already downloaded under outputDir for a
|
|
54
|
+
* micro-frontend import-map manifest (see `extractMicroFrontendUrls`) and confirms each
|
|
55
|
+
* referenced remote-entry URL via Content-Type before returning it as a new download
|
|
56
|
+
* candidate. Internal#74: js-recon was already downloading these manifests (picked up
|
|
57
|
+
* like any other `<script src>`) but never reading them — every remote a
|
|
58
|
+
* module-federation app can dynamically load is listed here, including remotes whose
|
|
59
|
+
* components never rendered (and so never fired a request) during the crawl.
|
|
60
|
+
*/
|
|
61
|
+
const generic_importMapDiscovery = (outputDir_1, ...args_1) => __awaiter(void 0, [outputDir_1, ...args_1], void 0, function* (outputDir, alreadyKnownUrls = new Set(), threads = 1) {
|
|
62
|
+
if (!fs.existsSync(outputDir))
|
|
63
|
+
return [];
|
|
64
|
+
const files = fs.readdirSync(outputDir, { recursive: true, encoding: "utf8" });
|
|
65
|
+
const candidates = new Set();
|
|
66
|
+
for (const relPath of files) {
|
|
67
|
+
if (!/\.(js|mjs|json)$/i.test(relPath))
|
|
68
|
+
continue;
|
|
69
|
+
const filePath = path.join(outputDir, relPath);
|
|
70
|
+
let content;
|
|
71
|
+
try {
|
|
72
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
73
|
+
}
|
|
74
|
+
catch (_a) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
for (const url of extractMicroFrontendUrls(content)) {
|
|
78
|
+
if (!alreadyKnownUrls.has(url))
|
|
79
|
+
candidates.add(url);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (candidates.size === 0)
|
|
83
|
+
return [];
|
|
84
|
+
return confirmJsContentType([...candidates], threads);
|
|
85
|
+
});
|
|
86
|
+
export default generic_importMapDiscovery;
|
|
87
|
+
//# sourceMappingURL=generic_importMapDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic_importMapDiscovery.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_importMapDiscovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { printMsg, MSG } from "../../utility/printMsg.js";
|
|
11
|
+
import { customHeadersToRecord } from "../../utility/customHeaders.js";
|
|
12
|
+
import * as globals from "../../utility/globals.js";
|
|
13
|
+
/**
|
|
14
|
+
* Extracts the host (scheme-independent, matches the format used throughout
|
|
15
|
+
* `lazyLoad/globals.ts`'s scope list) from a URL.
|
|
16
|
+
*/
|
|
17
|
+
export const hostFromUrl = (url) => new URL(url).host;
|
|
18
|
+
/**
|
|
19
|
+
* Manually follows HTTP redirects starting at startUrl, up to maxRedirects hops,
|
|
20
|
+
* and returns the final URL reached. Uses redirect: "manual" (rather than the
|
|
21
|
+
* platform default of automatically following) so the hop count is actually
|
|
22
|
+
* enforced by this function instead of an opaque undici-internal limit.
|
|
23
|
+
*/
|
|
24
|
+
export const resolveRedirectChain = (startUrl_1, maxRedirects_1, ...args_1) => __awaiter(void 0, [startUrl_1, maxRedirects_1, ...args_1], void 0, function* (startUrl, maxRedirects, fetchImpl = fetch) {
|
|
25
|
+
let currentUrl = startUrl;
|
|
26
|
+
for (let i = 0; i < maxRedirects; i++) {
|
|
27
|
+
let res;
|
|
28
|
+
try {
|
|
29
|
+
res = yield fetchImpl(currentUrl, {
|
|
30
|
+
redirect: "manual",
|
|
31
|
+
headers: customHeadersToRecord(globals.getCustomHeaders()),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (_a) {
|
|
35
|
+
return currentUrl;
|
|
36
|
+
}
|
|
37
|
+
if (res.status >= 300 && res.status < 400) {
|
|
38
|
+
const location = res.headers.get("location");
|
|
39
|
+
if (!location)
|
|
40
|
+
return currentUrl;
|
|
41
|
+
try {
|
|
42
|
+
currentUrl = new URL(location, currentUrl).href;
|
|
43
|
+
}
|
|
44
|
+
catch (_b) {
|
|
45
|
+
return currentUrl;
|
|
46
|
+
}
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
return currentUrl;
|
|
50
|
+
}
|
|
51
|
+
return currentUrl;
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Default scope for the `generic` tech: fetch the target URL, follow redirects
|
|
55
|
+
* (capped at maxRedirects), and scope the crawl to the host of the final
|
|
56
|
+
* destination. Without this, an unscoped generic crawl would follow every
|
|
57
|
+
* in-page link across the entire web.
|
|
58
|
+
*/
|
|
59
|
+
const resolveGenericScope = (url, maxRedirects) => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
const finalUrl = yield resolveRedirectChain(url, maxRedirects);
|
|
61
|
+
const host = hostFromUrl(finalUrl);
|
|
62
|
+
printMsg(MSG.Header, `[i] Generic crawl scope resolved to: ${host}`);
|
|
63
|
+
return [host];
|
|
64
|
+
});
|
|
65
|
+
export default resolveGenericScope;
|
|
66
|
+
//# sourceMappingURL=generic_resolveScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic_resolveScope.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_resolveScope.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,wCAIjB,EAAE,+EAHjB,QAAgB,EAChB,YAAoB,EACpB,YAA0B,KAAK;IAE/B,IAAI,UAAU,GAAG,QAAQ,CAAC;IAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE;gBAC9B,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;aAC7D,CAAC,CAAC;QACP,CAAC;QAAC,WAAM,CAAC;YACL,OAAO,UAAU,CAAC;QACtB,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ;gBAAE,OAAO,UAAU,CAAC;YACjC,IAAI,CAAC;gBACD,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC;YACpD,CAAC;YAAC,WAAM,CAAC;gBACL,OAAO,UAAU,CAAC;YACtB,CAAC;YACD,SAAS;QACb,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAA,CAAC;AAEF;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAO,GAAW,EAAE,YAAoB,EAAqB,EAAE;IACvF,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,wCAAwC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC,CAAA,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import * as cheerio from "cheerio";
|
|
11
|
+
import makeRequest from "../../utility/makeReq.js";
|
|
12
|
+
import { isJsContentType } from "./generic_jsMimeTypes.js";
|
|
13
|
+
import { printMsg, MSG } from "../../utility/printMsg.js";
|
|
14
|
+
/**
|
|
15
|
+
* Resolves value against baseUrl and returns the href if it's a network-fetchable
|
|
16
|
+
* (http/https) URL with a path segment ending in ".js" — this is what catches assets
|
|
17
|
+
* served like ".../beacon.min.js/v124/token" (a ".js"-suffixed segment that isn't the
|
|
18
|
+
* last one, so a plain endsWith(".js") check on the whole path would miss it). Returns
|
|
19
|
+
* null for anything unparseable or non-http(s) (data:/blob:/javascript: etc — these
|
|
20
|
+
* aren't requests confirmJsContentType could ever meaningfully make).
|
|
21
|
+
*/
|
|
22
|
+
export const resolveJsPathCandidate = (value, baseUrl) => {
|
|
23
|
+
if (!value)
|
|
24
|
+
return null;
|
|
25
|
+
const trimmed = value.trim();
|
|
26
|
+
if (!trimmed)
|
|
27
|
+
return null;
|
|
28
|
+
// A fragment-only ("#selector") or query-only ("?x=1") value resolves against
|
|
29
|
+
// baseUrl by inheriting its pathname completely unchanged. When baseUrl is itself
|
|
30
|
+
// a .js file (e.g. generic_stringsDiscovery.ts resolving strings found INSIDE an
|
|
31
|
+
// already-downloaded JS file), a value that isn't a path reference at all — a CSS
|
|
32
|
+
// selector string embedded in a Vue bundle's scoped styles, say — would otherwise
|
|
33
|
+
// falsely look like a legitimate JS-path candidate purely because it inherited the
|
|
34
|
+
// base's own ".js"-ending pathname.
|
|
35
|
+
if (trimmed.startsWith("#") || trimmed.startsWith("?"))
|
|
36
|
+
return null;
|
|
37
|
+
let parsed;
|
|
38
|
+
try {
|
|
39
|
+
parsed = new URL(trimmed, baseUrl);
|
|
40
|
+
}
|
|
41
|
+
catch (_a) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
|
|
45
|
+
return null;
|
|
46
|
+
const segments = parsed.pathname.split("/");
|
|
47
|
+
if (!segments.some((seg) => seg.toLowerCase().endsWith(".js")))
|
|
48
|
+
return null;
|
|
49
|
+
return parsed.href;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Pure candidate extraction: walks every element attribute in the given HTML and
|
|
53
|
+
* keeps the ones that resolve to a JS-looking path (see resolveJsPathCandidate).
|
|
54
|
+
*/
|
|
55
|
+
export const findJsPathSegmentCandidates = (html, baseUrl) => {
|
|
56
|
+
const $ = cheerio.load(html);
|
|
57
|
+
const candidates = new Set();
|
|
58
|
+
$("*").each((_, elem) => {
|
|
59
|
+
const attribs = elem.attribs;
|
|
60
|
+
if (!attribs)
|
|
61
|
+
return;
|
|
62
|
+
for (const value of Object.values(attribs)) {
|
|
63
|
+
const resolved = resolveJsPathCandidate(value, baseUrl);
|
|
64
|
+
if (resolved)
|
|
65
|
+
candidates.add(resolved);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return [...candidates];
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Confirms each candidate is actually JavaScript via Content-Type (per RFC 9239 /
|
|
72
|
+
* RFC 4329 and legacy variants — see generic_jsMimeTypes.ts), not just the URL shape.
|
|
73
|
+
* Uses GET rather than HEAD: makeRequest's response cache is keyed on URL only (not
|
|
74
|
+
* method), so a cached HEAD response would poison the later GET that downloads the
|
|
75
|
+
* body — every other crawler in this codebase uses GET for the same reason.
|
|
76
|
+
*
|
|
77
|
+
* `concurrency` (default 1, matching every other generic-tech call site's default
|
|
78
|
+
* single-threaded behavior) controls how many candidates are in flight at once — a
|
|
79
|
+
* worker-pool over the candidate list, same shape as generic_downloadFiles.ts's
|
|
80
|
+
* `processOne`/`worker` pattern. Internal#75: a webpack chunk-hash-map can list far
|
|
81
|
+
* more candidates than a string-literal scan ever would (every chunk ID an entry
|
|
82
|
+
* chunk knows about, not just ones referenced by a literal path), and each failing
|
|
83
|
+
* candidate costs up to `10 retries * requestTimeout` in makeRequest — sequential
|
|
84
|
+
* confirmation of a large candidate batch, with even a handful of dead chunk IDs in
|
|
85
|
+
* it, becomes prohibitively slow. Passing a caller-supplied `threads` value here
|
|
86
|
+
* (already threaded through generic tech for downloads) keeps that path proportional.
|
|
87
|
+
*/
|
|
88
|
+
export const confirmJsContentType = (candidates_1, ...args_1) => __awaiter(void 0, [candidates_1, ...args_1], void 0, function* (candidates, concurrency = 1) {
|
|
89
|
+
const confirmed = [];
|
|
90
|
+
let cursor = 0;
|
|
91
|
+
const worker = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
var _a;
|
|
93
|
+
while (true) {
|
|
94
|
+
const idx = cursor++;
|
|
95
|
+
if (idx >= candidates.length)
|
|
96
|
+
break;
|
|
97
|
+
const url = candidates[idx];
|
|
98
|
+
let contentType = null;
|
|
99
|
+
try {
|
|
100
|
+
const res = yield makeRequest(url, { method: "GET" });
|
|
101
|
+
contentType = (_a = res === null || res === void 0 ? void 0 : res.headers.get("content-type")) !== null && _a !== void 0 ? _a : null;
|
|
102
|
+
}
|
|
103
|
+
catch (_b) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (isJsContentType(contentType)) {
|
|
107
|
+
printMsg(MSG.Run, `[✓] Confirmed JS via Content-Type: ${url}`);
|
|
108
|
+
confirmed.push(url);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
yield Promise.all(Array.from({ length: Math.max(1, concurrency) }, () => worker()));
|
|
113
|
+
return confirmed;
|
|
114
|
+
});
|
|
115
|
+
const generic_scanAttributesForJs = (html_1, baseUrl_1, ...args_1) => __awaiter(void 0, [html_1, baseUrl_1, ...args_1], void 0, function* (html, baseUrl, alreadyKnownUrls = new Set()) {
|
|
116
|
+
const candidates = findJsPathSegmentCandidates(html, baseUrl).filter((u) => !alreadyKnownUrls.has(u));
|
|
117
|
+
if (candidates.length === 0)
|
|
118
|
+
return [];
|
|
119
|
+
return confirmJsContentType(candidates);
|
|
120
|
+
});
|
|
121
|
+
export default generic_scanAttributesForJs;
|
|
122
|
+
//# sourceMappingURL=generic_scanAttributesForJs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic_scanAttributesForJs.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_scanAttributesForJs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import strings from "../../strings/index.js";
|
|
13
|
+
import { resolveJsPathCandidate, confirmJsContentType } from "./generic_scanAttributesForJs.js";
|
|
14
|
+
import { printMsg, MSG } from "../../utility/printMsg.js";
|
|
15
|
+
/**
|
|
16
|
+
* Parses the `// File Source: <url>` header every generic-downloaded file carries
|
|
17
|
+
* as its first line (written by generic_downloadFiles.ts and generic_getScriptTags.ts)
|
|
18
|
+
* to recover the URL a downloaded file actually came from. This is what lets string
|
|
19
|
+
* literals found inside that file resolve against ITS OWN url — unlike Next.js's
|
|
20
|
+
* subsequent-requests pass (next_SubsequentRequests.ts), which resolves every
|
|
21
|
+
* extracted path against a single fixed target URL for the whole crawl.
|
|
22
|
+
*/
|
|
23
|
+
export const extractFileSourceUrl = (fileContent) => {
|
|
24
|
+
const match = /^\/\/ File Source: (\S+)/.exec(fileContent);
|
|
25
|
+
return match ? match[1] : null;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Pure candidate extraction: given the strings module's raw per-file output
|
|
29
|
+
* ({ [filePath]: string[] }), resolves each string against the URL its own file
|
|
30
|
+
* came from and keeps the ones that look like a JS path. readFile is injected so
|
|
31
|
+
* this stays unit-testable without real filesystem access.
|
|
32
|
+
*/
|
|
33
|
+
export const findJsPathCandidatesFromStrings = (allStrings, readFile) => {
|
|
34
|
+
var _a;
|
|
35
|
+
const candidates = new Set();
|
|
36
|
+
for (const filePath of Object.keys(allStrings)) {
|
|
37
|
+
let content;
|
|
38
|
+
try {
|
|
39
|
+
content = readFile(filePath);
|
|
40
|
+
}
|
|
41
|
+
catch (_b) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const sourceUrl = extractFileSourceUrl(content);
|
|
45
|
+
if (!sourceUrl)
|
|
46
|
+
continue;
|
|
47
|
+
for (const str of (_a = allStrings[filePath]) !== null && _a !== void 0 ? _a : []) {
|
|
48
|
+
const resolved = resolveJsPathCandidate(str, sourceUrl);
|
|
49
|
+
if (resolved)
|
|
50
|
+
candidates.add(resolved);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return [...candidates];
|
|
54
|
+
};
|
|
55
|
+
let stringsPassCounter = 0;
|
|
56
|
+
/**
|
|
57
|
+
* Runs the existing `strings` module against the generic crawl's whole output
|
|
58
|
+
* directory (files span multiple host subdirectories — the page's own host plus
|
|
59
|
+
* any third-party asset hosts), recovers per-file source URLs, and confirms
|
|
60
|
+
* JS-looking string-literal candidates via Content-Type. Internal#66: WordPress
|
|
61
|
+
* plugin configs routinely reference further JS assets only as a string inside
|
|
62
|
+
* an already-downloaded file (inline script or external JS), invisible to
|
|
63
|
+
* attribute scanning or <script src> discovery.
|
|
64
|
+
*
|
|
65
|
+
* alreadyKnownUrls (typically the caller's running downloadedJsUrls set) is
|
|
66
|
+
* filtered out BEFORE confirmJsContentType, not after — each subsequent pass
|
|
67
|
+
* rescans the same growing directory (strings() has no incremental-scan mode),
|
|
68
|
+
* so without this every already-confirmed URL from a prior pass would otherwise
|
|
69
|
+
* trigger a redundant live GET request every single pass.
|
|
70
|
+
*/
|
|
71
|
+
const generic_stringsDiscovery = (outputDir_1, ...args_1) => __awaiter(void 0, [outputDir_1, ...args_1], void 0, function* (outputDir, alreadyKnownUrls = new Set()) {
|
|
72
|
+
if (!fs.existsSync(outputDir))
|
|
73
|
+
return [];
|
|
74
|
+
const tmpStringsFile = path.join(outputDir, `.generic-strings-pass-${stringsPassCounter++}.json`);
|
|
75
|
+
try {
|
|
76
|
+
yield strings(outputDir, tmpStringsFile, false, "", false, false, false);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
printMsg(MSG.Warn, `[!] Generic strings discovery pass failed: ${err}`);
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
let allStrings;
|
|
83
|
+
try {
|
|
84
|
+
allStrings = JSON.parse(fs.readFileSync(tmpStringsFile, "utf-8"));
|
|
85
|
+
}
|
|
86
|
+
catch (_a) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
try {
|
|
91
|
+
fs.unlinkSync(tmpStringsFile);
|
|
92
|
+
}
|
|
93
|
+
catch (_b) {
|
|
94
|
+
/* best-effort cleanup — a leftover temp file isn't fatal */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const candidates = findJsPathCandidatesFromStrings(allStrings, (p) => fs.readFileSync(p, "utf-8")).filter((u) => !alreadyKnownUrls.has(u));
|
|
98
|
+
if (candidates.length === 0)
|
|
99
|
+
return [];
|
|
100
|
+
return confirmJsContentType(candidates);
|
|
101
|
+
});
|
|
102
|
+
export default generic_stringsDiscovery;
|
|
103
|
+
//# sourceMappingURL=generic_stringsDiscovery.js.map
|