@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
|
@@ -1,307 +1,38 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"--oxylabs-waf-fallback",
|
|
35
|
-
"--oxylabs-fallback-max-requests",
|
|
36
|
-
"--oxylabs-fallback-max-total",
|
|
37
|
-
"--oxylabs-fallback-max-origins",
|
|
38
|
-
"--cache-file",
|
|
39
|
-
"--disable-cache",
|
|
40
|
-
"--cache-only",
|
|
41
|
-
"-y",
|
|
42
|
-
"--yes",
|
|
43
|
-
"--timeout",
|
|
44
|
-
"-k",
|
|
45
|
-
"--insecure",
|
|
46
|
-
"--no-sandbox",
|
|
47
|
-
"--build-id",
|
|
48
|
-
"--sourcemap-dir",
|
|
49
|
-
"--research",
|
|
50
|
-
"--research-output",
|
|
51
|
-
"--max-iterations",
|
|
52
|
-
"--max-js-size",
|
|
53
|
-
"--lazyload-timeout",
|
|
54
|
-
"--detection-timeout",
|
|
55
|
-
"--max-pages",
|
|
56
|
-
"--include-methods",
|
|
57
|
-
"--exclude-methods",
|
|
58
|
-
"--list-methods",
|
|
59
|
-
],
|
|
60
|
-
endpoints: [
|
|
61
|
-
"-u",
|
|
62
|
-
"--url",
|
|
63
|
-
"-d",
|
|
64
|
-
"--directory",
|
|
65
|
-
"-o",
|
|
66
|
-
"--output",
|
|
67
|
-
"--output-format",
|
|
68
|
-
"-t",
|
|
69
|
-
"--tech",
|
|
70
|
-
"-l",
|
|
71
|
-
"--list",
|
|
72
|
-
"--mapped-json",
|
|
73
|
-
],
|
|
74
|
-
strings: [
|
|
75
|
-
"-d",
|
|
76
|
-
"--directory",
|
|
77
|
-
"-o",
|
|
78
|
-
"--output",
|
|
79
|
-
"-e",
|
|
80
|
-
"--extract-urls",
|
|
81
|
-
"--extracted-url-path",
|
|
82
|
-
"-p",
|
|
83
|
-
"--permutate",
|
|
84
|
-
"--openapi",
|
|
85
|
-
"-s",
|
|
86
|
-
"--scan-secrets",
|
|
87
|
-
"--trufflehog",
|
|
88
|
-
],
|
|
89
|
-
proxy: [
|
|
90
|
-
"-i",
|
|
91
|
-
"--init",
|
|
92
|
-
"-d",
|
|
93
|
-
"--destroy",
|
|
94
|
-
"--destroy-all",
|
|
95
|
-
"-r",
|
|
96
|
-
"--region",
|
|
97
|
-
"--aws-access-key",
|
|
98
|
-
"--aws-secret-key",
|
|
99
|
-
"-c",
|
|
100
|
-
"--config",
|
|
101
|
-
"-l",
|
|
102
|
-
"--list",
|
|
103
|
-
"--feasibility",
|
|
104
|
-
"--feasibility-url",
|
|
105
|
-
"--proxy-method",
|
|
106
|
-
"--proxy",
|
|
107
|
-
"--oxylabs-username",
|
|
108
|
-
"--oxylabs-password",
|
|
109
|
-
"--oxylabs-country",
|
|
110
|
-
"--oxylabs-city",
|
|
111
|
-
"--oxylabs-session-id",
|
|
112
|
-
],
|
|
113
|
-
map: [
|
|
114
|
-
"-d",
|
|
115
|
-
"--directory",
|
|
116
|
-
"-t",
|
|
117
|
-
"--tech",
|
|
118
|
-
"-l",
|
|
119
|
-
"--list",
|
|
120
|
-
"-o",
|
|
121
|
-
"--output",
|
|
122
|
-
"-f",
|
|
123
|
-
"--format",
|
|
124
|
-
"-i",
|
|
125
|
-
"--interactive",
|
|
126
|
-
"-c",
|
|
127
|
-
"--command",
|
|
128
|
-
"--ai",
|
|
129
|
-
"--ai-threads",
|
|
130
|
-
"--ai-provider",
|
|
131
|
-
"--ai-endpoint",
|
|
132
|
-
"--openai-api-key",
|
|
133
|
-
"--model",
|
|
134
|
-
"--openapi",
|
|
135
|
-
"--openapi-output",
|
|
136
|
-
"--openapi-chunk-tag",
|
|
137
|
-
"--no-graphql",
|
|
138
|
-
"--ngql",
|
|
139
|
-
"--max-recursion-depth",
|
|
140
|
-
"--max-heap",
|
|
141
|
-
],
|
|
142
|
-
refactor: [
|
|
143
|
-
"-m",
|
|
144
|
-
"--mapped-json",
|
|
145
|
-
"-o",
|
|
146
|
-
"--output",
|
|
147
|
-
"-t",
|
|
148
|
-
"--tech",
|
|
149
|
-
"-l",
|
|
150
|
-
"--list",
|
|
151
|
-
"--collisions",
|
|
152
|
-
"--sq",
|
|
153
|
-
"--signature-quality",
|
|
154
|
-
"--refresh-cache",
|
|
155
|
-
"--skip-cache-checks",
|
|
156
|
-
"--no-remote",
|
|
157
|
-
"--remote-collisions",
|
|
158
|
-
"--scat",
|
|
159
|
-
"--detect-version",
|
|
160
|
-
"--detect-version-config",
|
|
161
|
-
"--detect-version-dynamic-threshold",
|
|
162
|
-
"--detect-version-dynamic-conf-purge",
|
|
163
|
-
],
|
|
164
|
-
analyze: [
|
|
165
|
-
"-r",
|
|
166
|
-
"--rules",
|
|
167
|
-
"--disable-rules-version-check",
|
|
168
|
-
"-m",
|
|
169
|
-
"--mapped-json",
|
|
170
|
-
"-t",
|
|
171
|
-
"--tech",
|
|
172
|
-
"--openapi",
|
|
173
|
-
"-l",
|
|
174
|
-
"--list",
|
|
175
|
-
"--validate",
|
|
176
|
-
"-o",
|
|
177
|
-
"--output",
|
|
178
|
-
],
|
|
179
|
-
report: [
|
|
180
|
-
"-s",
|
|
181
|
-
"--sqlite-db",
|
|
182
|
-
"-m",
|
|
183
|
-
"--mapped-json",
|
|
184
|
-
"-a",
|
|
185
|
-
"--analyze-json",
|
|
186
|
-
"-e",
|
|
187
|
-
"--endpoints-json",
|
|
188
|
-
"--map-openapi",
|
|
189
|
-
"--mapped-openapi-json",
|
|
190
|
-
"-o",
|
|
191
|
-
"--output",
|
|
192
|
-
],
|
|
193
|
-
run: [
|
|
194
|
-
"-u",
|
|
195
|
-
"--url",
|
|
196
|
-
"-r",
|
|
197
|
-
"--rules",
|
|
198
|
-
"--disable-rules-version-check",
|
|
199
|
-
"-c",
|
|
200
|
-
"--command",
|
|
201
|
-
"-o",
|
|
202
|
-
"--output",
|
|
203
|
-
"--output-overwrite",
|
|
204
|
-
"--strict-scope",
|
|
205
|
-
"-s",
|
|
206
|
-
"--scope",
|
|
207
|
-
"-t",
|
|
208
|
-
"--threads",
|
|
209
|
-
"--proxy-config",
|
|
210
|
-
"--ignore-proxy-env",
|
|
211
|
-
"--proxy-waf-fallback",
|
|
212
|
-
"--oxylabs-waf-fallback",
|
|
213
|
-
"--oxylabs-fallback-max-requests",
|
|
214
|
-
"--oxylabs-fallback-max-total",
|
|
215
|
-
"--oxylabs-fallback-max-origins",
|
|
216
|
-
"--cache-file",
|
|
217
|
-
"--disable-cache",
|
|
218
|
-
"--cache-only",
|
|
219
|
-
"-y",
|
|
220
|
-
"--yes",
|
|
221
|
-
"--secrets",
|
|
222
|
-
"--trufflehog",
|
|
223
|
-
"--ai",
|
|
224
|
-
"--ai-threads",
|
|
225
|
-
"--ai-provider",
|
|
226
|
-
"--ai-endpoint",
|
|
227
|
-
"--openai-api-key",
|
|
228
|
-
"--model",
|
|
229
|
-
"--map-openapi-chunk-tag",
|
|
230
|
-
"--no-graphql",
|
|
231
|
-
"--ngql",
|
|
232
|
-
"--timeout",
|
|
233
|
-
"-k",
|
|
234
|
-
"--insecure",
|
|
235
|
-
"--no-sandbox",
|
|
236
|
-
"--sourcemap-dir",
|
|
237
|
-
"--research",
|
|
238
|
-
"--research-output",
|
|
239
|
-
"--max-iterations",
|
|
240
|
-
"--max-js-size",
|
|
241
|
-
"--lazyload-timeout",
|
|
242
|
-
"--detection-timeout",
|
|
243
|
-
"--max-heap",
|
|
244
|
-
"--max-pages",
|
|
245
|
-
"--include-methods",
|
|
246
|
-
"--exclude-methods",
|
|
247
|
-
"--list-methods",
|
|
248
|
-
"--cs-mast-tech-detect-threshold",
|
|
249
|
-
"--disable-refactor",
|
|
250
|
-
],
|
|
251
|
-
load: ["-c", "--caido", "-u", "--url", "--cache-file"],
|
|
252
|
-
fingerprint: [
|
|
253
|
-
"-u",
|
|
254
|
-
"--url",
|
|
255
|
-
"-o",
|
|
256
|
-
"--output",
|
|
257
|
-
"-f",
|
|
258
|
-
"--format",
|
|
259
|
-
"-t",
|
|
260
|
-
"--threads",
|
|
261
|
-
"--timeout",
|
|
262
|
-
"-k",
|
|
263
|
-
"--insecure",
|
|
264
|
-
"--no-sandbox",
|
|
265
|
-
],
|
|
266
|
-
mcp: [
|
|
267
|
-
"--cli",
|
|
268
|
-
"--server",
|
|
269
|
-
"-c",
|
|
270
|
-
"--chat",
|
|
271
|
-
"--config",
|
|
272
|
-
"--api-key",
|
|
273
|
-
"--model",
|
|
274
|
-
"--provider",
|
|
275
|
-
"--no-refresh-claude-creds",
|
|
276
|
-
"--claude-client-id",
|
|
277
|
-
],
|
|
278
|
-
"cs-mast": [
|
|
279
|
-
"-o",
|
|
280
|
-
"--output",
|
|
281
|
-
"--ct",
|
|
282
|
-
"--collision-table",
|
|
283
|
-
"--min-collisions",
|
|
284
|
-
"--co",
|
|
285
|
-
"--collision-output",
|
|
286
|
-
"--cf",
|
|
287
|
-
"--collision-format",
|
|
288
|
-
"--scat",
|
|
289
|
-
"--sinc",
|
|
290
|
-
"--all-scat-permutations",
|
|
291
|
-
"--perm-output",
|
|
292
|
-
"--perm-concurrency",
|
|
293
|
-
],
|
|
294
|
-
sourcemaps: ["-i", "--input", "-o", "--output"],
|
|
295
|
-
completion: ["bash", "zsh", "fish"],
|
|
296
|
-
};
|
|
297
|
-
function generateBashCompletion() {
|
|
298
|
-
const cmdList = COMMANDS.join(" ");
|
|
299
|
-
const cmdPattern = COMMANDS.join("|");
|
|
300
|
-
const caseBranches = Object.entries(FLAGS)
|
|
301
|
-
.map(([cmd, flags]) => ` ${cmd})\n opts="${flags.join(" ")}"\n ;;`)
|
|
302
|
-
.join("\n");
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { printMsg, MSG } from "../utility/printMsg.js";
|
|
5
|
+
import { buildProgram } from "../cliProgram.js";
|
|
6
|
+
import { buildCommandTree } from "./introspect.js";
|
|
7
|
+
function bashLeafOpts(node) {
|
|
8
|
+
return [...node.options.flatMap((o) => o.flags), ...node.argumentChoices].join(" ");
|
|
9
|
+
}
|
|
10
|
+
// Recursively emits nested `case` blocks so multi-level subcommands (e.g. `proxy aws`) get their
|
|
11
|
+
// own flags completed, not just the parent's child-name list. `wordIndex` is the COMP_WORDS index
|
|
12
|
+
// this node's name occupies (1 for top-level commands, 2 for their children, and so on).
|
|
13
|
+
function generateBashCaseBranch(node, wordIndex) {
|
|
14
|
+
const indent = " ".repeat(wordIndex + 1);
|
|
15
|
+
if (node.subcommands.length === 0) {
|
|
16
|
+
return `${indent}${node.name})
|
|
17
|
+
${indent} opts="${bashLeafOpts(node)}"
|
|
18
|
+
${indent} ;;`;
|
|
19
|
+
}
|
|
20
|
+
const childBranches = node.subcommands.map((child) => generateBashCaseBranch(child, wordIndex + 1)).join("\n");
|
|
21
|
+
const childNames = node.subcommands.map((c) => c.name).join(" ");
|
|
22
|
+
return `${indent}${node.name})
|
|
23
|
+
${indent} case "\${words[${wordIndex + 1}]:-}" in
|
|
24
|
+
${childBranches}
|
|
25
|
+
${indent} *)
|
|
26
|
+
${indent} opts="${childNames}"
|
|
27
|
+
${indent} ;;
|
|
28
|
+
${indent} esac
|
|
29
|
+
${indent} ;;`;
|
|
30
|
+
}
|
|
31
|
+
function generateBashCompletion(tree) {
|
|
32
|
+
const cmdList = tree.map((n) => n.name).join(" ");
|
|
33
|
+
const caseBranches = tree.map((node) => generateBashCaseBranch(node, 1)).join("\n");
|
|
303
34
|
return `# js-recon bash completion
|
|
304
|
-
#
|
|
35
|
+
# Installed automatically by: js-recon completion bash
|
|
305
36
|
_js_recon_completion() {
|
|
306
37
|
local cur prev words cword opts
|
|
307
38
|
COMPREPLY=()
|
|
@@ -310,25 +41,13 @@ _js_recon_completion() {
|
|
|
310
41
|
words=("\${COMP_WORDS[@]}")
|
|
311
42
|
cword=\${COMP_CWORD}
|
|
312
43
|
|
|
313
|
-
if [[ \${
|
|
314
|
-
COMPREPLY=( \$(compgen -
|
|
315
|
-
return 0
|
|
316
|
-
fi
|
|
317
|
-
|
|
318
|
-
local cmd=""
|
|
319
|
-
local word
|
|
320
|
-
for word in "\${words[@]}"; do
|
|
321
|
-
case "\${word}" in
|
|
322
|
-
${cmdPattern}) cmd="\${word}"; break ;;
|
|
323
|
-
esac
|
|
324
|
-
done
|
|
325
|
-
if [[ -z \${cmd} ]]; then
|
|
326
|
-
COMPREPLY=( \$(compgen -W "--config ${cmdList}" -- "\${cur}") )
|
|
44
|
+
if [[ \${cword} -eq 1 ]]; then
|
|
45
|
+
COMPREPLY=( \$(compgen -W "${cmdList}" -- "\${cur}") )
|
|
327
46
|
return 0
|
|
328
47
|
fi
|
|
329
48
|
|
|
330
49
|
opts=""
|
|
331
|
-
case "\${
|
|
50
|
+
case "\${words[1]}" in
|
|
332
51
|
${caseBranches}
|
|
333
52
|
esac
|
|
334
53
|
|
|
@@ -338,34 +57,88 @@ ${caseBranches}
|
|
|
338
57
|
complete -F _js_recon_completion js-recon
|
|
339
58
|
`;
|
|
340
59
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
60
|
+
// zsh escaping: backslash first, then compsys metacharacters, then the shell-level single-quote
|
|
61
|
+
// trick last (since every spec string here is wrapped in '...').
|
|
62
|
+
function zshBracketDesc(desc) {
|
|
63
|
+
return desc.replace(/\\/g, "\\\\").replace(/\]/g, "\\]").replace(/\[/g, "\\[").replace(/'/g, "'\\''");
|
|
64
|
+
}
|
|
65
|
+
// Used inside `_describe` `name:description` arrays, where `:` is the field delimiter.
|
|
66
|
+
function zshDescribeDesc(desc) {
|
|
67
|
+
return desc.replace(/\\/g, "\\\\").replace(/:/g, "\\:").replace(/'/g, "'\\''");
|
|
68
|
+
}
|
|
69
|
+
function zshOptionSpec(option) {
|
|
70
|
+
const desc = zshBracketDesc(option.description);
|
|
71
|
+
const short = option.flags.find((f) => f.length === 2 && f.startsWith("-") && !f.startsWith("--"));
|
|
72
|
+
const long = option.flags.find((f) => f.startsWith("--"));
|
|
73
|
+
if (short && long)
|
|
74
|
+
return `'(${short} ${long})'{${short},${long}}'[${desc}]'`;
|
|
75
|
+
if (long)
|
|
76
|
+
return `'${long}[${desc}]'`;
|
|
77
|
+
if (short)
|
|
78
|
+
return `'${short}[${desc}]'`;
|
|
79
|
+
return "";
|
|
80
|
+
}
|
|
81
|
+
function zshDescribeEntry(node) {
|
|
82
|
+
return `'${node.name}:${zshDescribeDesc(node.description)}'`;
|
|
83
|
+
}
|
|
84
|
+
function zshLeafArguments(node) {
|
|
85
|
+
const parts = [];
|
|
86
|
+
if (node.argumentChoices.length > 0) {
|
|
87
|
+
parts.push(`'1: :(${node.argumentChoices.join(" ")})'`);
|
|
88
|
+
}
|
|
89
|
+
parts.push(...node.options.map(zshOptionSpec).filter(Boolean));
|
|
90
|
+
if (parts.length === 0)
|
|
91
|
+
return ":";
|
|
92
|
+
return `_arguments ${parts.join(" ")}`;
|
|
93
|
+
}
|
|
94
|
+
// Recursively emits a nested `_arguments -C` + `case $state` block for a level of subcommands.
|
|
95
|
+
// Reusing the generic `cmd`/`args` state labels at every nesting level is safe here because each
|
|
96
|
+
// `_arguments -C` call is evaluated strictly before the `case $state` that reads its result — by
|
|
97
|
+
// the time a nested level's `$state` is inspected, the outer level's value is no longer needed.
|
|
98
|
+
function zshSubcommandBlock(nodes, describeTag) {
|
|
99
|
+
const entries = nodes.map(zshDescribeEntry).join("\n ");
|
|
100
|
+
const branches = nodes
|
|
101
|
+
.map((node) => {
|
|
102
|
+
const body = node.subcommands.length > 0 ? zshSubcommandBlock(node.subcommands, node.name) : zshLeafArguments(node);
|
|
103
|
+
return ` (${node.name})
|
|
104
|
+
${body}
|
|
105
|
+
;;`;
|
|
106
|
+
})
|
|
107
|
+
.join("\n");
|
|
108
|
+
return `_arguments -C \\
|
|
109
|
+
'1: :->cmd' \\
|
|
110
|
+
'*::arg:->args'
|
|
111
|
+
|
|
112
|
+
case \$state in
|
|
113
|
+
cmd)
|
|
114
|
+
local -a items
|
|
115
|
+
items=(
|
|
116
|
+
${entries}
|
|
117
|
+
)
|
|
118
|
+
_describe -t items '${describeTag}' items
|
|
119
|
+
;;
|
|
120
|
+
args)
|
|
121
|
+
case \$line[1] in
|
|
122
|
+
${branches}
|
|
123
|
+
esac
|
|
124
|
+
;;
|
|
125
|
+
esac`;
|
|
126
|
+
}
|
|
127
|
+
function generateZshCompletion(tree) {
|
|
128
|
+
const commandDescriptions = tree.map(zshDescribeEntry).join("\n ");
|
|
129
|
+
const caseBranches = tree
|
|
130
|
+
.map((node) => {
|
|
131
|
+
const body = node.subcommands.length > 0
|
|
132
|
+
? zshSubcommandBlock(node.subcommands, `${node.name} subcommand`)
|
|
133
|
+
: zshLeafArguments(node);
|
|
134
|
+
return ` (${node.name})
|
|
135
|
+
${body}
|
|
136
|
+
;;`;
|
|
363
137
|
})
|
|
364
138
|
.join("\n");
|
|
365
139
|
return `#compdef js-recon
|
|
366
140
|
# js-recon zsh completion
|
|
367
|
-
#
|
|
368
|
-
# Or: js-recon completion zsh > "\${fpath[1]}/_js-recon"
|
|
141
|
+
# Installed automatically by: js-recon completion zsh
|
|
369
142
|
|
|
370
143
|
_js_recon() {
|
|
371
144
|
local state line
|
|
@@ -374,7 +147,6 @@ _js_recon() {
|
|
|
374
147
|
_arguments -C \\
|
|
375
148
|
'(-h --help)'{-h,--help}'[Show help]' \\
|
|
376
149
|
'(-V --version)'{-V,--version}'[Show version]' \\
|
|
377
|
-
'--config[Application YAML config]:file:_files' \\
|
|
378
150
|
'1: :->command' \\
|
|
379
151
|
'*: :->args'
|
|
380
152
|
|
|
@@ -397,40 +169,55 @@ ${caseBranches}
|
|
|
397
169
|
_js_recon "\$@"
|
|
398
170
|
`;
|
|
399
171
|
}
|
|
400
|
-
function
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
172
|
+
function fishDesc(desc) {
|
|
173
|
+
return desc.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
174
|
+
}
|
|
175
|
+
function fishConditionForPath(namePath) {
|
|
176
|
+
return namePath.map((name) => `__fish_seen_subcommand_from ${name}`).join("; and ");
|
|
177
|
+
}
|
|
178
|
+
// Recursively emits `complete` lines for a node's own flags/argument choices (gated on the full
|
|
179
|
+
// name path having been seen so far) and, for each child, both a name-completion at this level
|
|
180
|
+
// and a recursive call so the child's own flags are completed too (e.g. `proxy aws --<tab>`).
|
|
181
|
+
function generateFishNode(node, parentPath) {
|
|
182
|
+
const namePath = [...parentPath, node.name];
|
|
183
|
+
const cond = fishConditionForPath(namePath);
|
|
184
|
+
const lines = [];
|
|
185
|
+
for (const option of node.options) {
|
|
186
|
+
const short = option.flags.find((f) => f.length === 2 && f.startsWith("-") && !f.startsWith("--"));
|
|
187
|
+
const long = option.flags.find((f) => f.startsWith("--"));
|
|
188
|
+
const desc = fishDesc(option.description);
|
|
189
|
+
if (short && long) {
|
|
190
|
+
lines.push(`complete -c js-recon -n '${cond}' -s ${short.slice(1)} -l ${long.slice(2)} -d '${desc}'`);
|
|
191
|
+
}
|
|
192
|
+
else if (long) {
|
|
193
|
+
lines.push(`complete -c js-recon -n '${cond}' -l ${long.slice(2)} -d '${desc}'`);
|
|
406
194
|
}
|
|
407
|
-
else if (
|
|
408
|
-
|
|
195
|
+
else if (short) {
|
|
196
|
+
lines.push(`complete -c js-recon -n '${cond}' -s ${short.slice(1)} -d '${desc}'`);
|
|
409
197
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
198
|
+
}
|
|
199
|
+
if (node.argumentChoices.length > 0) {
|
|
200
|
+
lines.push(`complete -c js-recon -n '${cond}' -a '${node.argumentChoices.join(" ")}'`);
|
|
201
|
+
}
|
|
202
|
+
for (const child of node.subcommands) {
|
|
203
|
+
lines.push(`complete -c js-recon -f -n '${cond}' -a ${child.name} -d '${fishDesc(child.description)}'`);
|
|
204
|
+
lines.push(...generateFishNode(child, namePath));
|
|
205
|
+
}
|
|
206
|
+
return lines;
|
|
207
|
+
}
|
|
208
|
+
function generateFishCompletion(tree) {
|
|
209
|
+
const cmdCompletions = tree
|
|
210
|
+
.map((node) => `complete -c js-recon -f -n '__fish_use_subcommand' -a ${node.name} -d '${fishDesc(node.description)}'`)
|
|
413
211
|
.join("\n");
|
|
212
|
+
const flagCompletions = tree.flatMap((node) => generateFishNode(node, [])).join("\n");
|
|
414
213
|
return `# js-recon fish completion
|
|
415
|
-
#
|
|
416
|
-
#
|
|
214
|
+
# Installed automatically by: js-recon completion fish
|
|
215
|
+
# (written to ~/.config/fish/completions/js-recon.fish, which fish auto-loads)
|
|
417
216
|
|
|
418
217
|
function __fish_use_subcommand
|
|
419
218
|
set -l cmd (commandline -poc)
|
|
420
219
|
set -e cmd[1]
|
|
421
|
-
set -l skip_next 0
|
|
422
220
|
for c in $cmd
|
|
423
|
-
if test $skip_next -eq 1
|
|
424
|
-
set skip_next 0
|
|
425
|
-
continue
|
|
426
|
-
end
|
|
427
|
-
if test "$c" = "--config"
|
|
428
|
-
set skip_next 1
|
|
429
|
-
continue
|
|
430
|
-
end
|
|
431
|
-
if string match -q -- '--config=*' "$c"
|
|
432
|
-
continue
|
|
433
|
-
end
|
|
434
221
|
if string match -qr '^[^-]' -- $c
|
|
435
222
|
return 1
|
|
436
223
|
end
|
|
@@ -451,29 +238,107 @@ end
|
|
|
451
238
|
|
|
452
239
|
${cmdCompletions}
|
|
453
240
|
|
|
454
|
-
complete -c js-recon -l config -r -F
|
|
455
|
-
|
|
456
241
|
${flagCompletions}
|
|
457
242
|
`;
|
|
458
243
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
244
|
+
const RC_MARKER = "# JS Recon shell completion";
|
|
245
|
+
function getCompletionDir() {
|
|
246
|
+
return path.join(os.homedir(), ".js-recon", "completion");
|
|
247
|
+
}
|
|
248
|
+
function getFishCompletionsDir() {
|
|
249
|
+
return path.join(os.homedir(), ".config", "fish", "completions");
|
|
250
|
+
}
|
|
251
|
+
// Path each shell's full generated script gets written to. Fish uses its own
|
|
252
|
+
// auto-loaded completions dir instead of ~/.js-recon, so it needs no rc-file entry.
|
|
253
|
+
function getInstalledScriptPath(shell) {
|
|
254
|
+
switch (shell) {
|
|
255
|
+
case "bash":
|
|
256
|
+
return path.join(getCompletionDir(), "js-recon.bash");
|
|
257
|
+
case "zsh":
|
|
258
|
+
return path.join(getCompletionDir(), "_js-recon");
|
|
259
|
+
case "fish":
|
|
260
|
+
return path.join(getFishCompletionsDir(), "js-recon.fish");
|
|
261
|
+
default:
|
|
262
|
+
throw new Error(`Unknown shell: ${shell}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function getRcFilePath(shell) {
|
|
266
|
+
return path.join(os.homedir(), shell === "bash" ? ".bashrc" : ".zshrc");
|
|
267
|
+
}
|
|
268
|
+
// Small snippet printed for `--rc-file` — this is what actually goes in the user's rc file
|
|
269
|
+
// (via `eval "$(js-recon completion <shell> --rc-file)"`), pointing at the full script on disk.
|
|
270
|
+
function generateRcFileLoader(shell) {
|
|
271
|
+
const importantHeader = `# IMPORTANT: the contents of this command are expected to be present in
|
|
272
|
+
# the shell's rc file, invoked as \`eval "$(js-recon completion ${shell} --rc-file)"\`.
|
|
273
|
+
# Run \`js-recon completion ${shell}\` to (re)install.`;
|
|
274
|
+
if (shell === "bash") {
|
|
275
|
+
return `${importantHeader}
|
|
276
|
+
if [ -f "$HOME/.js-recon/completion/js-recon.bash" ]; then
|
|
277
|
+
source "$HOME/.js-recon/completion/js-recon.bash"
|
|
278
|
+
fi
|
|
279
|
+
`;
|
|
463
280
|
}
|
|
464
|
-
|
|
281
|
+
return `${importantHeader}
|
|
282
|
+
fpath=("$HOME/.js-recon/completion" $fpath)
|
|
283
|
+
autoload -Uz compinit
|
|
284
|
+
compinit
|
|
285
|
+
`;
|
|
286
|
+
}
|
|
287
|
+
function generateCompletionScript(shell) {
|
|
288
|
+
const tree = buildCommandTree(buildProgram());
|
|
289
|
+
switch (shell) {
|
|
465
290
|
case "bash":
|
|
466
|
-
|
|
467
|
-
break;
|
|
291
|
+
return generateBashCompletion(tree);
|
|
468
292
|
case "zsh":
|
|
469
|
-
|
|
470
|
-
break;
|
|
293
|
+
return generateZshCompletion(tree);
|
|
471
294
|
case "fish":
|
|
472
|
-
|
|
473
|
-
break;
|
|
295
|
+
return generateFishCompletion(tree);
|
|
474
296
|
default:
|
|
475
|
-
|
|
297
|
+
throw new Error(`Unknown shell: ${shell}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Writes the full script to disk and, for bash/zsh, wires a tiny loader entry into the
|
|
301
|
+
// user's rc file (idempotent — checks RC_MARKER before appending).
|
|
302
|
+
function installCompletion(shell) {
|
|
303
|
+
const scriptPath = getInstalledScriptPath(shell);
|
|
304
|
+
fs.mkdirSync(path.dirname(scriptPath), { recursive: true });
|
|
305
|
+
fs.writeFileSync(scriptPath, generateCompletionScript(shell));
|
|
306
|
+
if (shell === "fish") {
|
|
307
|
+
printMsg(MSG.Run, `[+] Installed fish completion to ${scriptPath}`);
|
|
308
|
+
printMsg(MSG.Run, "[+] Fish auto-loads this — no further action needed.");
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const rcPath = getRcFilePath(shell);
|
|
312
|
+
const rcContent = fs.existsSync(rcPath) ? fs.readFileSync(rcPath, "utf8") : "";
|
|
313
|
+
if (rcContent.includes(RC_MARKER)) {
|
|
314
|
+
printMsg(MSG.Run, `[+] Installed ${shell} completion to ${scriptPath}`);
|
|
315
|
+
printMsg(MSG.Run, `[+] ${rcPath} already wired for js-recon completion.`);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const entry = `\n${RC_MARKER}\neval "$(js-recon completion ${shell} --rc-file)"\n`;
|
|
319
|
+
fs.appendFileSync(rcPath, entry);
|
|
320
|
+
printMsg(MSG.Run, `[+] Installed ${shell} completion to ${scriptPath}`);
|
|
321
|
+
printMsg(MSG.Run, `[+] Added completion loader to ${rcPath}`);
|
|
322
|
+
printMsg(MSG.Run, `[+] Restart your shell or run: source ${rcPath}`);
|
|
323
|
+
}
|
|
324
|
+
export default function completion(shell, rcFile) {
|
|
325
|
+
if (!shell) {
|
|
326
|
+
printMsg(MSG.Err, "[!] Shell type required. Usage: js-recon completion <bash|zsh|fish>");
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
const normalizedShell = shell.toLowerCase();
|
|
330
|
+
if (normalizedShell !== "bash" && normalizedShell !== "zsh" && normalizedShell !== "fish") {
|
|
331
|
+
printMsg(MSG.Err, `[!] Unknown shell: "${shell}". Supported shells: bash, zsh, fish`);
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
if (rcFile) {
|
|
335
|
+
if (normalizedShell === "fish") {
|
|
336
|
+
printMsg(MSG.Err, '[!] --rc-file is not applicable to fish; fish auto-loads completions from "~/.config/fish/completions/".');
|
|
476
337
|
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
process.stdout.write(generateRcFileLoader(normalizedShell));
|
|
340
|
+
return;
|
|
477
341
|
}
|
|
342
|
+
installCompletion(normalizedShell);
|
|
478
343
|
}
|
|
479
344
|
//# sourceMappingURL=index.js.map
|