@shriyanss/js-recon 1.3.1-alpha.2 → 1.3.1-alpha.4

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.
Files changed (162) hide show
  1. package/.github/workflows/build-and-prettify.yaml +15 -1
  2. package/.github/workflows/pr_checker.yml +9 -8
  3. package/.github/workflows/publish-js-recon.yml +13 -1
  4. package/CHANGELOG.md +96 -0
  5. package/CLAUDE.md +225 -0
  6. package/README.md +2 -0
  7. package/build/analyze/engine/astEngine.js +57 -29
  8. package/build/analyze/engine/astEngine.js.map +1 -1
  9. package/build/analyze/engine/index.js +2 -2
  10. package/build/analyze/engine/index.js.map +1 -1
  11. package/build/analyze/helpers/engineHelpers/taintFlow.js +32 -0
  12. package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -1
  13. package/build/analyze/helpers/initRules.js +9 -0
  14. package/build/analyze/helpers/initRules.js.map +1 -1
  15. package/build/analyze/helpers/schemas.js +6 -1
  16. package/build/analyze/helpers/schemas.js.map +1 -1
  17. package/build/analyze/helpers/validate.js +49 -9
  18. package/build/analyze/helpers/validate.js.map +1 -1
  19. package/build/analyze/index.js +10 -4
  20. package/build/analyze/index.js.map +1 -1
  21. package/build/endpoints/next_js/client_mappedJsonFile.js +12 -5
  22. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
  23. package/build/fingerprint/index.js +123 -0
  24. package/build/fingerprint/index.js.map +1 -0
  25. package/build/globalConfig.js +1 -1
  26. package/build/index.js +72 -5
  27. package/build/index.js.map +1 -1
  28. package/build/lazyLoad/downloadFilesUtil.js +3 -3
  29. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  30. package/build/lazyLoad/downloadQueue.js +16 -11
  31. package/build/lazyLoad/downloadQueue.js.map +1 -1
  32. package/build/lazyLoad/index.js +260 -163
  33. package/build/lazyLoad/index.js.map +1 -1
  34. package/build/lazyLoad/next_js/NextJsCrawler.js +58 -16
  35. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  36. package/build/lazyLoad/next_js/next_GetJSScript.js +8 -4
  37. package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -1
  38. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +149 -139
  39. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  40. package/build/lazyLoad/next_js/next_SubsequentRequests.js +25 -4
  41. package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -1
  42. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +13 -5
  43. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -1
  44. package/build/lazyLoad/react/react_followImports.js +105 -0
  45. package/build/lazyLoad/react/react_followImports.js.map +1 -0
  46. package/build/lazyLoad/react/react_getScriptTags.js +28 -5
  47. package/build/lazyLoad/react/react_getScriptTags.js.map +1 -1
  48. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +162 -0
  49. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -0
  50. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +15 -0
  51. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  52. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +180 -0
  53. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -0
  54. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +15 -1
  55. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  56. package/build/lazyLoad/techDetect/checkReact.js +67 -36
  57. package/build/lazyLoad/techDetect/checkReact.js.map +1 -1
  58. package/build/lazyLoad/techDetect/checkSvelte.js +35 -35
  59. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
  60. package/build/lazyLoad/techDetect/index.js +31 -25
  61. package/build/lazyLoad/techDetect/index.js.map +1 -1
  62. package/build/lazyLoad/vue/vue_getClientSidePaths.js +6 -0
  63. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
  64. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +6 -0
  65. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  66. package/build/lazyLoad/vue/vue_stringJsFiles.js +6 -0
  67. package/build/lazyLoad/vue/vue_stringJsFiles.js.map +1 -1
  68. package/build/load/index.js +316 -0
  69. package/build/load/index.js.map +1 -0
  70. package/build/map/graphql/resolveGraphql.js +296 -0
  71. package/build/map/graphql/resolveGraphql.js.map +1 -0
  72. package/build/map/index.js +104 -6
  73. package/build/map/index.js.map +1 -1
  74. package/build/map/next_js/interactive.js +30 -0
  75. package/build/map/next_js/interactive.js.map +1 -1
  76. package/build/map/next_js/interactive_helpers/commandHandler.js +26 -0
  77. package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -1
  78. package/build/map/next_js/interactive_helpers/commandHelpers.js +28 -0
  79. package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
  80. package/build/map/next_js/interactive_helpers/esqueryGen.js +370 -0
  81. package/build/map/next_js/interactive_helpers/esqueryGen.js.map +1 -0
  82. package/build/map/next_js/interactive_helpers/helpMenu.js +2 -1
  83. package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -1
  84. package/build/map/next_js/interactive_helpers/inputPatch.js +207 -0
  85. package/build/map/next_js/interactive_helpers/inputPatch.js.map +1 -0
  86. package/build/map/next_js/interactive_helpers/ui.js +0 -1
  87. package/build/map/next_js/interactive_helpers/ui.js.map +1 -1
  88. package/build/map/next_js/resolveServerActions.js +449 -0
  89. package/build/map/next_js/resolveServerActions.js.map +1 -0
  90. package/build/map/next_js/utils.js +89 -2
  91. package/build/map/next_js/utils.js.map +1 -1
  92. package/build/map/react_js/getReactConnections.js +298 -0
  93. package/build/map/react_js/getReactConnections.js.map +1 -0
  94. package/build/map/react_js/interactive.js +4 -0
  95. package/build/map/react_js/interactive.js.map +1 -0
  96. package/build/map/react_js/react_resolveFetch.js +6 -0
  97. package/build/map/react_js/react_resolveFetch.js.map +1 -0
  98. package/build/map/svelte_js/interactive.js +58 -0
  99. package/build/map/svelte_js/interactive.js.map +1 -0
  100. package/build/map/svelte_js/interactive_helpers/commandHandler.js +4 -0
  101. package/build/map/svelte_js/interactive_helpers/commandHandler.js.map +1 -0
  102. package/build/map/vue_js/bodyResolver.js +477 -0
  103. package/build/map/vue_js/bodyResolver.js.map +1 -0
  104. package/build/map/vue_js/crossFileResolver.js +438 -0
  105. package/build/map/vue_js/crossFileResolver.js.map +1 -0
  106. package/build/map/vue_js/getViteConnections.js +151 -106
  107. package/build/map/vue_js/getViteConnections.js.map +1 -1
  108. package/build/map/vue_js/interactive.js +28 -0
  109. package/build/map/vue_js/interactive.js.map +1 -1
  110. package/build/map/vue_js/interactive_helpers/commandHandler.js +22 -0
  111. package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -1
  112. package/build/map/vue_js/interactive_helpers/helpMenu.js +1 -0
  113. package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -1
  114. package/build/map/vue_js/taint_utils.js +621 -0
  115. package/build/map/vue_js/taint_utils.js.map +1 -0
  116. package/build/map/vue_js/vue_resolveFetch.js +279 -25
  117. package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
  118. package/build/map/vue_js/vue_resolveHttpClient.js +733 -0
  119. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -0
  120. package/build/map/vue_js/vue_resolveXhr.js +279 -0
  121. package/build/map/vue_js/vue_resolveXhr.js.map +1 -0
  122. package/build/mcp/chatOneShot.js +101 -0
  123. package/build/mcp/chatOneShot.js.map +1 -0
  124. package/build/mcp/claudeCodeCreds.js +150 -0
  125. package/build/mcp/claudeCodeCreds.js.map +1 -0
  126. package/build/mcp/cli.js +140 -149
  127. package/build/mcp/cli.js.map +1 -1
  128. package/build/mcp/commands.js +80 -0
  129. package/build/mcp/commands.js.map +1 -1
  130. package/build/mcp/index.js +30 -9
  131. package/build/mcp/index.js.map +1 -1
  132. package/build/mcp/intent.js +204 -0
  133. package/build/mcp/intent.js.map +1 -0
  134. package/build/mcp/jobs.js +199 -0
  135. package/build/mcp/jobs.js.map +1 -0
  136. package/build/mcp/mcpServer.js +241 -0
  137. package/build/mcp/mcpServer.js.map +1 -0
  138. package/build/mcp/providers.js +18 -1
  139. package/build/mcp/providers.js.map +1 -1
  140. package/build/mcp/skills.js +115 -0
  141. package/build/mcp/skills.js.map +1 -0
  142. package/build/refactor/index.js +6 -0
  143. package/build/refactor/index.js.map +1 -1
  144. package/build/refactor/react/index.js +636 -0
  145. package/build/refactor/react/index.js.map +1 -0
  146. package/build/report/utility/populateDb/populateAnalysisFindings.js +1 -1
  147. package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -1
  148. package/build/run/index.js +277 -60
  149. package/build/run/index.js.map +1 -1
  150. package/build/run/interruptHandler.js +93 -0
  151. package/build/run/interruptHandler.js.map +1 -0
  152. package/build/utility/globals.js +38 -0
  153. package/build/utility/globals.js.map +1 -1
  154. package/build/utility/makeReq.js +39 -5
  155. package/build/utility/makeReq.js.map +1 -1
  156. package/build/utility/openapiGenerator.js +61 -17
  157. package/build/utility/openapiGenerator.js.map +1 -1
  158. package/build/utility/postmanGenerator.js +69 -16
  159. package/build/utility/postmanGenerator.js.map +1 -1
  160. package/build/utility/progressLog.js +50 -0
  161. package/build/utility/progressLog.js.map +1 -0
  162. package/package.json +7 -4
@@ -38,9 +38,23 @@ jobs:
38
38
  fi
39
39
  fi
40
40
 
41
- prettier:
41
+ audit:
42
42
  runs-on: ubuntu-latest
43
43
  needs: version_check
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: actions/setup-node@v4
47
+ with:
48
+ node-version: "22"
49
+ cache: "npm"
50
+ - name: Install dependencies
51
+ run: npm ci
52
+ - name: Run npm audit
53
+ run: npm audit
54
+
55
+ prettier:
56
+ runs-on: ubuntu-latest
57
+ needs: audit
44
58
  steps:
45
59
  - name: Checkout
46
60
  uses: actions/checkout@v4
@@ -8,16 +8,17 @@ on:
8
8
  jobs:
9
9
  check-branch:
10
10
  runs-on: ubuntu-latest
11
+ permissions:
12
+ pull-requests: write
11
13
  steps:
12
- - uses: actions/checkout@v4
13
- - name: Check source branch
14
- if: github.head_ref != 'dev'
14
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
15
+ - name: Redirect PR to dev
16
+ if: github.head_ref != 'dev' || github.event.pull_request.head.repo.full_name != 'shriyanss/js-recon'
15
17
  env:
16
18
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17
- PR_URL: ${{ github.event.pull_request.html_url }}
19
+ PR_NUMBER: ${{ github.event.pull_request.number }}
18
20
  BRANCH_NAME: ${{ github.head_ref }}
21
+ SOURCE_REPO: ${{ github.event.pull_request.head.repo.full_name }}
19
22
  run: |
20
- git config user.name "github-actions[bot]"
21
- git config user.email "github-actions[bot]@users.noreply.github.com"
22
- gh pr comment $PR_URL --body "This merge is not possible. Create a PR for $BRANCH_NAME -> dev"
23
- gh pr close $PR_URL
23
+ gh pr edit $PR_NUMBER --base dev
24
+ gh pr comment $PR_NUMBER --body "This PR was targeting \`main\`, but only the \`dev\` branch of \`shriyanss/js-recon\` can merge directly into \`main\`. The target branch has been changed to \`dev\` (source: \`$SOURCE_REPO:$BRANCH_NAME\`)."
@@ -35,9 +35,21 @@ jobs:
35
35
  GITHUB_RELEASE_VERSION_RAW: ${{ github.event.release.tag_name }}
36
36
 
37
37
 
38
- build:
38
+ audit:
39
39
  needs: version_check
40
40
  runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+ - uses: actions/setup-node@v4
44
+ with:
45
+ node-version: 22
46
+ - run: npm ci
47
+ - name: Run npm audit
48
+ run: npm audit
49
+
50
+ build:
51
+ needs: audit
52
+ runs-on: ubuntu-latest
41
53
  steps:
42
54
  - uses: actions/checkout@v4
43
55
  - uses: actions/setup-node@v4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,101 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.3.1-alpha.4 - 2026-06-08
4
+
5
+ ### Fixed
6
+
7
+ - `extractSourceMaps` no longer crashes with `EISDIR` when a source map entry has a degenerate path (e.g. a bare `webpack://` prefix with no trailing path) that `normalizePath` reduces to `"."` — such entries are now silently skipped (`lazyload`, `run`)
8
+ - Source map files extracted during `run` are now written to `output/<domain>/extracted/` (or the equivalent per-target subdirectory) instead of a bare `extracted/` directory in the current working directory (`lazyload`, `run`)
9
+
10
+ ### Performance
11
+
12
+ - `makeGetCallers` now caches per-file content + Babel AST tuples for the lifetime of the resolver instance, so repeated caller searches at high recursion depth no longer re-read and re-parse every JS file on each call — depth-8 runs that previously took 200+ minutes on a large real-world target now complete in under a minute (`map`)
13
+ - `map -t svelte/vue/react`: `getViteConnections` now parses each JS file exactly once instead of twice (single-pass replaces the two-pass approach), cutting parse-time memory in half for large applications (`map`)
14
+ - `map -t svelte/vue/react`: replaced `JSON.stringify(chunks)` (which allocated a string equal in size to the entire output file) with a streaming `createWriteStream` write that serialises one chunk at a time, eliminating the peak in-memory JSON string (`map`)
15
+ - `map -t svelte/vue/react`: `vue_resolveFetch` no longer caches all parsed ASTs and file contents for "fetch"-containing files simultaneously; ASTs are now parsed on-demand and discarded after each file, with a bounded LRU cache of at most 20 ASTs kept alive for cross-file caller lookup (`map`)
16
+ - `map -t svelte/vue/react`: `FetchEntry.enclosingFn.node` (an AST node reference that pinned each file's full Babel AST through the entries array until the end of the second pass) is now nulled out — the field is not read in the second pass; `FetchEntry.fileContent` is similarly cleared to avoid retaining all processed file contents in memory (`map`)
17
+
18
+ ### Added
19
+
20
+ - GraphQL operation extraction during `--openapi` generation — `map` now scans every downloaded JS file's string and template literals, feeds candidates through the official `graphql` library's `parse()`, and emits each parsed query/mutation/subscription as a POST request. Output is placed under a flat top-level `GraphQL` folder in the Postman collection and tagged `GraphQL` in the OpenAPI spec, with method `POST`, path `/{{graphqlEndpoint}}`, and a JSON body of shape `{"operationName": "...", "query": "...", "variables": {...}}`. The printed query inlines transitively-referenced fragment definitions so each emitted request is self-contained. Disabled with `--no-graphql` (alias `--ngql`) on both `map` and `run` (`map`, `run`)
21
+ - `collectionFolder` optional field on `OpenapiOutputItem` — when set, the OpenAPI generator uses it as the operation's `tags` value and the Postman generator places the item under a flat top-level folder with that name, bypassing the path-segment-derived hierarchy. Used by the new GraphQL resolver to group all operations under a single `GraphQL` folder regardless of transport URL (`map`)
22
+ - `--lazyload-timeout <minutes>` flag on both `lazyload` and `run` commands (default 30, 0 = disabled) — sets a hard ceiling on how long each lazyLoad step runs. When the timer fires the module logs a warning and the pipeline continues to the next step; in-flight Puppeteer pages and downloads may still complete in the background but their results are discarded (`lazyload`, `run`)
23
+ - Next.js lazyload now scans ALL downloaded JS files for webpack chunk URL builder functions (`__webpack_require__.u` pattern), not just `webpack-*.js` files — covers module federation entry points and other non-standard filenames. Scanning runs iteratively after the initial crawl until no new chunk URLs are discovered, with a CLI progress bar (`lazyload`)
24
+ - `--max-recursion-depth <n>` flag on `map` (default 3) — controls how far the HTTP-client URL fan-out and cross-file resolver recurse through caller chains. Higher values resolve more `[param:X]` markers at the cost of runtime; the per-entry deadline scales with depth so deeper recursion still terminates (`map`)
25
+ - `deepSubstituteBodyValue` body resolver — when a request body contains a `[param:X]` leaf whose call-site value is a structured object (e.g. a credentials/config object passed by an outer caller), the leaf is now replaced with the full nested object rather than left as a placeholder string. Used by both the HTTP-client and fetch resolvers (`map`)
26
+ - `makeGetCallersSameFile` fallback for body-param resolution — when the param-owning function has a short minifier-local binding name (≤ 2 chars), `resolveParamToAnyValue` now does a targeted same-file AST search to catch direct in-file callers that `makeGetCallers` skips to avoid cross-file false positives. Same-file short-name calls are unambiguous because the binding is in scope (`map`)
27
+ - Object-preference in `resolveParamToAnyValue` — prefers a caller whose argument resolves to a structured object/array over one that resolves to a bare string, since body params are typically objects and string-arg overloads are usually unrelated dispatch calls. Also skips resolved values where every leaf is still an unresolved placeholder marker (`map`)
28
+ - `OptionalMemberExpression` AST node handling in `deepResolveValue`, `resolveReturnInline`, and `resolveNodeValue` — optional chaining (`a?.b`) in URL/body expressions is now resolved the same way as regular member expressions instead of returning the opaque "unsupported node type" marker (`map`)
29
+ - HTTP-client method-call resolver for Vue/React/Svelte bundles — captures `<obj>.<verb>(<url>, [body], [config])` callsites (where `<verb>` ∈ {get,post,put,delete,patch,head,options}), runs same-function assignment recovery for late-bound locals, fans the URL out across every caller chain, and emits one OpenAPI entry per resolved caller. Designed for bundles whose transport layer overrides `XMLHttpRequest.prototype.{open,send,setRequestHeader}` (axios xhrAdapter and similar wrappers), where the literal URL is composed at the client-instance method call site rather than inside the adapter (`map`)
30
+ - `EnclosingFn.paramNames` + `parent` chain in the shared taint primitives — taint substitution can now resolve `[param:X]` for any parameter at any index in any enclosing function, including across anonymous Promise-chain callbacks where the immediate enclosing function doesn't declare X (`map`)
31
+ - Per-file alias map in `makeGetCallers` — recognizes `{ name: Binding }` re-exports and `{ name: () => Binding }` webpack getter exports so callsites that hit the binding through its public name (e.g. `ae.request(...)`, `r.default.postUnchecked(...)`) are correctly matched as callers of the local minified symbol. Aliases are scoped per file because minifier locals collide across modules (`map`)
32
+ - Member-expression callsite matching in `makeGetCallers` — `<anything>.<exportedName>(...)` is now recognised as a caller of the bound function, in addition to bare-identifier calls (`map`)
33
+ - XMLHttpRequest detection and resolution for Vue.JS, React, and Svelte/Astro bundles — resolves `.open()` method/URL, `.setRequestHeader()` header pairs, and `.send()` body from each XHR binding's call chain; results are registered in the OpenAPI output (`map`)
34
+ - Detect Next.js Server Actions registered via `createServerReference` and emit them as POST endpoints in the OpenAPI spec and Postman collection — includes `next-action` / `Accept` / `Content-Type` headers, route derived from App Router file path, and argument hints traced from the first call site (`map`)
35
+ - Argument hints in Server Action request bodies carry the inferred type alongside the variable name (e.g. `<string:userId>`) instead of an opaque placeholder (`map`)
36
+ - Location metadata for Server Actions: definition chunk + absolute file path + line and call-site chunk + absolute file path + line, surfaced as the `description` field in both the OpenAPI spec and Postman collection (`map`)
37
+ - `list server_actions` interactive command — prints all discovered Server Actions with route, body args, and source locations (`map -i`)
38
+ - Svelte/Astro framework support — `lazyload` now discovers island JS files via recursive HTML page crawl and ESM import following; `map` decodes Vite production chunks using the same logic as Vue; `analyze` and `run` pipeline added for Svelte/Astro apps (`lazyload`, `map`, `analyze`, `run`)
39
+ - `fingerprint` subcommand — batch framework detection against one or more target URLs; outputs detected framework and version to stdout in `text` (default), `json`, `jsonl`, or `csv` format; useful for triaging large target lists before running the full pipeline (`fingerprint`)
40
+ - React (Vite/Rolldown) framework detection via `<link rel="modulepreload">` elements and fast-path filename matching, in addition to inline `<script>` tags (`lazyload`)
41
+ - Recursive ESM import following for React bundles — static imports, dynamic `import()`, and Vite `__vite_mapDeps` arrays are parsed from each downloaded file so all referenced chunks are fetched transitively (`lazyload`)
42
+ - `map` and `analyze` pipeline support for React (Vite/Rolldown) applications, using the same fetch-resolver and analyze engine as Vue with vendor-chunk filtering (`map`, `analyze`, `run`)
43
+ - Content-entropy deduplication in `lazyload` — query-param variants of the same path are probed and only skipped when their extracted script sets are identical, so genuinely distinct parameterised routes are still crawled (`lazyload`)
44
+ - Ctrl-C interrupt menu in `run` — pressing Ctrl-C during a pipeline step shows an interactive prompt (skip current step / skip current target / exit) instead of immediately killing the process; in batch mode an extra "skip target" option is offered (`run`)
45
+ - `regexMatch` step type in the AST rule engine — matches string and template literals against a regex pattern, enabling rules that detect hardcoded credentials and other value-pattern findings (`analyze`)
46
+ - React tech added to all tech-gated type definitions and rule schemas (`analyze`)
47
+ - Model Context Protocol stdio server (`mcp --server`) — speaks the MCP protocol so js-recon can be wired into Claude Code, Cursor, and other MCP-aware hosts as a tool provider. Registers `lazyload`, `strings`, `map`, `endpoints`, `analyze`, `report`, `run`, `list_skills`, and `run_skill` as MCP tools. Subcommand stdout is captured and redirected to stderr so the chatty `console.log` output never corrupts the JSON-RPC frame; captured text is returned as the tool result (`mcp`)
48
+ - One-shot chat flag `-c/--chat <prompt>` on `mcp` (repeatable) — sends a single prompt to the AI agent non-interactively, prints the reply, and exits. Intent-detected `lazyload`/`run` jobs are awaited before the reply so the LLM sees the captured output (`mcp`)
49
+ - Claude Code OAuth credential reuse — when no API key is configured, `mcp --cli` and `mcp -c` fall back to the OAuth bearer token stored by the official Claude Code CLI (macOS keychain service `Claude Code-credentials`, or `~/.claude/.credentials.json` on Linux). The Anthropic SDK is constructed with `authToken` + `anthropic-beta: oauth-2025-04-20`. Tokens are auto-refreshed when expired (with a warning); refresh tokens are written back to the source credential store. OAuth tokens are never persisted to `~/.js-recon/mcp.yaml`. Disable refresh with `--no-refresh-claude-creds` (`mcp`)
50
+ - Background-job runner for `mcp --cli` — `lazyload` and `run` actions now spawn child processes (`node build/index.js <subcmd> ...`) and return immediately so the REPL stays responsive. The user can chat with the LLM while a job runs; tails of running jobs are auto-injected into the LLM context on every turn so the model can answer "how's it going?" naturally. New slash commands: `/jobs`, `/log <id>`, `/tail <id> [n]`, `/cancel <id>`. Ctrl-C cancels the most recent running job (SIGTERM → SIGKILL after 3s) before falling through to the exit warning (`mcp --cli`)
51
+ - Skills system — workflow prompts shipped under `~/.js-recon/skills/*.md` (delivered via a new `skills/` directory in the `js-recon-rules` release zipball, staged by `initRules`). Each skill carries YAML frontmatter (`name`, `description`, `params`, optional `pre_actions`). Invoke from the REPL with `/skill <name> [--param value …]`, via natural-language intent (e.g. `pentest <url>` routes to `web_app_pentest`), or from external MCP hosts via the `run_skill` MCP tool. `pre_actions` declare tool jobs (e.g. `run`) that are spawned before the rendered skill prompt is handed to the LLM. Ships with `graphql_pentest` and `web_app_pentest` (`mcp`, `analyze`)
52
+ - `--claude-client-id <id>` flag on `mcp` — OAuth client ID used when auto-refreshing Claude Code credentials; required in environments where the default Anthropic client ID is not registered (`mcp --cli`, `mcp -c`)
53
+
54
+ ### Changed
55
+
56
+ - Fetch resolution log lines now include the resolved URL, method, headers, and body immediately after the `[+] Found fetch call in "file":line` line instead of being grouped at the end (`map`)
57
+ - Fetch resolution logs correctly label the framework ("React" or "Vue.JS") in the start and summary messages (`map`)
58
+ - `mcp --cli` launches in the user's current working directory and prints a `Working directory: <abs>` + `Artifacts are preserved across runs.` banner. Spawned job child processes inherit that cwd explicitly so artifacts always land next to the user's other working files (`mcp --cli`)
59
+ - Intent detector now requires word-boundary matches on `scan|run|check|test` so the substring `pentest` no longer accidentally routes to `run`; "pentest" + URL now routes to the `web_app_pentest` skill (or any `*_pentest` skill) when one is loaded (`mcp --cli`)
60
+ - Updated `@anthropic-ai/sdk` dependency to **0.102.0**
61
+
62
+ ### Fixed
63
+
64
+ - `refactor -t react`: chunks whose AST already contains `export { X as default }` or `export default X` no longer receive a second trailing `export default` statement — the refactor pass now checks for an existing default export in the generated code before appending one (`refactor`)
65
+ - Fetch resolver second pass now handles `[param:X]` markers in request bodies — previously `MARKER_RE` matched only `[member:]` / `[urlsearchparams:]` and the resolver explicitly excluded `[param:]` markers, so a fetch wrapper whose body was an outer function parameter (`fetch(url, { body: JSON.stringify({ ..., body: E }) })`) was emitted with the literal placeholder string instead of the structured object the caller actually passed. The body JSON is now parsed and walked with `deepSubstituteBodyValue` so nested object/array call-site values replace the marker leaves (`map`)
66
+ - `[MemberExpression -> X]`, `[var X]`, and other unresolved placeholders in URLs are now substituted with their OpenAPI equivalents (`{X}`) before URL parsing in the OpenAPI spec generator, preventing spurious `Invalid URL` errors for placeholder-containing paths (`map`)
67
+ - Silenced the `Invalid URL` catch in the OpenAPI query-parameter extractor — URLs that remain unparseable after placeholder substitution (e.g. absolute URLs with placeholder hostnames) are skipped silently, since this is expected behaviour (`map`)
68
+ - Add error handling if webpack JS file is not valid
69
+ - `getRuleFilesRecursive` now skips hidden directories (e.g. `.github`) so GitHub Actions workflow YAML files are not loaded as rules (`analyze`)
70
+ - `run` now deletes stale map artifacts (`mapped.json`, `mapped-openapi.json`, `mapped-openapi.postman_collection.json`) before invoking `map`, preventing a leftover file from a previous run being reused when the output directory has been cleared without a full `cleanup` — which caused `resolveFetch` to look up file paths from the wrong target (`run`)
71
+ - `regexMatch` engine step now collects all matching string/template-literal nodes instead of stopping at the first hit; each matched node emits its own finding, so all hardcoded secrets in a single chunk are reported individually rather than only the first one (`analyze`)
72
+ - Taint propagation now follows callback parameters: when a tainted value is passed alongside an inline function argument in a call (e.g. Vue `watch(source, cb)`), the parameters of the inline function are marked tainted, fixing false-negatives where the callback param received a tainted value at runtime but was not tracked (`analyze`)
73
+ - CSPT rule no longer treats `route.params.*` and `useParams()` as taint sources — route segment params are validated against the router's path pattern and cannot carry arbitrary `../` traversal strings; only query params (`route.query`, `URLSearchParams`, `location.search/hash`) are high-confidence CSPT sources (`analyze`)
74
+ - Vue and React pipelines now also delete stale map artifacts before invoking `map`, applying the same fix as the Next.js pipeline; previously a stale `mapped.json` from a prior run would cause the analyze step to report findings against the wrong target's chunk IDs (`run`)
75
+ - `mcp --cli` "Thinking..." spinner no longer ticks forever after a provider error — the `setInterval` is now declared outside the `try` and cleared in `finally`, so 4xx/network failures render cleanly and the next prompt is not mangled (`mcp --cli`)
76
+ - Job/skill announcements (e.g. `[Job 1] run started ...`, `[Invoking skill: web_app_pentest]`) are now echoed to the REPL the moment `handleToolExecution` returns, in addition to being baked into the LLM context. Previously, if the subsequent LLM call failed (quota / auth), the user had no visible signal that a background scan had actually been spawned (`mcp --cli`)
77
+ - Ctrl-C in `mcp --cli` no longer crashes the readline with `SES_UNCAUGHT_EXCEPTION: readline was closed`. The SIGINT handler is wrapped in a try/catch and `prompt()` is guarded by a `promptingActive` flag so a re-entrant call against an already-pending `rl.question` is dropped instead of tearing the interface down (`mcp --cli`)
78
+
79
+ ## 1.3.1-alpha.3 - 2026-05-20
80
+
81
+ ### Added
82
+
83
+ - Add version for rule templates
84
+ - Add Vue js support for analyze module
85
+ - `esquery` interactive command + headless `-c/--command` runner for `map` and `run`, with `&&` chaining (`map`)
86
+ - Line-editor behavior in interactive mode: cursor movement (left/right/home/end/ctrl-a/ctrl-e), word-wise motion/delete (ctrl-w, ctrl-left/right), kill-to-start/end (ctrl-u/ctrl-k), delete-at-cursor, mid-string insertion so paste lands at the cursor, and horizontal scroll for long inputs (`map -i`)
87
+
88
+ ### Changed
89
+
90
+ - Removed `mouse: true` from the interactive output pane so terminal-native text selection/copy works in the output area (`map -i`)
91
+ - Vue.js fetch resolver now walks back to the enclosing wrapper function's caller(s) so `URLSearchParams(param.subprop)` expands to real `?k1={k1}&k2={k2}` query strings and spread-header / member-value placeholders get substituted from the caller's object literal — including transitive resolution when the caller passes its own param through (`map`)
92
+ - Vue.js fetch resolver recognises destructured fetch wrappers (e.g. `const { wrapperKey: x } = factory({ ... })`) and resolves their callsites as fetch calls, with positional-first-arg filtering to avoid mis-identifying object-shaped wrappers that construct the URL from a property of their input (`map`)
93
+ - Distinct callsites for the same `(path, method)` are preserved in both the OpenAPI spec (path key gets a `#N` suffix) and the Postman collection (request name gets a `#N` suffix) instead of being collapsed to a single entry (`map`)
94
+
95
+ ### Fixed
96
+
97
+ - Spread elements in request bodies and option objects are no longer silently dropped when the spread argument is unresolvable — the output surfaces a sentinel key (e.g. `"...arg": "<spread>"`, `"...call()": "<spread>"`) so downstream readers know more fields exist at runtime (`map`)
98
+
3
99
  ## 1.3.1-alpha.2 - 2026-05-18
4
100
 
5
101
  ### Added
package/CLAUDE.md ADDED
@@ -0,0 +1,225 @@
1
+ # js-recon
2
+
3
+ Static analysis tool that maps API endpoints and detects client-side security issues by analyzing Next.js (webpack/turbopack) and Vue.js bundles. Written in TypeScript, compiled to `build/` before running.
4
+
5
+ ## Build & run
6
+
7
+ ```bash
8
+ npm run cleanup # rm -rf build/ + tsc (full rebuild)
9
+ npm run start -- <subcommand> [options]
10
+ ```
11
+
12
+ `cleanup` must be run before testing any TypeScript change when using the `run` command.
13
+
14
+ ## Subcommands
15
+
16
+ | Command | Purpose |
17
+ | ------------- | ---------------------------------------------------------------------------------- |
18
+ | `lazyload` | Download JS chunks from a target URL |
19
+ | `strings` | Extract strings/paths/secrets from JS files |
20
+ | `map` | Parse webpack/turbopack bundles into a structured `mapped.json` |
21
+ | `endpoints` | Extract client-side routes |
22
+ | `analyze` | Run YAML rules against `mapped.json` / OpenAPI spec |
23
+ | `report` | Generate HTML/SQLite report |
24
+ | `run` | Run all of the above in sequence (primary interface) |
25
+ | `api-gateway` | Manage AWS API Gateway for IP rotation |
26
+ | `mcp` | AI-powered CLI / one-shot chat (`-c`) / Model Context Protocol server (`--server`) |
27
+
28
+ ## Key source files
29
+
30
+ - `src/index.ts` — CLI entry point; all subcommand definitions and option declarations live here
31
+ - `src/run/index.ts` — orchestrates the full pipeline (`run` subcommand); two tech-specific flows (Next.js 8-step, Vue 4-step)
32
+ - `src/analyze/index.ts` — loads/validates rules, runs AST and request engines
33
+ - `src/analyze/helpers/initRules.ts` — downloads/caches rules from GitHub to `~/.js-recon/rules`
34
+ - `src/analyze/helpers/validate.ts` — validates rules and checks `js_recon_version` compatibility
35
+ - `src/analyze/helpers/schemas.ts` — Zod schema for rule YAML files
36
+ - `src/map/graphql/resolveGraphql.ts` — framework-agnostic GraphQL operation scanner. Visits every `StringLiteral` and `TemplateLiteral` in every JS file, validates with the `graphql` library's `parse()`, and emits each operation as a POST request under a flat `GraphQL` collection folder. Inlines transitively-referenced fragment definitions into each printed query so emitted requests are self-contained. Runs in every framework branch of `map/index.ts` when `--openapi` is on and `--no-graphql`/`--ngql` is not set.
37
+ - `src/map/next_js/resolveFetch.ts` — resolves `fetch()` calls, detects Next.js framework chunks
38
+ - `src/map/next_js/resolveServerActions.ts` — detects `createServerReference(actionId, ...)` calls, derives App Router routes from chunk file paths, traces argument call sites (same-chunk and cross-chunk), and emits POST endpoints with `next-action` headers and typed arg hints (e.g. `<string:userId>`) into the global OpenAPI output
39
+ - `src/map/next_js/utils.ts` — `resolveNodeValue`, `resolveVariableInChunk`, `substituteVariablesInString`
40
+ - `src/map/vue_js/vue_resolveXhr.ts` — directory-scan resolver for `new XMLHttpRequest()` + `.open()/.setRequestHeader()/.send()` patterns. Shared by Vue/React/Svelte pipelines; the `frameworkName` arg only changes log labels. Reaches ground-truth XHR sites but in axios/Got/Ky-style bundles the URL/method come from a dispatcher config (`re.url`, `re.method`) and resolve only to opaque `[member:re.url]` placeholders that taint analysis cannot unwind across the library's internal dispatch chain — those entries fail the `looksLikeUrl` check at emit time. Catch the wrapper-level call instead via `vue_resolveHttpClient`.
41
+ - `src/map/vue_js/vue_resolveHttpClient.ts` — directory-scan resolver for `<obj>.<verb>(<url>, [body], [config])` calls where `<verb>` ∈ {get,post,put,delete,patch,head,options}. Designed for bundles whose transport layer overrides `XMLHttpRequest.prototype.{open,send,setRequestHeader}` (axios xhrAdapter and similar wrappers): the override layer is irrelevant to URL extraction because the literal URL is composed at the client-instance method call site, not inside the adapter. The `looksLikeUrl` heuristic (post-placeholder-strip, must contain `/` or scheme) filters out `Map.get` / `Headers.delete` / `EventBus.post` false positives while keeping partially-resolved URLs like `[call:base()]<literal>/[var X]`. Three resolution stages run on every captured callsite — each addresses a separate gap exposed when an RPC wrapper is hidden behind multiple layers of webpack-exported helpers:
42
+ 1. `resolveFromAssignments` — walks `binding.constantViolations` for `[unresolved: NAME]` markers, so identifiers declared as `let X;` and assigned later in the function body (e.g. `(X = a + "/" + b)` inside a sequence expression) resolve to their RHS. `resolveNodeValue`'s Identifier handler only looks at `binding.init`, which is empty for late-assigned locals.
43
+ 2. `expandParamPlaceholders` — fans out one captured callsite into one URL per caller chain. Walks the `enclosingFn.parent` chain to find which named function declares each `[param:X]`, then substitutes **every** placeholder owned by that same function from a single caller's args (keeps `[param:e]`/`[param:t]` consistent across one caller — never mixing args from different callsites). Recurses on the caller's `enclosingFn` so a forwarding wrapper (`Se(e,t,n) → ae.request(e,t,n,...)`) walks up to the wrapper's own callers.
44
+ 3. Taint substitution falls back to `substituteCallerPlaceholders` / `substituteCallerHeaders` for body/header placeholders that don't have multi-caller fan-out semantics.
45
+
46
+ Wired into Vue / React / Svelte pipelines in `map/index.ts`.
47
+
48
+ - `src/map/vue_js/taint_utils.ts` — shared taint analysis primitives. Several pieces are non-obvious and exist to make `vue_resolveHttpClient` (and `vue_resolveXhr`) work on webpack output:
49
+ - `EnclosingFn.paramNames` + `parent` chain: `resolveNodeValue` emits `[param:X]` for any param at any index in any enclosing function. The chain lets the helpers resolve such a marker against whichever enclosing scope actually declared X — bundled code routinely nests the resolution callsite inside an anonymous `.then(function ($) {…})` whose own params don't include X, while X is a param of an outer named function.
50
+ - `buildAliasMap`: collects `{ exportedName: localBinding }` and `{ exportedName: () => localBinding }` patterns from object literals on a **per-file** basis. Webpack's `a.d(b, { name: () => Binding })` getter exports and re-export registries (`const ae = { request: Me }`) hide the local minifier name behind a meaningful key; without this map, `getCallers("Me")` would miss every `ae.request(...)` / `r.default.request(...)` callsite. **The map must be file-scoped** — minifier locals (`Se`, `Me`) collide across modules, and a global alias map blends unrelated functions into the same name set.
51
+ - `makeGetCallers` accepts an optional `sourceFile` argument so callers can scope alias lookup to the file where the binding was declared. Direct minifier-local matches (`bindingName.length ≤ 2`) are dropped from the candidate list because they generate too many false positives across files; meaningful aliases (length > 2) are kept and used for both bare-identifier (`X(...)`) and member-expression (`<anything>.X(...)`) callsite matching. Overflow returns the partial caller list rather than nothing — the file-scoped alias map already suppresses noise, so partial coverage beats none.
52
+ - `src/map/next_js/getWebpackConnections.ts` — extracts chunk code from webpack bundles
53
+ - `src/map/next_js/interactive_helpers/esqueryGen.ts` — `esquery` interactive command: minifies a pasted snippet, matches it against each chunk's minified AST nodes, prints loose/strict selectors. Vue's command handler imports the same module — keep it framework-agnostic.
54
+ - `src/map/next_js/interactive.ts` / `src/map/vue_js/interactive.ts` — export both the blessed-backed `interactive()` entry and a headless `runCommands(chunks, mapFile, commands)` that pipes `outputBox.log` to stdout for `-c/--command` execution.
55
+ - `src/map/next_js/interactive_helpers/inputPatch.ts` — `enableCursorInput(inputBox)` patches a blessed textbox instance to support cursor movement, mid-string insertion, and paste-at-cursor. It overrides `_listener`/`setValue`/`_updateCursor`/`clearValue` on the instance. **Don't try to remove blessed's listener after the fact** — blessed re-binds `this._listener` on every focus, so overriding `_listener` on the instance is the only race-free approach. Shared by Next.js and Vue interactive entries.
56
+ - `src/globalConfig.ts` — current version string and tool-wide constants
57
+ - `src/utility/globals.ts` — mutable global state (tech detection result, AI config, OpenAPI flag, etc.)
58
+
59
+ ## `run` pipeline in detail
60
+
61
+ `run` is the primary subcommand. It calls `processUrl` for each target, which dispatches to one of two pipelines based on the detected front-end framework (`globalsUtil.getTech()`).
62
+
63
+ ### Next.js pipeline (8 steps)
64
+
65
+ 1. **Lazyload** — downloads initial JS chunks via Puppeteer; detects framework; sets `globalsUtil.getTech()` to `"next"`
66
+ 2. **Strings** — scans downloaded JS for strings, extracts URL paths → `extracted_urls.json`
67
+ 3. **Lazyload (subsequent requests)** — re-crawls using the extracted paths to fetch dynamically loaded chunks; also fetches `buildId`
68
+ 4. **Strings (pass 2)** — re-runs strings on the expanded chunk set; generates `extracted_urls.txt` (permuted) and `extracted_urls-openapi.json`; optionally scans secrets (`--secrets`)
69
+ 5. **Lazyload re-pass (step 4.5)** — a second subsequent-requests crawl to pick up chunks for dynamic routes discovered in pass 2
70
+ 6. **Strings re-pass (step 4.6)** — strings pass over the re-pass chunks
71
+ 7. **Map** — parses webpack/turbopack bundles; resolves `fetch()` calls and axios usage; generates `mapped.json` and `mapped-openapi.json`; CDN-aware: if JS was served from a different host, `getCdnDir` finds the CDN output dir and passes that to map instead of `outputDir/host`
72
+ 8. **Endpoints** — extracts client-side route paths; uses `___subsequent_requests` directory presence to decide whether to pass a JS directory
73
+ 9. **Analyze** — loads YAML rules (from `-r/--rules` if provided, otherwise default rules cache); runs AST engine and request engine; writes `analyze.json`
74
+ 10. **Report** — populates SQLite DB (`js-recon.db`) and generates HTML report
75
+
76
+ ### Vue.js pipeline (4 steps)
77
+
78
+ 1. **Lazyload** — same as Next.js step 1; sets `globalsUtil.getTech()` to `"vue"`
79
+ 2. **Map** — scans the entire `outputDir` (Vue chunks spread across asset hosts)
80
+ 3. **Analyze** — same rule loading as Next.js; `-r/--rules` is forwarded here too
81
+ 4. **Report** — same as Next.js; if `endpoints.json` doesn't exist it is written as `[]` since Vue endpoints extraction isn't implemented yet
82
+
83
+ ### Tech detection flow
84
+
85
+ `lazyLoad` sets the global tech string. If it remains `""` after lazyload, `run` exits (single URL) or skips (batch). Techs other than `"next"` and `"vue"` only get lazyload; the rest of the pipeline is skipped with a warning.
86
+
87
+ ### Batch mode
88
+
89
+ When `-u` points to a file of URLs, each line is processed sequentially. For each URL:
90
+
91
+ - A subdirectory `output/<host>/` is created
92
+ - `clearJsUrls()` / `clearJsonUrls()` reset the URL sets so previous targets don't bleed over
93
+ - All output paths are prefixed with `workingDir/`
94
+
95
+ ## Adding a new flag to `run`
96
+
97
+ 1. Declare the option in `src/index.ts` on the `run` command (`.option(...)`)
98
+ 2. If it configures a global, call the setter in the `action` handler before `await run(cmd)`
99
+ 3. If it needs to reach a downstream module (like `analyze`), thread it through `cmd` — `processUrl` receives the full `cmd` object and passes it to submodule calls
100
+
101
+ **Example — `-r/--rules` flag (added in this codebase):**
102
+
103
+ - Declared in `src/index.ts`: `.option("-r, --rules <file/dir>", "Rules file or directory (passed to analyze module)")`
104
+ - In `src/run/index.ts` the `analyze` calls use `cmd.rules || ""` — empty string tells `analyze` to use the default rules cache
105
+
106
+ **Example — `--lazyload-timeout` flag:**
107
+
108
+ - Declared in `src/index.ts` on both the `lazyload` and `run` commands: `.option("--lazyload-timeout <minutes>", ..., "30")`
109
+ - Threaded directly into each `lazyLoad()` call as `Number(cmd.lazyloadTimeout) * 60 * 1000` (converts minutes → ms). Unlike flags that set a global, this one is passed as a parameter — no setter in the action handler.
110
+
111
+ ## Interactive-mode commands
112
+
113
+ The `map -i` blessed UI dispatches user input through `interactive_helpers/commandHandler.ts`. The same handler runs headlessly when commands are supplied via `-c/--command`:
114
+
115
+ - The `-c` option's commander coerce function splits each value on `&&` (with optional whitespace) and concatenates into a single command array. So `-c "list fetch && esquery * fetch"` is two commands; passing `-c` twice has the same effect.
116
+ - `map`'s entry point checks `commands.length > 0` first — if non-empty, it calls `nextRunCommands` / `vueRunCommands` and skips the blessed UI even when `-i` is also set.
117
+ - New commands should be added to **both** `next_js/interactive_helpers/commandHandler.ts` and `vue_js/interactive_helpers/commandHandler.ts`, plus the corresponding `helpMenu.ts` entry. When the implementation is framework-agnostic (e.g. `esquery`), put it under `next_js/interactive_helpers/` and import it from the Vue handler — don't duplicate.
118
+ - `list server_actions` is intentionally Next.js-only (it reads from `getOpenapiOutput()` filtered by `next-action` header) and has no Vue counterpart.
119
+
120
+ ## Reversing RPC-style API calls from manual browser observations
121
+
122
+ When the user supplies a call-stack screenshot or notes from a real session ("XHR sent here, sink is this prototype override, body comes from this function"), the goal isn't to reproduce that exact target — it's to find the _generic pattern_ that the bundler emitted and add resolver support for it. The reverse-engineering workflow that produced the HTTP-client resolver:
123
+
124
+ 1. **Read the call stack bottom-up.** The deepest frame is almost always the transport (`XMLHttpRequest.send`, `fetch`); ignore it. The next frames going up are the HTTP library (axios's `_request` / `dispatchXhrRequest`); ignore those too unless the URL is literal at that level. Look for the first frame whose source line contains _a recognisable path fragment or template string_ — that's the wrapper callsite worth resolving.
125
+ 2. **Identify the URL composition site.** Open the file at that frame in the downloaded bundle (`output/<host>/static/js/<chunk>.js`) and find the literal. Typical webpack patterns are `client.post(base + "literal/path/" + paramVar, body, config)` or `client.request({ url: base + "/" + paramVar, method: "POST" })`. Note what's a literal, what's a parameter, what's a local variable.
126
+ 3. **Walk inward from the wrapper.** For every non-literal in the URL, find where it came from in the same function. If it's a `let X;` followed by `X = a + "/" + b` in a sequence expression, that's `resolveFromAssignments`' territory. If it's a function parameter, that's taint analysis' territory.
127
+ 4. **Walk outward from the wrapper.** Look at the callers of the enclosing function. In webpack bundles the function is usually exported through one of:
128
+ - A registry object: `const ae = { request: Me, postUnchecked: Se }` — callsites read `ae.request(...)`, NOT `Me(...)`.
129
+ - A webpack getter export: `a.d(b, { request: () => Me })` — same effect, different shape.
130
+ - Both. The same binding often appears in multiple aliases.
131
+
132
+ Both shapes are recognised by `buildAliasMap` in `taint_utils.ts` and _must be matched per file_ — minifier locals like `Se`, `Me` collide across modules.
133
+
134
+ 5. **Trace forwarding wrappers all the way out.** A wrapper like `Se(e, t, n) → ae.request(e, t, n, ...)` just forwards its parameters. After substituting at the wrapper level, recurse into Se's own callers; the externally-meaningful arguments (`s.signIn.namespace`) are several layers up.
135
+ 6. **Confirm the literal source.** The outermost caller passes a `MemberExpression` like `s.signIn.namespace`. Find the `const s = { signIn: { namespace: "...", method: "..." } }` declaration — `resolveNodeValue` handles this naturally as long as the binding is in scope at the caller's location.
136
+
137
+ If at any layer the new resolver returns `[unresolved: X]` or `[param:X]`, that's a signal which primitive is missing — extend `taint_utils.ts` (chain walk, per-file aliases, member-expression matching, late-assignment recovery) rather than special-casing the wrapper. The goal is a primitive that resolves _similar_ RPC-style libraries in unrelated apps, not the one bundle in front of you.
138
+
139
+ **Do not encode target-specific paths or service names in code or comments.** When iterating, run `map` against the downloaded chunks and grep the resulting `mapped-openapi.json` for the expected URL fragment — never paste that fragment into source.
140
+
141
+ ### How to test changes here
142
+
143
+ The HTTP-client resolver runs inside the `map` step of the React/Vue/Svelte pipeline; verify it as part of the full `run` pipeline (see "Testing a change" below). Quick iteration loop while debugging:
144
+
145
+ ```bash
146
+ npx tsc
147
+ node --max-old-space-size=8192 build/index.js map \
148
+ -d output/<host>/static/js -o /tmp/jsr-mapped -t react -f json \
149
+ 2>&1 | grep "URL: " | sort -u
150
+ ```
151
+
152
+ This bypasses the slow `lazyload` step by reusing already-downloaded chunks. The final acceptance test is still `npm run cleanup && npm run start -- run -u <target> -y -k`; grep `mapped-openapi.json` for the expected resolved URL fragment.
153
+
154
+ ## Rules
155
+
156
+ Rules are YAML files (`.yml`/`.yaml`) in two places:
157
+
158
+ - **Workspace:** `../js-recon-rules/` (relative to this repo)
159
+ - **Installed cache:** `~/.js-recon/rules`
160
+
161
+ `initRules` downloads rules from GitHub when missing or when the cached version doesn't match the latest release. `js_recon_version` (required) must be declared in every rule (e.g. `js_recon_version: ">=X.Y.Z"`); `initRules` uses it to validate compatibility and skips incompatible rules with a warning. The version check strips prerelease suffixes (e.g. `1.3.1-alpha.3` → `[1,3,1]`).
162
+
163
+ Rule categories:
164
+
165
+ - `ast/` — AST-based pattern matching against chunk code (uses `@babel/parser` + `esquery`)
166
+ - `request/` — OpenAPI/request-level checks against the resolved endpoint list
167
+
168
+ When `-r` points to a single file, only that rule is loaded. When it points to a directory, all `.yml`/`.yaml` files are loaded recursively.
169
+
170
+ ## Testing a change
171
+
172
+ **Testing is mandatory for every change.** Before reporting a task complete:
173
+
174
+ 1. Run `npm run cleanup` to rebuild TypeScript.
175
+ 2. Run the `run` subcommand against the target the user provides. Do not use `analyze` or other individual subcommands as a substitute — the `run` subcommand must be used to validate end-to-end behavior.
176
+ 3. If the user has not provided a target, ask for one before proceeding.
177
+
178
+ Typical test invocation:
179
+
180
+ ```bash
181
+ npm run cleanup && npm run start -- run -u <target-url> -y -k
182
+ ```
183
+
184
+ ## Release process
185
+
186
+ Releasing a new version touches four repos. Work on `dev` (js-recon, js-recon-rules) and `stage` (js-recon-docs). Do **not** touch `js-recon-research` — it is private and excluded from releases.
187
+
188
+ ### Steps
189
+
190
+ 1. **Bump version** — update `version` in `src/globalConfig.ts` and `package.json` to the new tag (e.g. `1.3.1-alpha.4`). Both must match.
191
+
192
+ 2. **Update CHANGELOG** — add a `## <version> - <YYYY-MM-DD>` section to `CHANGELOG.md` with `### Fixed`, `### Performance`, `### Added`, `### Changed` sub-sections as needed. Verify every `feat`/`fix` commit since the previous tag is covered:
193
+
194
+ ```bash
195
+ git log <prev-tag>..HEAD --oneline | grep -E "^[a-f0-9]+ (feat|fix)"
196
+ ```
197
+
198
+ 3. **Update README** — ensure the Commands table in `README.md` lists every subcommand declared in `src/index.ts`.
199
+
200
+ 4. **Update rules** (`js-recon-rules` repo, `dev` branch) — if there are unreleased commits, update `CHANGELOG.md` and `version.txt`, then push.
201
+
202
+ 5. **Update docs** (`js-recon-docs` repo, `stage` branch):
203
+ - Fix any option/flag gaps in `docs/docs/modules/*.md` (cross-check against `src/index.ts`).
204
+ - Snapshot the current docs: `npx docusaurus docs:version <version>` (run inside `js-recon-docs/`).
205
+ - Keep `lastVersion` in `docusaurus.config.ts` pointing to the last **stable** release (do not change it for alphas/betas).
206
+ - Verify: `npm run build` in `js-recon-docs/` must pass with no broken-link errors.
207
+
208
+ 6. **Push** — push all three repos to their source branches (`dev`/`stage`).
209
+
210
+ 7. **Open PRs** using `gh pr create`:
211
+ | Repo | Source | Target | Title | Body |
212
+ |------|--------|--------|-------|------|
213
+ | `shriyanss/js-recon` | `dev` | `main` | version string (e.g. `v1.3.1-alpha.4`) | `## <version>` changelog section |
214
+ | `shriyanss/js-recon-docs` | `stage` | `main` | version string | Brief summary of doc changes |
215
+ | `shriyanss/js-recon-rules` | `dev` | `main` | rules version (e.g. `v1.2.0`) | `## <version>` rules changelog section |
216
+
217
+ 8. **Monitor PRs** — CodeRabbit reviews automatically. Wait for GitHub CI (version check, build, etc.) to pass. The docs CI check is expected to fail until js-recon is fully published to npm.
218
+
219
+ ## Security / confidentiality
220
+
221
+ When a change is informed by behavior observed on a real target (URLs, endpoint names, response shapes, finding details, etc.):
222
+
223
+ - **Do not include any target information in code comments, commit messages, docstrings, variable names, or any other artifact.**
224
+ - This applies to hostnames, paths, parameter names, response content, or any other detail that could identify the target.
225
+ - If context from the target is needed to describe a change, describe it in abstract terms only (e.g. "URL parameter passed to fetch" not "https://example.com/api/docs passes `file` param to fetch").
package/README.md CHANGED
@@ -60,6 +60,8 @@ js-recon run -u https://app.example.com
60
60
  | `run` | Runs all analysis modules automatically on a target. | [Read Docs](https://js-recon.io/docs/docs/modules/run) |
61
61
  | `analyze` | Analyzes the code. | [Read Docs](https://js-recon.io/docs/docs/modules/analyze) |
62
62
  | `report` | Generates a report from the analysis modules. | [Read Docs](https://js-recon.io/docs/docs/modules/report) |
63
+ | `mcp` | AI-powered interactive CLI, one-shot chat, and MCP stdio server. | [Read Docs](https://js-recon.io/docs/docs/modules/mcp) |
64
+ | `fingerprint` | Detects the JavaScript framework used by a target URL (JSON/JSONL output). | [Read Docs](https://js-recon.io/docs/docs/modules/fingerprint) |
63
65
 
64
66
  ## Key Features
65
67
 
@@ -9,7 +9,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import chalk from "chalk";
11
11
  import parser from "@babel/parser";
12
+ import _traverse from "@babel/traverse";
12
13
  import _generator from "@babel/generator";
14
+ const _traverseDefault = _traverse.default;
13
15
  const generator = _generator.default;
14
16
  import esquery from "esquery";
15
17
  import { highlight } from "cli-highlight";
@@ -134,6 +136,30 @@ const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
134
136
  }
135
137
  }
136
138
  }
139
+ else if (step.regexMatch) {
140
+ // Scan all StringLiteral/TemplateLiteral nodes in the chunk for values matching the regex
141
+ const pattern = new RegExp(step.regexMatch.pattern);
142
+ const foundNodes = [];
143
+ _traverseDefault(ast, {
144
+ StringLiteral(nodePath) {
145
+ if (pattern.test(nodePath.node.value)) {
146
+ foundNodes.push(nodePath.node);
147
+ }
148
+ },
149
+ TemplateLiteral(nodePath) {
150
+ for (const quasi of nodePath.node.quasis) {
151
+ if (pattern.test(quasi.value.raw)) {
152
+ foundNodes.push(nodePath.node);
153
+ break;
154
+ }
155
+ }
156
+ },
157
+ });
158
+ if (foundNodes.length > 0) {
159
+ matchList[step.name] = { node: foundNodes[0], scope: ast, allNodes: foundNodes };
160
+ completedSteps.add(step.name);
161
+ }
162
+ }
137
163
  else if (step.checkAssignmentExist) {
138
164
  const selectedNode = (_b = matchList[step.checkAssignmentExist.name]) === null || _b === void 0 ? void 0 : _b.node;
139
165
  const toMatch = step.checkAssignmentExist.type;
@@ -158,36 +184,38 @@ const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
158
184
  if (completedSteps.size === rule.steps.length) {
159
185
  const message = `[+] "${rule.name}" found in chunk ${chunk.id}`;
160
186
  const lastMatch = Object.values(matchList)[Object.keys(matchList).length - 1];
161
- const code = generator(lastMatch.node).code;
162
- // print the message based on the severity of the rule
163
- if (rule.severity === "info") {
164
- console.log(chalk.cyan(message));
165
- }
166
- else if (rule.severity === "low") {
167
- console.log(chalk.yellow(message));
168
- }
169
- else if (rule.severity === "medium") {
170
- console.log(chalk.magenta(message));
171
- }
172
- else if (rule.severity === "high") {
173
- console.log(chalk.red(message));
187
+ const nodesToReport = lastMatch.allNodes && lastMatch.allNodes.length > 1 ? lastMatch.allNodes : [lastMatch.node];
188
+ for (const reportNode of nodesToReport) {
189
+ const code = generator(reportNode).code;
190
+ if (rule.severity === "info") {
191
+ console.log(chalk.cyan(message));
192
+ }
193
+ else if (rule.severity === "low") {
194
+ console.log(chalk.yellow(message));
195
+ }
196
+ else if (rule.severity === "medium") {
197
+ console.log(chalk.magenta(message));
198
+ }
199
+ else if (rule.severity === "high") {
200
+ console.log(chalk.red(message));
201
+ }
202
+ console.log(highlight(code, {
203
+ language: "javascript",
204
+ ignoreIllegals: true,
205
+ theme: undefined,
206
+ }));
207
+ findings.push({
208
+ ruleId: rule.id,
209
+ ruleName: rule.name,
210
+ ruleType: rule.type,
211
+ ruleDescription: rule.description,
212
+ ruleAuthor: rule.author,
213
+ ruleTech: rule.tech,
214
+ severity: rule.severity,
215
+ message: message,
216
+ findingLocation: `// ${chunk.id}\n\n${code}`,
217
+ });
174
218
  }
175
- console.log(highlight(code, {
176
- language: "javascript",
177
- ignoreIllegals: true,
178
- theme: undefined,
179
- }));
180
- findings.push({
181
- ruleId: rule.id,
182
- ruleName: rule.name,
183
- ruleType: rule.type,
184
- ruleDescription: rule.description,
185
- ruleAuthor: rule.author,
186
- ruleTech: rule.tech,
187
- severity: rule.severity,
188
- message: message,
189
- findingLocation: `// ${chunk.id}\n\n${code}`,
190
- });
191
219
  }
192
220
  }
193
221
  return findings;
@@ -1 +1 @@
1
- {"version":3,"file":"astEngine.js","sourceRoot":"","sources":["../../../src/analyze/engine/astEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"astEngine.js","sourceRoot":"","sources":["../../../src/analyze/engine/astEngine.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,CAAC;AAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC;AACrC,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAClG,OAAO,EAAE,8BAA8B,EAAE,MAAM,4DAA4D,CAAC;AAC5G,OAAO,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAa,MAAM,uCAAuC,CAAC;AAGnG;;;;;;;;;;GAUG;AACH,MAAM,aAAa,GAAG,CAAO,IAAU,EAAE,cAAsB,EAA2B,EAAE;;IACxF,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QAChD,qCAAqC;QACrC,IAAI,GAAG,CAAC;QACR,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC3B,UAAU,EAAE,aAAa;gBACzB,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC;gBAC9B,aAAa,EAAE,IAAI;aACtB,CAAC,CAAC;QACP,CAAC;QAAC,WAAM,CAAC;YACL,SAAS;QACb,CAAC;QAED,IAAI,SAAS,GAAsE,EAAE,CAAC;QACtF,MAAM,cAAc,GAAgB,IAAI,GAAG,EAAE,CAAC;QAC9C,6EAA6E;QAC7E,yCAAyC;QACzC,MAAM,UAAU,GAAwC,EAAE,CAAC;QAE3D,wCAAwC;QACxC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,gFAAgF;YAChF,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzE,IAAI,CAAC,cAAc,EAAE,CAAC;oBAClB,SAAS;gBACb,CAAC;YACL,CAAC;YAED,8CAA8C;YAC9C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;gBAEpC,iFAAiF;gBACjF,4EAA4E;gBAC5E,yFAAyF;gBACzF,IAAI,UAAU,GAAS,GAAG,CAAC;gBAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBACzB,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBACrD,IAAI,CAAC,UAAU,EAAE,CAAC;wBACd,mDAAmD;wBACnD,SAAS;oBACb,CAAC;oBACD,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC;gBACjC,CAAC;gBAED,wEAAwE;gBACxE,IAAI,OAAO,GAAW,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBAEpD,yEAAyE;gBACzE,uEAAuE;gBACvE,gEAAgE;gBAChE,oDAAoD;gBACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;oBAC9C,MAAM,WAAW,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;oBAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;wBACf,sDAAsD;wBACtD,SAAS;oBACb,CAAC;oBACD,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;wBAC9B,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;wBAC/D,UAAU,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;oBAChE,CAAC;oBACD,MAAM,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;oBACzC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;gBACtE,CAAC;gBAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrB,+EAA+E;oBAC/E,oEAAoE;oBACpE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;oBAC3E,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBACrC,6FAA6F;gBAE7F,MAAM,YAAY,GAAS,MAAA,SAAS,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,0CAAE,IAAI,CAAC;gBAE7E,IAAI,YAAY,EAAE,CAAC;oBACf,0DAA0D;oBAC1D,IAAI,YAAY,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;wBACzC,IACI,YAAY,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB;4BAC/C,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;4BAClD,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,kBAAkB;4BACxD,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe;4BAClD,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,EAC/C,CAAC;4BACC,IAAI,YAAY,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gCACtC,+CAA+C;gCAC/C,4BAA4B;gCAC5B,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oCAClD,qCAAqC;oCACrC,MAAM,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oCACrD,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;oCAE5E,IAAI,gBAAgB,EAAE,CAAC;wCACnB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;wCAC9D,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oCAClC,CAAC;gCACL,CAAC;qCAAM,IACH,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB;oCACvD,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,yBAAyB,EAC9D,CAAC;oCACC,MAAM,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oCACrD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;oCAChE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gCAClC,CAAC;4BACL,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzB,0FAA0F;gBAC1F,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACpD,MAAM,UAAU,GAAW,EAAE,CAAC;gBAC9B,gBAAgB,CAAC,GAAG,EAAE;oBAClB,aAAa,CAAC,QAAa;wBACvB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;4BACpC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;wBACnC,CAAC;oBACL,CAAC;oBACD,eAAe,CAAC,QAAa;wBACzB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;4BACvC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gCAChC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gCAC/B,MAAM;4BACV,CAAC;wBACL,CAAC;oBACL,CAAC;iBACJ,CAAC,CAAC;gBACH,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;oBACjF,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBACnC,MAAM,YAAY,GAAS,MAAA,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,0CAAE,IAAI,CAAC;gBAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;gBAC/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC;gBAEpE,IAAI,YAAY,IAAI,gBAAgB,EAAE,CAAC;oBACnC,MAAM,cAAc,GAAG,8BAA8B,CACjD,YAAY,EACZ,OAAO,EACP,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,KAAK,CAClD,CAAC;oBAEF,IAAI,cAAc,EAAE,CAAC;wBACjB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;wBAC5D,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;qBAAM,IAAI,YAAY,EAAE,CAAC;oBACtB,MAAM,cAAc,GAAG,oBAAoB,CACvC,YAAY,EACZ,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,KAAK,CAClD,CAAC;oBAEF,IAAI,cAAc,EAAE,CAAC;wBACjB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;wBAC5D,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,qEAAqE;QACrE,IAAI,cAAc,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,IAAI,CAAC,IAAI,oBAAoB,KAAK,CAAC,EAAE,EAAE,CAAC;YAChE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC9E,MAAM,aAAa,GACf,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAEhG,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;gBAExC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrC,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;oBACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBACvC,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;gBACxC,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;oBAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBACpC,CAAC;gBAED,OAAO,CAAC,GAAG,CACP,SAAS,CAAC,IAAI,EAAE;oBACZ,QAAQ,EAAE,YAAY;oBACtB,cAAc,EAAE,IAAI;oBACpB,KAAK,EAAE,SAAS;iBACnB,CAAC,CACL,CAAC;gBAEF,QAAQ,CAAC,IAAI,CAAC;oBACV,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,eAAe,EAAE,IAAI,CAAC,WAAW;oBACjC,UAAU,EAAE,IAAI,CAAC,MAAM;oBACvB,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,OAAO,EAAE,OAAO;oBAChB,eAAe,EAAE,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI,EAAE;iBAC/C,CAAC,CAAC;YACP,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAA,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -35,7 +35,7 @@ export const engine = (rule, mappedJsonData, openapiData, tech) => __awaiter(voi
35
35
  techValid = false;
36
36
  }
37
37
  }
38
- if (techValid || tech === "all") {
38
+ if (techValid || tech === "all" || rule.tech.includes("all")) {
39
39
  findings.push(...(yield requestEngine(rule, openapiData)));
40
40
  }
41
41
  }
@@ -49,7 +49,7 @@ export const engine = (rule, mappedJsonData, openapiData, tech) => __awaiter(voi
49
49
  techValid = false;
50
50
  }
51
51
  }
52
- if (techValid || tech === "all") {
52
+ if (techValid || tech === "all" || rule.tech.includes("all")) {
53
53
  findings.push(...(yield astEngine(rule, mappedJsonData)));
54
54
  }
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyze/engine/index.ts"],"names":[],"mappings":";;;;;;;;;AAGA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAGvC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAClB,IAAU,EACV,cAAkC,EAClC,WAAoC,EACpC,IAAoB,EACe,EAAE;IACrC,yGAAyG;IAEzG,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAElC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAA,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyze/engine/index.ts"],"names":[],"mappings":";;;;;;;;;AAGA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAGvC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAClB,IAAU,EACV,cAAkC,EAClC,WAAoC,EACpC,IAAiD,EACd,EAAE;IACrC,yGAAyG;IAEzG,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAElC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAA,CAAC;AAEF,eAAe,MAAM,CAAC"}