@shriyanss/js-recon 1.4.1-alpha.3 → 1.4.1-alpha.5
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/.github/workflows/build-and-prettify.yaml +195 -9
- package/.github/workflows/publish-js-recon.yml +54 -10
- package/.github/workflows/rules-smoke-test.yaml +79 -0
- package/CHANGELOG.md +51 -0
- package/CLAUDE.md +232 -11
- package/README.md +35 -16
- package/build/analyze/engine/csMastSEngine.js +129 -0
- package/build/analyze/engine/csMastSEngine.js.map +1 -0
- package/build/analyze/engine/index.js +15 -0
- package/build/analyze/engine/index.js.map +1 -1
- package/build/analyze/helpers/engineHelpers/findDirectAssignment.js +2 -1
- package/build/analyze/helpers/engineHelpers/findDirectAssignment.js.map +1 -1
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +2 -1
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
- package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js +2 -1
- package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js.map +1 -1
- package/build/analyze/helpers/engineHelpers/taintFlow.js +11 -2
- package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -1
- package/build/analyze/helpers/schemas.js +5 -1
- package/build/analyze/helpers/schemas.js.map +1 -1
- package/build/analyze/helpers/validate.js +3 -3
- package/build/analyze/helpers/validate.js.map +1 -1
- package/build/completion/index.js +432 -0
- package/build/completion/index.js.map +1 -0
- package/build/cs_mast/index.js +94 -3
- package/build/cs_mast/index.js.map +1 -1
- package/build/endpoints/next_js/client_jsFilesHref.js +2 -1
- package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
- package/build/endpoints/next_js/client_jsonParse.js +2 -1
- package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
- package/build/endpoints/next_js/client_mappedJsonFile.js +2 -1
- package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
- package/build/endpoints/next_js/client_subsequentRequests.js +2 -1
- package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
- package/build/fingerprint/index.js +56 -33
- package/build/fingerprint/index.js.map +1 -1
- package/build/globalConfig.js +1 -1
- package/build/index.js +76 -6
- package/build/index.js.map +1 -1
- package/build/lazyLoad/angular/angular_getFromMainJs.js +2 -1
- package/build/lazyLoad/angular/angular_getFromMainJs.js.map +1 -1
- package/build/lazyLoad/downloadFilesUtil.js +6 -5
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/downloadLoadedJsUtil.js +56 -7
- package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -1
- package/build/lazyLoad/downloadQueue.js +9 -8
- package/build/lazyLoad/downloadQueue.js.map +1 -1
- package/build/lazyLoad/index.js +30 -47
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +36 -34
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +63 -15
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_parseLayoutJs.js +80 -68
- package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js +22 -16
- package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js +49 -47
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -1
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +3 -2
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/react/react_followImports.js +12 -9
- package/build/lazyLoad/react/react_followImports.js.map +1 -1
- package/build/lazyLoad/react/react_webpackChunkPaths.js +175 -123
- package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +3 -2
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js +27 -6
- package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkReact.js +8 -0
- package/build/lazyLoad/techDetect/checkReact.js.map +1 -1
- package/build/lazyLoad/techDetect/index.js +23 -2
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_RuntimeJs.js +2 -1
- package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +22 -10
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +2 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/vue/vue_jsImports.js +2 -1
- package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
- package/build/lazyLoad/vue/vue_viteMapDeps.js +62 -54
- package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -1
- package/build/map/angular_js/getAngularConnections.js +1 -1
- package/build/map/angular_js/getAngularConnections.js.map +1 -1
- package/build/map/graphql/resolveGraphql.js +2 -1
- package/build/map/graphql/resolveGraphql.js.map +1 -1
- package/build/map/next_js/getExports.js +2 -1
- package/build/map/next_js/getExports.js.map +1 -1
- package/build/map/next_js/getFetchInstances.js +2 -1
- package/build/map/next_js/getFetchInstances.js.map +1 -1
- package/build/map/next_js/getTurbopackConnections.js +2 -1
- package/build/map/next_js/getTurbopackConnections.js.map +1 -1
- package/build/map/next_js/getWebpackConnections.js +2 -1
- package/build/map/next_js/getWebpackConnections.js.map +1 -1
- package/build/map/next_js/resolveAxios.js +2 -1
- package/build/map/next_js/resolveAxios.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/traceBody.js +2 -1
- package/build/map/next_js/resolveAxiosHelpers/traceBody.js.map +1 -1
- package/build/map/next_js/resolveFetch.js +2 -1
- package/build/map/next_js/resolveFetch.js.map +1 -1
- package/build/map/next_js/resolveNewRequest.js +2 -1
- package/build/map/next_js/resolveNewRequest.js.map +1 -1
- package/build/map/next_js/resolveServerActions.js +2 -1
- package/build/map/next_js/resolveServerActions.js.map +1 -1
- package/build/map/next_js/utils.js +2 -1
- package/build/map/next_js/utils.js.map +1 -1
- package/build/map/react_js/getReactConnections.js +5 -4
- package/build/map/react_js/getReactConnections.js.map +1 -1
- package/build/map/vue_js/crossFileResolver.js +3 -2
- package/build/map/vue_js/crossFileResolver.js.map +1 -1
- package/build/map/vue_js/getViteConnections.js +5 -4
- package/build/map/vue_js/getViteConnections.js.map +1 -1
- package/build/map/vue_js/taint_utils.js +2 -1
- package/build/map/vue_js/taint_utils.js.map +1 -1
- package/build/map/vue_js/vue_resolveFetch.js +3 -2
- package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
- package/build/map/vue_js/vue_resolveHttpClient.js +3 -2
- package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
- package/build/map/vue_js/vue_resolveXhr.js +3 -2
- package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
- package/build/mcp/cli.js.map +1 -1
- package/build/refactor/index.js +399 -60
- package/build/refactor/index.js.map +1 -1
- package/build/refactor/next/helpers.js +194 -13
- package/build/refactor/next/helpers.js.map +1 -1
- package/build/refactor/next/index.js +223 -36
- package/build/refactor/next/index.js.map +1 -1
- package/build/refactor/next/transform.js +905 -55
- package/build/refactor/next/transform.js.map +1 -1
- package/build/refactor/react/index.js +3 -3
- package/build/refactor/react/index.js.map +1 -1
- package/build/refactor/react/library-classify.js.map +1 -1
- package/build/refactor/react/transform.js +2 -1
- package/build/refactor/react/transform.js.map +1 -1
- package/build/refactor/react/validator.js +2 -1
- package/build/refactor/react/validator.js.map +1 -1
- package/build/refactor/react-vite/index.js +39 -5
- package/build/refactor/react-vite/index.js.map +1 -1
- package/build/refactor/react-vite/vendor-analyze.js +3 -3
- package/build/refactor/react-vite/vendor-analyze.js.map +1 -1
- package/build/refactor/remote/config.js +17 -1
- package/build/refactor/remote/config.js.map +1 -1
- package/build/refactor/remote/hf-client.js +27 -2
- package/build/refactor/remote/hf-client.js.map +1 -1
- package/build/refactor/remote/version-detect.js +355 -0
- package/build/refactor/remote/version-detect.js.map +1 -0
- package/build/refactor/vue/index.js +176 -0
- package/build/refactor/vue/index.js.map +1 -0
- package/build/refactor/vue/vendor-analyze-vue.js +271 -0
- package/build/refactor/vue/vendor-analyze-vue.js.map +1 -0
- package/build/refactor/vue/vite.js +216 -0
- package/build/refactor/vue/vite.js.map +1 -0
- package/build/report/utility/genHtml.js +14 -3
- package/build/report/utility/genHtml.js.map +1 -1
- package/build/run/bundler-detect.js +140 -0
- package/build/run/bundler-detect.js.map +1 -0
- package/build/run/index.js +91 -5
- package/build/run/index.js.map +1 -1
- package/build/sourcemaps/index.js +89 -0
- package/build/sourcemaps/index.js.map +1 -0
- package/build/strings/index.js +6 -2
- package/build/strings/index.js.map +1 -1
- package/build/strings/trufflehog.js +71 -0
- package/build/strings/trufflehog.js.map +1 -0
- package/build/utility/makeReq.js +10 -9
- package/build/utility/makeReq.js.map +1 -1
- package/build/utility/postmanGenerator.js +2 -2
- package/build/utility/postmanGenerator.js.map +1 -1
- package/build/utility/puppeteerInstance.js +7 -1
- package/build/utility/puppeteerInstance.js.map +1 -1
- package/package.json +9 -5
- package/scripts/smoke-test.js +74 -0
|
@@ -12,7 +12,7 @@ jobs:
|
|
|
12
12
|
!startsWith(github.event.head_commit.message, 'chore: prettify code')
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
16
16
|
- name: Check version mismatch
|
|
17
17
|
env:
|
|
18
18
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -42,8 +42,8 @@ jobs:
|
|
|
42
42
|
runs-on: ubuntu-latest
|
|
43
43
|
needs: version_check
|
|
44
44
|
steps:
|
|
45
|
-
- uses: actions/checkout@
|
|
46
|
-
- uses: actions/setup-node@
|
|
45
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
46
|
+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
47
47
|
with:
|
|
48
48
|
node-version: "22"
|
|
49
49
|
cache: "npm"
|
|
@@ -57,14 +57,14 @@ jobs:
|
|
|
57
57
|
needs: audit
|
|
58
58
|
steps:
|
|
59
59
|
- name: Checkout
|
|
60
|
-
uses: actions/checkout@
|
|
60
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
61
61
|
with:
|
|
62
62
|
# Make sure the action checks out the repository to the pull request branch
|
|
63
63
|
ref: ${{ github.ref_name }}
|
|
64
64
|
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
|
65
65
|
|
|
66
66
|
- name: Set up Node.js
|
|
67
|
-
uses: actions/setup-node@
|
|
67
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
68
68
|
with:
|
|
69
69
|
node-version: "22"
|
|
70
70
|
cache: "npm"
|
|
@@ -89,18 +89,39 @@ jobs:
|
|
|
89
89
|
git commit -m "chore: prettify code" || echo "No changes to commit"
|
|
90
90
|
git push
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
test:
|
|
93
93
|
needs: prettier
|
|
94
94
|
runs-on: ubuntu-latest
|
|
95
95
|
steps:
|
|
96
96
|
- name: Checkout
|
|
97
|
-
uses: actions/checkout@
|
|
97
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
98
|
+
with:
|
|
99
|
+
ref: ${{ github.ref_name }}
|
|
100
|
+
|
|
101
|
+
- name: Set up Node.js
|
|
102
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
103
|
+
with:
|
|
104
|
+
node-version: "22"
|
|
105
|
+
cache: "npm"
|
|
106
|
+
|
|
107
|
+
- name: Install dependencies
|
|
108
|
+
run: npm ci
|
|
109
|
+
|
|
110
|
+
- name: Run unit tests
|
|
111
|
+
run: npm test
|
|
112
|
+
|
|
113
|
+
build:
|
|
114
|
+
needs: test
|
|
115
|
+
runs-on: ubuntu-latest
|
|
116
|
+
steps:
|
|
117
|
+
- name: Checkout
|
|
118
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
98
119
|
with:
|
|
99
120
|
# Make sure the action checks out the repository to the pull request branch
|
|
100
121
|
ref: ${{ github.ref_name }}
|
|
101
122
|
|
|
102
123
|
- name: Set up Node.js
|
|
103
|
-
uses: actions/setup-node@
|
|
124
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
104
125
|
with:
|
|
105
126
|
node-version: "22"
|
|
106
127
|
cache: "npm"
|
|
@@ -113,9 +134,174 @@ jobs:
|
|
|
113
134
|
runs-on: ubuntu-latest
|
|
114
135
|
steps:
|
|
115
136
|
- name: Checkout
|
|
116
|
-
uses: actions/checkout@
|
|
137
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
117
138
|
with:
|
|
118
139
|
# Make sure the action checks out the repository to the pull request branch
|
|
119
140
|
ref: ${{ github.ref_name }}
|
|
120
141
|
- name: Build docker container
|
|
121
142
|
run: docker build -t shriyanss/js-recon .
|
|
143
|
+
|
|
144
|
+
integration-test-docker:
|
|
145
|
+
needs: build-docker
|
|
146
|
+
runs-on: ubuntu-latest
|
|
147
|
+
timeout-minutes: 30
|
|
148
|
+
steps:
|
|
149
|
+
- name: Checkout js-recon
|
|
150
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
151
|
+
with:
|
|
152
|
+
ref: ${{ github.ref_name }}
|
|
153
|
+
|
|
154
|
+
- name: Checkout js-recon-labs
|
|
155
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
156
|
+
with:
|
|
157
|
+
repository: shriyanss/js-recon-labs
|
|
158
|
+
path: js-recon-labs
|
|
159
|
+
|
|
160
|
+
- name: Checkout js-recon-rules
|
|
161
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
162
|
+
with:
|
|
163
|
+
repository: shriyanss/js-recon-rules
|
|
164
|
+
path: js-recon-rules
|
|
165
|
+
|
|
166
|
+
- name: Set up Node.js
|
|
167
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
168
|
+
with:
|
|
169
|
+
node-version: "22"
|
|
170
|
+
cache: "npm"
|
|
171
|
+
|
|
172
|
+
- name: Build js-recon Docker image
|
|
173
|
+
run: docker build -t shriyanss/js-recon .
|
|
174
|
+
|
|
175
|
+
- name: Install vuln-all-rules app dependencies
|
|
176
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
177
|
+
run: npm ci
|
|
178
|
+
|
|
179
|
+
- name: Build vuln-all-rules app
|
|
180
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
181
|
+
run: npm run build
|
|
182
|
+
|
|
183
|
+
- name: Start vuln-all-rules app
|
|
184
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
185
|
+
run: npm start &
|
|
186
|
+
|
|
187
|
+
- name: Wait for lab app to be ready
|
|
188
|
+
run: |
|
|
189
|
+
echo "Waiting for lab app on port 3001..."
|
|
190
|
+
n=0
|
|
191
|
+
until curl -sf http://localhost:3001 > /dev/null; do
|
|
192
|
+
n=$((n+1))
|
|
193
|
+
[ $n -ge 30 ] && echo "Timed out waiting for lab app" && exit 1
|
|
194
|
+
sleep 2
|
|
195
|
+
done
|
|
196
|
+
echo "Lab app is ready."
|
|
197
|
+
|
|
198
|
+
- name: Run js-recon via Docker against lab app
|
|
199
|
+
run: |
|
|
200
|
+
docker run --name js-recon-run \
|
|
201
|
+
--network host \
|
|
202
|
+
-v "$(pwd)/js-recon-rules:/home/pptruser/js-recon-rules" \
|
|
203
|
+
--entrypoint /bin/bash \
|
|
204
|
+
shriyanss/js-recon \
|
|
205
|
+
-c 'mkdir -p ~/.js-recon && ln -sf /home/pptruser/js-recon-rules ~/.js-recon/rules && printf "http://localhost:3001\n" > /tmp/urls.txt && node build/index.js run -u /tmp/urls.txt -r ./js-recon-rules --no-sandbox -y -k'
|
|
206
|
+
mkdir -p output
|
|
207
|
+
docker cp js-recon-run:/home/pptruser/output/. ./output/ 2>/dev/null || true
|
|
208
|
+
docker rm js-recon-run
|
|
209
|
+
|
|
210
|
+
- name: Verify all rules fired
|
|
211
|
+
run: node scripts/smoke-test.js
|
|
212
|
+
|
|
213
|
+
- name: Upload analyze.json on failure
|
|
214
|
+
if: failure()
|
|
215
|
+
uses: actions/upload-artifact@v4
|
|
216
|
+
with:
|
|
217
|
+
name: analyze-json-docker
|
|
218
|
+
path: output/localhost_3001/analyze.json
|
|
219
|
+
if-no-files-found: ignore
|
|
220
|
+
|
|
221
|
+
integration-test-macos:
|
|
222
|
+
needs: build
|
|
223
|
+
runs-on: macos-latest
|
|
224
|
+
timeout-minutes: 30
|
|
225
|
+
steps:
|
|
226
|
+
- name: Checkout js-recon
|
|
227
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
228
|
+
with:
|
|
229
|
+
ref: ${{ github.ref_name }}
|
|
230
|
+
|
|
231
|
+
- name: Checkout js-recon-labs
|
|
232
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
233
|
+
with:
|
|
234
|
+
repository: shriyanss/js-recon-labs
|
|
235
|
+
path: js-recon-labs
|
|
236
|
+
|
|
237
|
+
- name: Checkout js-recon-rules
|
|
238
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
239
|
+
with:
|
|
240
|
+
repository: shriyanss/js-recon-rules
|
|
241
|
+
path: js-recon-rules
|
|
242
|
+
|
|
243
|
+
- name: Set up Node.js
|
|
244
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
245
|
+
with:
|
|
246
|
+
node-version: "22"
|
|
247
|
+
cache: "npm"
|
|
248
|
+
|
|
249
|
+
- name: Install Chrome
|
|
250
|
+
run: brew install --cask google-chrome
|
|
251
|
+
|
|
252
|
+
- name: Install js-recon dependencies
|
|
253
|
+
run: npm ci
|
|
254
|
+
env:
|
|
255
|
+
PUPPETEER_SKIP_DOWNLOAD: "true"
|
|
256
|
+
|
|
257
|
+
- name: Build js-recon
|
|
258
|
+
run: npm run build
|
|
259
|
+
|
|
260
|
+
- name: Install vuln-all-rules app dependencies
|
|
261
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
262
|
+
run: npm ci
|
|
263
|
+
|
|
264
|
+
- name: Build vuln-all-rules app
|
|
265
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
266
|
+
run: npm run build
|
|
267
|
+
|
|
268
|
+
- name: Start vuln-all-rules app
|
|
269
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
270
|
+
run: npm start &
|
|
271
|
+
|
|
272
|
+
- name: Wait for lab app to be ready
|
|
273
|
+
run: |
|
|
274
|
+
echo "Waiting for lab app on port 3001..."
|
|
275
|
+
n=0
|
|
276
|
+
until curl -sf http://localhost:3001 > /dev/null; do
|
|
277
|
+
n=$((n+1))
|
|
278
|
+
[ $n -ge 30 ] && echo "Timed out waiting for lab app" && exit 1
|
|
279
|
+
sleep 2
|
|
280
|
+
done
|
|
281
|
+
echo "Lab app is ready."
|
|
282
|
+
|
|
283
|
+
- name: Pre-populate js-recon rules cache
|
|
284
|
+
run: |
|
|
285
|
+
mkdir -p ~/.js-recon
|
|
286
|
+
ln -sf "$GITHUB_WORKSPACE/js-recon-rules" ~/.js-recon/rules
|
|
287
|
+
|
|
288
|
+
- name: Run js-recon natively against lab app
|
|
289
|
+
run: |
|
|
290
|
+
echo "http://localhost:3001" > /tmp/smoke-urls.txt
|
|
291
|
+
node --max-old-space-size=4096 build/index.js run \
|
|
292
|
+
-u /tmp/smoke-urls.txt \
|
|
293
|
+
-r ./js-recon-rules \
|
|
294
|
+
-y -k
|
|
295
|
+
env:
|
|
296
|
+
PUPPETEER_EXECUTABLE_PATH: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
|
|
297
|
+
|
|
298
|
+
- name: Verify all rules fired
|
|
299
|
+
run: node scripts/smoke-test.js
|
|
300
|
+
|
|
301
|
+
- name: Upload analyze.json on failure
|
|
302
|
+
if: failure()
|
|
303
|
+
uses: actions/upload-artifact@v4
|
|
304
|
+
with:
|
|
305
|
+
name: analyze-json-macos
|
|
306
|
+
path: output/localhost_3001/analyze.json
|
|
307
|
+
if-no-files-found: ignore
|
|
@@ -11,7 +11,7 @@ jobs:
|
|
|
11
11
|
version_check:
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
14
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
15
15
|
- name: Check version mismatch
|
|
16
16
|
run: |
|
|
17
17
|
echo "[i] Checking if the version in the CHANGELOG.md, package.json, and Github release version matches"
|
|
@@ -39,8 +39,8 @@ jobs:
|
|
|
39
39
|
needs: version_check
|
|
40
40
|
runs-on: ubuntu-latest
|
|
41
41
|
steps:
|
|
42
|
-
- uses: actions/checkout@
|
|
43
|
-
- uses: actions/setup-node@
|
|
42
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
43
|
+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
44
44
|
with:
|
|
45
45
|
node-version: 22
|
|
46
46
|
- run: npm ci
|
|
@@ -51,8 +51,8 @@ jobs:
|
|
|
51
51
|
needs: audit
|
|
52
52
|
runs-on: ubuntu-latest
|
|
53
53
|
steps:
|
|
54
|
-
- uses: actions/checkout@
|
|
55
|
-
- uses: actions/setup-node@
|
|
54
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
55
|
+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
56
56
|
with:
|
|
57
57
|
node-version: 22
|
|
58
58
|
- run: npm ci
|
|
@@ -64,8 +64,8 @@ jobs:
|
|
|
64
64
|
needs: build
|
|
65
65
|
runs-on: ubuntu-latest
|
|
66
66
|
steps:
|
|
67
|
-
- uses: actions/checkout@
|
|
68
|
-
- uses: actions/setup-node@
|
|
67
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
68
|
+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
69
69
|
with:
|
|
70
70
|
node-version: 22
|
|
71
71
|
registry-url: https://registry.npmjs.org/
|
|
@@ -82,11 +82,55 @@ jobs:
|
|
|
82
82
|
VERSION: ${{ github.event.release.tag_name }}
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
update-homebrew-tap:
|
|
86
|
+
needs: publish-npm
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
steps:
|
|
89
|
+
- name: Get release version
|
|
90
|
+
id: version
|
|
91
|
+
run: |
|
|
92
|
+
RAW="${{ github.event.release.tag_name }}"
|
|
93
|
+
echo "version=${RAW#v}" >> "$GITHUB_OUTPUT"
|
|
94
|
+
|
|
95
|
+
- name: Compute npm tarball SHA256
|
|
96
|
+
id: sha256
|
|
97
|
+
run: |
|
|
98
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
99
|
+
URL="https://registry.npmjs.org/@shriyanss/js-recon/-/js-recon-${VERSION}.tgz"
|
|
100
|
+
SHA=$(curl -fsSL "${URL}" | sha256sum | awk '{print $1}')
|
|
101
|
+
echo "sha256=${SHA}" >> "$GITHUB_OUTPUT"
|
|
102
|
+
|
|
103
|
+
- name: Check out homebrew-tap
|
|
104
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
105
|
+
with:
|
|
106
|
+
repository: shriyanss/homebrew-tap
|
|
107
|
+
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
108
|
+
path: homebrew-tap
|
|
109
|
+
|
|
110
|
+
- name: Update formula fields
|
|
111
|
+
working-directory: homebrew-tap
|
|
112
|
+
run: |
|
|
113
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
114
|
+
SHA="${{ steps.sha256.outputs.sha256 }}"
|
|
115
|
+
F="Formula/js-recon.rb"
|
|
116
|
+
sed -i "s|^ url \"https://registry\.npmjs\.org/@shriyanss/js-recon/-/js-recon-[^\"]*\"| url \"https://registry.npmjs.org/@shriyanss/js-recon/-/js-recon-${VERSION}.tgz\"|" "${F}"
|
|
117
|
+
sed -i "s|^ sha256 \"[a-f0-9]*\"| sha256 \"${SHA}\"|" "${F}"
|
|
118
|
+
|
|
119
|
+
- name: Commit and push
|
|
120
|
+
working-directory: homebrew-tap
|
|
121
|
+
run: |
|
|
122
|
+
git config user.name "github-actions[bot]"
|
|
123
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
124
|
+
git add Formula/js-recon.rb
|
|
125
|
+
git commit -m "chore: update js-recon formula to ${{ steps.version.outputs.version }}"
|
|
126
|
+
git push
|
|
127
|
+
|
|
128
|
+
|
|
85
129
|
publish-docker:
|
|
86
130
|
needs: build
|
|
87
131
|
runs-on: ubuntu-latest
|
|
88
132
|
steps:
|
|
89
|
-
- uses: actions/checkout@
|
|
133
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
90
134
|
- name: Build and push to dockerhub
|
|
91
135
|
run: |
|
|
92
136
|
# login to docker
|
|
@@ -119,7 +163,7 @@ jobs:
|
|
|
119
163
|
contents: read
|
|
120
164
|
packages: write
|
|
121
165
|
steps:
|
|
122
|
-
- uses: actions/checkout@
|
|
166
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
123
167
|
- uses: docker/login-action@v3
|
|
124
168
|
with:
|
|
125
169
|
registry: ghcr.io
|
|
@@ -152,7 +196,7 @@ jobs:
|
|
|
152
196
|
- publish-ghcr
|
|
153
197
|
runs-on: ubuntu-latest
|
|
154
198
|
steps:
|
|
155
|
-
- uses: actions/checkout@
|
|
199
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
156
200
|
with:
|
|
157
201
|
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
|
158
202
|
fetch-depth: 0
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: Rules Smoke Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches-ignore:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
rules-smoke-test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
timeout-minutes: 30
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout js-recon
|
|
15
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
16
|
+
|
|
17
|
+
- name: Checkout js-recon-labs
|
|
18
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
19
|
+
with:
|
|
20
|
+
repository: shriyanss/js-recon-labs
|
|
21
|
+
path: js-recon-labs
|
|
22
|
+
|
|
23
|
+
- name: Checkout js-recon-rules
|
|
24
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
25
|
+
with:
|
|
26
|
+
repository: shriyanss/js-recon-rules
|
|
27
|
+
path: js-recon-rules
|
|
28
|
+
|
|
29
|
+
- name: Set up Node.js
|
|
30
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
31
|
+
with:
|
|
32
|
+
node-version: "22"
|
|
33
|
+
cache: "npm"
|
|
34
|
+
|
|
35
|
+
- name: Install js-recon dependencies
|
|
36
|
+
run: npm ci
|
|
37
|
+
|
|
38
|
+
- name: Build js-recon
|
|
39
|
+
run: npm run build
|
|
40
|
+
|
|
41
|
+
- name: Install vulnerable app dependencies
|
|
42
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
43
|
+
run: npm ci
|
|
44
|
+
|
|
45
|
+
- name: Build vulnerable app
|
|
46
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
47
|
+
run: npm run build
|
|
48
|
+
|
|
49
|
+
- name: Start vulnerable app
|
|
50
|
+
working-directory: js-recon-labs/next_js/vuln-all-rules
|
|
51
|
+
run: npm start &
|
|
52
|
+
|
|
53
|
+
- name: Wait for app to be ready
|
|
54
|
+
run: |
|
|
55
|
+
echo "Waiting for app on port 3001..."
|
|
56
|
+
timeout 60 bash -c 'until curl -sf http://localhost:3001 > /dev/null; do sleep 2; done'
|
|
57
|
+
echo "App is ready."
|
|
58
|
+
|
|
59
|
+
- name: Run js-recon against vulnerable app
|
|
60
|
+
run: |
|
|
61
|
+
echo "http://localhost:3001" > /tmp/smoke-urls.txt
|
|
62
|
+
node --max-old-space-size=4096 build/index.js run \
|
|
63
|
+
-u /tmp/smoke-urls.txt \
|
|
64
|
+
-r ./js-recon-rules \
|
|
65
|
+
--no-sandbox \
|
|
66
|
+
-y -k
|
|
67
|
+
env:
|
|
68
|
+
PUPPETEER_EXECUTABLE_PATH: /usr/bin/google-chrome-stable
|
|
69
|
+
|
|
70
|
+
- name: Verify all rules fired
|
|
71
|
+
run: node scripts/smoke-test.js
|
|
72
|
+
|
|
73
|
+
- name: Upload analyze.json on failure
|
|
74
|
+
if: failure()
|
|
75
|
+
uses: actions/upload-artifact@v4
|
|
76
|
+
with:
|
|
77
|
+
name: analyze-json
|
|
78
|
+
path: output/localhost_3001/analyze.json
|
|
79
|
+
if-no-files-found: ignore
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 1.4.1-alpha.5 - 2026-07-13
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Homebrew install: `puppeteer-extra` now receives the ESM `puppeteer` instance directly via `addExtra()` instead of relying on its internal `require('puppeteer')` call. On newer Node.js versions (22+, as shipped by Homebrew), a synchronous `require()` of an ESM module triggers `ExperimentalWarning` on every run. Using `addExtra()` bypasses the `require()` entirely and silences the warning. (`all`)
|
|
8
|
+
- `lazyload` (tech detect, react): React framework detection now works for Vite dev-mode servers. Vite's `@vitejs/plugin-react` and `@vitejs/plugin-react-swc` inject an inline `<script>` block containing `import { injectIntoGlobalHook } from "/@react-refresh"` into every dev-served page. Previously, none of the `REACT_MARKERS` matched this content, so dev-mode targets returned `unknown`. Two fixes: (1) `@react-refresh` and `injectIntoGlobalHook` are now included in `REACT_MARKERS` so the inline-script branch of `checkReact` fires immediately; (2) `/@react-refresh` is now a fast-path match in `fetchAndCheck` so any script src pointing at the HMR endpoint is also caught; (3) the intercepted-URL fallback in `frameworkDetect` now recognises `/@react-refresh` as a React signal alongside the existing Next.js / Nuxt / Svelte URL patterns. (`lazyload`, `fingerprint`, `run`)
|
|
9
|
+
- `lazyload` (tech detect, angular): Angular framework detection is now more robust. Three HTML-level signals are checked before fetching `main.js` — `data-beasties-container` (Angular's Beasties SSR/prerendering marker), `ng-version` (set by the Angular runtime on the root component element after bootstrapping, visible in Puppeteer-rendered DOM), and `_nghost-*` view-encapsulation attributes. These checks require no extra HTTP request and work even for zoneless Angular apps (Angular 16+) that omit Zone.js and therefore lack the previous `isAngularZone`/`this.ngZone` patterns. The `main.js` src pattern was also broadened from `main-` (hashed production builds only) to also match `main.js` (unhashed development builds). (`lazyload`, `fingerprint`, `run`)
|
|
10
|
+
- `lazyload`, `map`, `strings`: `.mjs` (ES module) files are now fully supported across all framework pipelines. Previously, extension filters in `downloadQueue.ts`, `downloadFilesUtil.ts`, `downloadLoadedJsUtil.ts`, `react_followImports.ts`, `getReactConnections.ts`, `getViteConnections.ts`, `getAngularConnections.ts`, `vue_resolveHttpClient.ts`, `vue_resolveFetch.ts`, `vue_resolveXhr.ts`, `crossFileResolver.ts`, and `strings/index.ts` only matched `.js` files. Sites that bundle all application code as `.mjs` (e.g. Framer/Rolldown) were silently ignored — all chunks were downloaded but zero files were scanned for connections, strings, or secrets. All affected paths now match both `.js` and `.mjs`. (`run`, `lazyload`, `map`, `strings`)
|
|
11
|
+
- `run` (react): The map step now receives the full `outputDir` (all downloaded hosts) rather than only the target host's subdirectory. Previously, when a React site served all its JS from a CDN host, the map step was pointed at an empty target-host directory and reported zero chunks. Now mirrors the Vue pipeline's directory-passing behaviour so CDN-hosted chunks are analysed correctly. (`run`, `map`)
|
|
12
|
+
- `lazyload` (react): `react_followImports` now discovers dynamic imports written as template literals (``import(`./chunk.mjs`)``) in addition to single/double-quoted strings. Bundlers that use Rolldown (e.g. Framer) emit all dynamic import paths as template literals; the previous regex only matched quoted strings, silently missing all lazily-loaded page and collection chunks. (`lazyload`, `run`)
|
|
13
|
+
- `lazyload`: `.mjs.map` sourcemap files are now handled correctly. The filename extraction regex now prefers the `.mjs.map` suffix over the shorter `.mjs` match, preventing sourcemap JSON content from being written with a `.mjs` extension (which caused Prettier's Babel parser to throw a `SyntaxError` and discard the file). The sourcemap write path now uses the JSON parser for both `.js.map` and `.mjs.map` files. (`lazyload`, `run`)
|
|
14
|
+
- `lazyload` (Puppeteer): `downloadLoadedJsUtil` now uses `waitUntil: "networkidle0"` with a 10 s timeout on `page.goto()`. Previously the call had no timeout and no error handling, so pages whose `load` event never fires (deferred JS, service workers, some SPA patterns) caused the lazyload step to hang indefinitely. Navigation errors and timeouts are now caught and the URLs collected up to that point are returned normally. (`lazyload`, `run`)
|
|
15
|
+
- `lazyload` (Puppeteer): `browser.close()` in `downloadLoadedJsUtil` is now wrapped in a try/catch; if it hangs, the Chrome process is force-killed via `SIGKILL`. Previously a stuck `browser.close()` caused the process to hang after download was otherwise complete. (`lazyload`, `run`)
|
|
16
|
+
- `lazyload` (Puppeteer): All three Puppeteer-using modules (`downloadLoadedJsUtil`, `next_GetLazyResourcesWebpackJs`, `techDetect/index`) now abort non-http/s requests (e.g. `mailto:`, `data:`, `blob:`, `chrome-extension:`, `tel:`) in the request interceptor instead of calling `request.continue()`. Calling `continue()` on these schemes throws an unhandled error and can trigger OS protocol handlers. (`lazyload`, `run`)
|
|
17
|
+
- `lazyload` (Puppeteer): `downloadLoadedJsUtil` and `next_GetLazyResourcesWebpackJs` now pass `--disable-external-protocol-dialog` to Chrome at launch and install an `evaluateOnNewDocument` guard that overrides `window.open` and suppresses clicks on non-http/s anchors. This provides a three-layer defence (Chrome flag + JS intercept + request interceptor abort) ensuring that non-http protocol links on target pages never invoke OS handlers (mail client, phone, etc.). (`lazyload`, `run`)
|
|
18
|
+
- `lazyload` (Puppeteer): All three Puppeteer-using modules now issue a `Page.setDownloadBehavior({ behavior: "deny" })` CDP command immediately after page creation. This prevents accidental file downloads triggered by download-link clicks or JavaScript during crawl, which could block the browser and fill the output directory with unexpected files. (`lazyload`, `run`)
|
|
19
|
+
- `lazyload` (tech detect): After `waitUntil: "load"` resolves, if no framework URL has been captured in `interceptedUrls` yet, a conditional `page.waitForNavigation({ timeout: 5000 })` is now issued to wait for a second navigation event. This catches sites that serve a JS proof-of-work bot challenge (e.g. Vercel's `challenge.v2.min.js`) that fires its own `load` event before calling `window.location` to redirect to the real app. Previously, Puppeteer exited on the challenge page's `load` event and tech detection returned null (exit 10). On sites with no redirect the navigation wait times out after 5 s and detection continues normally. (`lazyload`, `run`)
|
|
20
|
+
- `lazyload`: When `frameworkDetect` returns null and `downloadLoadedJs` is used as a fallback, the downloaded file URL paths are now scanned for `/_next/`, `/_nuxt/`, and `/_app/immutable/` signatures as a second-chance tech detection pass. Previously, sites that serve their framework app at a non-root `basePath` (e.g. Next.js at `/app` instead of `/`) caused the initial Puppeteer-based detection to miss the framework because the intercepted JS paths didn't match any framework pattern, resulting in exit 10. (`lazyload`, `run`)
|
|
21
|
+
- `lazyload` (next_js): `next_parseLayoutJs` now applies a 1.5 MB per-file size guard — checked from both the `Content-Length` response header and the fetched content body — before passing layout files to the AST parser. Files exceeding the limit are skipped with a yellow warning. Previously, Next.js App Router sites with 50+ nested pages each loading a large `layout.js` caused cumulative AST memory of ~2 GB, exhausting the V8 heap and crashing with SIGSEGV (exit 139). (`lazyload`, `run`)
|
|
22
|
+
- `cs-mast`: `--scat`, `--sinc`, `--all-scat-permutations`, `--perm-output`, and `--perm-concurrency` flags were declared in the CLI but not wired to the underlying function, causing a TypeScript compile error (`TS2554: Expected 5 arguments, but got 10`). The function now accepts all five additional parameters: `--scat`/`--sinc` override the active CS-MAST config, and `--all-scat-permutations` runs all 511 non-empty scat subsets in parallel batches and writes one collision file per subset to `--perm-output`. (`cs-mast`)
|
|
23
|
+
|
|
24
|
+
- `refactor -t react-vite`: vendor chunks (`vendor-react-*.js`, `rolldown-runtime-*.js`) that are absent from `mapped.json` are now automatically located in the downloaded assets directory and injected before the refactor pass. Previously, `mapped.json` typically contained only app chunks — vendor chunks are excluded from mapping because they hold only third-party code. This left `vendorExportMaps` empty, so the `rewriteVendorImports` pass had nothing to match against and vendor import statements like `import { d as t } from './vendor-react-CLFLfR9F.js'` survived into the output, causing the Vite build check to fail with "Could not resolve". The fix uses the existing `findAssetsDir`/`findVendorChunkFiles` helpers (already used by the webpack branch) to discover the assets directory from `// File Source:` headers in chunk code.
|
|
25
|
+
- `lazyload` (nuxt): `nuxt_getFromPageSource` now prints the number of new JS files discovered (delta from the global URL set) instead of the running total. Previously the count included every URL already known from earlier in the session.
|
|
26
|
+
- `lazyload` (vue): Each discovery method in `vue_discoverJsFiles` now prints only the count of URL that are genuinely new — URLs already known from earlier methods are excluded. Previously `fromImports.length`, `fromStringRefs.length`, etc. could include URLs already in the accumulator and over-count.
|
|
27
|
+
- Error messages emitted by `makeReq` (fetch failures, cache errors, timeout notices, firewall detection) now use `progressError`/`progressLog` instead of `console.error`/`console.log`, so they are routed through the active progress bar's logger and no longer clutter the bar line when errors occur during a scan.
|
|
28
|
+
- `refactor` (`react-webpack`, `react-vite`): new `--detect-version` flag. When set, the tool fetches per-version `reliable_signatures.json` files from the `shriyanss/cs-mast-s-dataset` HuggingFace bucket (path: `version/react/<bundler>/<version>/<scat>/reliable_signatures.json`) and matches them against CS-MAST signatures generated from the target bundle's chunks. The best-matching React version is used to set `react` and `react-dom` version pins in the refactored output's `package.json` instead of the default `^18.3.1`. Signatures are cached under `~/.js-recon/refactor/version_sigs_cache/` with a 7-day TTL. Supports all webpack versions (react-0.12 through react-19) and all Vite versions (react-16 through react-19) available in the dataset. (`refactor`)
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- `fingerprint`: output files are now written incrementally — each result is flushed to disk immediately after detection rather than buffered and written at the end. For text, csv, and jsonl formats the result is appended; for json the full array is rewritten. Output files are also created (and csv headers written) before the worker pool starts, so a partial file always exists if the scan is interrupted. (`fingerprint`)
|
|
33
|
+
- CLI: help output is now colorized. Section titles (`Usage:`, `Options:`, `Commands:`) are bold cyan; flag names are yellow; `<required>` argument placeholders are magenta; `[optional]` argument placeholders are cyan; descriptions are dimmed; and `(default: …)` suffixes are dim italic. Applies to every subcommand.
|
|
34
|
+
- `run`: the pipeline now runs an optional `refactor` pass after the report step for React, Vue, Nuxt, and Next.js targets. The bundler (webpack vs vite) is detected automatically using CS-MAST-S signatures sampled from the `shriyanss/cs-mast-s-dataset` HuggingFace bucket — the same bucket and caching layer used by `refactor --remote-collisions`. If the detected match count meets `--cs-mast-tech-detect-threshold` (default `50`), `refactor` is called with the full tech identifier (e.g. `react-webpack`); otherwise the step is silently skipped. Refactored output is written to `refactored/` (single-URL mode) or `<workingDir>/refactored/` (batch mode). Currently only React bundles have bucket entries; Vue, Nuxt, and Next.js gracefully skip until their signatures are added to the bucket. (`run`, `refactor`)
|
|
35
|
+
- `run`: new `--cs-mast-tech-detect-threshold <n>` flag (default `50`). Sets the minimum number of CS-MAST-S signature matches required to consider a bundler detected for the refactor step. Pass `0` to disable refactor entirely. (`run`)
|
|
36
|
+
- `refactor` (`react-vite`, `react-webpack`): new `--remote-collisions <path>` flag. Accepts a HuggingFace bucket path (e.g. `react/vite/large-0.1.8`) and uses it as the signature source instead of the automatic `TECH_TO_BRANCH` mapping. When the path does not exist in the `shriyanss/cs-mast-s-dataset` bucket the tool exits with code 25. The existing caching layer is fully reused — signatures are cached under `~/.js-recon/refactor/signature_cache/` and the file list is cached in `~/.js-recon/refactor/cs-mast-s-list-cache.json`. Feature directories that contain no collision records in the dataset are skipped during intersection rather than collapsing the result to zero.
|
|
37
|
+
- `refactor` (`react-webpack`, `react-vite`): `--detect-version` now uses multiple scat configurations for improved accuracy. Three new flags control the behaviour: `--detect-version-config` (default `dynamic`), `--detect-version-dynamic-threshold` (default `3`), and `--detect-version-dynamic-conf-purge`. In `dynamic` mode the tool automatically selects up to `--detect-version-dynamic-threshold` scat configs that have non-empty reliable signatures across all known React versions, caches the selection in `~/.js-recon/refactor/config.json`, and aggregates match counts across all configs per version for a stronger detection signal. Alternatively, passing comma-separated scat categories (e.g. `lit,decl,loop,cond`) to `--detect-version-config` fixes the config; the tool validates signatures are non-empty for every version and exits with code 26 if not. Use `--detect-version-dynamic-conf-purge` to force recomputation of the cached config.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Set `react/webpack/large-0.1.8` as default cs-mast-s dataset for react + webpack refactoring
|
|
42
|
+
|
|
43
|
+
## 1.4.1-alpha.4 - 2026-06-29
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- `sourcemaps`: new subcommand to extract original source files from `.map` sourcemaps without running the full pipeline. Accepts a single `.map` file or a directory of `.map` files via `-i`/`--input`; writes recovered sources to `-o`/`--output` (default: `extracted`).
|
|
48
|
+
- Homebrew tap distribution: `brew tap shriyanss/tap && brew install js-recon` installs js-recon via the `shriyanss/homebrew-tap` Homebrew tap. The formula (`Formula/js-recon.rb`) auto-updates on every npm publish via the `update-homebrew-tap` CI job in `publish-js-recon.yml`.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- `lazyload`: sourcemap extraction logic moved to the new `sourcemaps` module (`src/sourcemaps/`). Behaviour is identical; `lazyload` now delegates to `extractSourceMaps` from that module rather than containing a private copy.
|
|
53
|
+
|
|
3
54
|
## 1.4.1-alpha.3 - 2026-06-25
|
|
4
55
|
|
|
5
56
|
### Added
|