codebase-onboarder 0.6.0 → 0.7.0
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/README.md +174 -46
- package/bin/build-if-source.js +23 -0
- package/cli/commands.d.ts +26 -0
- package/cli/commands.js +836 -811
- package/cli/commands.js.map +1 -0
- package/cli/explorer/advanced.d.ts +14 -0
- package/cli/explorer/advanced.js +321 -329
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +384 -313
- package/cli/explorer/app.js.map +1 -0
- package/cli/explorer/assistant.d.ts +9 -0
- package/cli/explorer/assistant.js +58 -0
- package/cli/explorer/assistant.js.map +1 -0
- package/cli/explorer/commands.d.ts +17 -0
- package/cli/explorer/commands.js +368 -302
- package/cli/explorer/commands.js.map +1 -0
- package/cli/explorer/featureViews.d.ts +124 -0
- package/cli/explorer/featureViews.js +179 -0
- package/cli/explorer/featureViews.js.map +1 -0
- package/cli/explorer/github.d.ts +21 -0
- package/cli/explorer/github.js +42 -44
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +90 -95
- package/cli/explorer/graphs.js.map +1 -0
- package/cli/explorer/picker.d.ts +22 -0
- package/cli/explorer/picker.js +150 -0
- package/cli/explorer/picker.js.map +1 -0
- package/cli/explorer/report.d.ts +85 -0
- package/cli/explorer/report.js +60 -0
- package/cli/explorer/report.js.map +1 -0
- package/cli/explorer/session.d.ts +449 -0
- package/cli/explorer/session.js +143 -144
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +465 -482
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +28 -44
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +214 -161
- package/cli/main.js.map +1 -0
- package/cli/prompt.d.ts +5 -0
- package/cli/prompt.js +84 -80
- package/cli/prompt.js.map +1 -0
- package/cli/scanOptions.d.ts +2 -0
- package/cli/scanOptions.js +11 -0
- package/cli/scanOptions.js.map +1 -0
- package/cli/ui.d.ts +33 -0
- package/cli/ui.js +35 -44
- package/cli/ui.js.map +1 -0
- package/cli/wizard.d.ts +187 -0
- package/cli/wizard.js +304 -284
- package/cli/wizard.js.map +1 -0
- package/package.json +15 -4
- package/public/app.d.ts +1 -0
- package/public/app.js +1057 -1009
- package/public/app.js.map +1 -0
- package/public/browser.d.ts +68 -0
- package/public/browser.js +2 -0
- package/public/browser.js.map +1 -0
- package/public/index.html +30 -13
- package/public/js/about.d.ts +6 -0
- package/public/js/about.js +152 -172
- package/public/js/about.js.map +1 -0
- package/public/js/aiDraft.d.ts +3 -0
- package/public/js/aiDraft.js +116 -124
- package/public/js/aiDraft.js.map +1 -0
- package/public/js/analysisPanel.d.ts +7 -0
- package/public/js/analysisPanel.js +166 -166
- package/public/js/analysisPanel.js.map +1 -0
- package/public/js/analysisReport.d.ts +38 -0
- package/public/js/analysisReport.js +105 -110
- package/public/js/analysisReport.js.map +1 -0
- package/public/js/api.d.ts +26 -0
- package/public/js/api.js +176 -167
- package/public/js/api.js.map +1 -0
- package/public/js/atlas.d.ts +6 -0
- package/public/js/atlas.js +50 -58
- package/public/js/atlas.js.map +1 -0
- package/public/js/blameView.d.ts +2 -0
- package/public/js/blameView.js +36 -37
- package/public/js/blameView.js.map +1 -0
- package/public/js/codeTab.d.ts +3 -0
- package/public/js/codeTab.js +175 -180
- package/public/js/codeTab.js.map +1 -0
- package/public/js/codeViewer.d.ts +5 -0
- package/public/js/codeViewer.js +162 -150
- package/public/js/codeViewer.js.map +1 -0
- package/public/js/components/FileChip.d.ts +9 -0
- package/public/js/components/FileChip.js +45 -49
- package/public/js/components/FileChip.js.map +1 -0
- package/public/js/components/MetricSparkline.d.ts +7 -0
- package/public/js/components/MetricSparkline.js +35 -44
- package/public/js/components/MetricSparkline.js.map +1 -0
- package/public/js/components/RiskBadge.d.ts +9 -0
- package/public/js/components/RiskBadge.js +55 -63
- package/public/js/components/RiskBadge.js.map +1 -0
- package/public/js/deepAnalysisView.d.ts +99 -0
- package/public/js/deepAnalysisView.js +282 -302
- package/public/js/deepAnalysisView.js.map +1 -0
- package/public/js/diagramPane.d.ts +8 -0
- package/public/js/diagramPane.js +133 -135
- package/public/js/diagramPane.js.map +1 -0
- package/public/js/diffView.d.ts +6 -0
- package/public/js/diffView.js +222 -209
- package/public/js/diffView.js.map +1 -0
- package/public/js/docsView.d.ts +2 -0
- package/public/js/docsView.js +441 -442
- package/public/js/docsView.js.map +1 -0
- package/public/js/dom.d.ts +189 -0
- package/public/js/dom.js +5 -0
- package/public/js/dom.js.map +1 -0
- package/public/js/fileSourceBrowser.d.ts +5 -0
- package/public/js/fileSourceBrowser.js +33 -41
- package/public/js/fileSourceBrowser.js.map +1 -0
- package/public/js/flameGraph.d.ts +5 -0
- package/public/js/flameGraph.js +62 -72
- package/public/js/flameGraph.js.map +1 -0
- package/public/js/forceGraph.d.ts +10 -0
- package/public/js/forceGraph.js +581 -556
- package/public/js/forceGraph.js.map +1 -0
- package/public/js/heatmap.d.ts +4 -0
- package/public/js/heatmap.js +142 -164
- package/public/js/heatmap.js.map +1 -0
- package/public/js/highlight.d.ts +2 -0
- package/public/js/highlight.js +116 -107
- package/public/js/highlight.js.map +1 -0
- package/public/js/html.d.ts +2 -0
- package/public/js/html.js +14 -44
- package/public/js/html.js.map +1 -0
- package/public/js/insightsView.d.ts +5 -0
- package/public/js/insightsView.js +93 -111
- package/public/js/insightsView.js.map +1 -0
- package/public/js/inspector.d.ts +37 -0
- package/public/js/inspector.js +416 -445
- package/public/js/inspector.js.map +1 -0
- package/public/js/llm.d.ts +113 -0
- package/public/js/llm.js +233 -272
- package/public/js/llm.js.map +1 -0
- package/public/js/mapView.d.ts +3 -0
- package/public/js/mapView.js +121 -120
- package/public/js/mapView.js.map +1 -0
- package/public/js/markdown.d.ts +3 -0
- package/public/js/markdown.js +84 -91
- package/public/js/markdown.js.map +1 -0
- package/public/js/mindmap.d.ts +32 -0
- package/public/js/mindmap.js +244 -259
- package/public/js/mindmap.js.map +1 -0
- package/public/js/mobilePanels.d.ts +5 -0
- package/public/js/mobilePanels.js +50 -0
- package/public/js/mobilePanels.js.map +1 -0
- package/public/js/repoFiles.d.ts +12 -0
- package/public/js/repoFiles.js +28 -27
- package/public/js/repoFiles.js.map +1 -0
- package/public/js/reviewView.d.ts +28 -0
- package/public/js/reviewView.js +256 -0
- package/public/js/reviewView.js.map +1 -0
- package/public/js/sbomView.d.ts +3 -0
- package/public/js/sbomView.js +59 -67
- package/public/js/sbomView.js.map +1 -0
- package/public/js/scanCache.d.ts +16 -0
- package/public/js/scanCache.js +67 -65
- package/public/js/scanCache.js.map +1 -0
- package/public/js/search.d.ts +7 -0
- package/public/js/search.js +868 -800
- package/public/js/search.js.map +1 -0
- package/public/js/searchLocal.d.ts +42 -0
- package/public/js/searchLocal.js +87 -0
- package/public/js/searchLocal.js.map +1 -0
- package/public/js/serverSettings.d.ts +5 -0
- package/public/js/serverSettings.js +153 -164
- package/public/js/serverSettings.js.map +1 -0
- package/public/js/state.d.ts +798 -0
- package/public/js/state.js +114 -122
- package/public/js/state.js.map +1 -0
- package/public/js/tour.d.ts +6 -0
- package/public/js/tour.js +5 -7
- package/public/js/tour.js.map +1 -0
- package/public/js/transitions.d.ts +2 -0
- package/public/js/transitions.js +9 -10
- package/public/js/transitions.js.map +1 -0
- package/public/js/tree.d.ts +12 -0
- package/public/js/tree.js +157 -154
- package/public/js/tree.js.map +1 -0
- package/public/js/workflowsView.d.ts +3 -0
- package/public/js/workflowsView.js +15 -22
- package/public/js/workflowsView.js.map +1 -0
- package/public/search.css +495 -0
- package/public/styles.css +163 -346
- package/public/workbench.css +166 -0
- package/server/apiAuth.d.ts +3 -0
- package/server/apiAuth.js +18 -20
- package/server/apiAuth.js.map +1 -0
- package/server/apiDiff.d.ts +2 -0
- package/server/apiDiff.js +20 -18
- package/server/apiDiff.js.map +1 -0
- package/server/apiDocs.d.ts +2 -0
- package/server/apiDocs.js +38 -40
- package/server/apiDocs.js.map +1 -0
- package/server/apiFile.d.ts +1 -0
- package/server/apiFile.js +14 -17
- package/server/apiFile.js.map +1 -0
- package/server/apiGitBlame.d.ts +2 -0
- package/server/apiGitBlame.js +50 -51
- package/server/apiGitBlame.js.map +1 -0
- package/server/apiMcp.d.ts +4 -0
- package/server/apiMcp.js +64 -66
- package/server/apiMcp.js.map +1 -0
- package/server/apiReview.d.ts +2 -0
- package/server/apiReview.js +45 -0
- package/server/apiReview.js.map +1 -0
- package/server/apiScan.d.ts +5 -0
- package/server/apiScan.js +90 -71
- package/server/apiScan.js.map +1 -0
- package/server/apiSearch.d.ts +33 -0
- package/server/apiSearch.js +184 -200
- package/server/apiSearch.js.map +1 -0
- package/server/apiSettings.d.ts +4 -0
- package/server/apiSettings.js +84 -85
- package/server/apiSettings.js.map +1 -0
- package/server/apiTools.d.ts +3 -0
- package/server/apiTools.js +55 -56
- package/server/apiTools.js.map +1 -0
- package/server/auth.d.ts +5 -0
- package/server/auth.js +54 -51
- package/server/auth.js.map +1 -0
- package/server/config.d.ts +42 -0
- package/server/config.js +189 -194
- package/server/config.js.map +1 -0
- package/server/daemon.d.ts +12 -0
- package/server/daemon.js +124 -114
- package/server/daemon.js.map +1 -0
- package/server/fileSourceNode.d.ts +2 -0
- package/server/fileSourceNode.js +34 -36
- package/server/fileSourceNode.js.map +1 -0
- package/server/gitClone.d.ts +9 -0
- package/server/gitClone.js +59 -61
- package/server/gitClone.js.map +1 -0
- package/server/gitDiff.d.ts +36 -0
- package/server/gitDiff.js +271 -169
- package/server/gitDiff.js.map +1 -0
- package/server/gitHistory.d.ts +12 -0
- package/server/gitHistory.js +80 -80
- package/server/gitHistory.js.map +1 -0
- package/server/gitRemote.d.ts +12 -0
- package/server/gitRemote.js +37 -38
- package/server/gitRemote.js.map +1 -0
- package/server/htmlText.d.ts +4 -0
- package/server/htmlText.js +16 -23
- package/server/htmlText.js.map +1 -0
- package/server/http.d.ts +5 -0
- package/server/http.js +27 -30
- package/server/http.js.map +1 -0
- package/server/httpGuards.d.ts +2 -0
- package/server/httpGuards.js +47 -43
- package/server/httpGuards.js.map +1 -0
- package/server/https.d.ts +34 -0
- package/server/https.js +121 -111
- package/server/https.js.map +1 -0
- package/server/index.d.ts +40 -0
- package/server/index.js +139 -147
- package/server/index.js.map +1 -0
- package/server/layout.d.ts +26 -0
- package/server/layout.js +59 -64
- package/server/layout.js.map +1 -0
- package/server/llmProxy.d.ts +3 -0
- package/server/llmProxy.js +137 -135
- package/server/llmProxy.js.map +1 -0
- package/server/logger.d.ts +38 -0
- package/server/logger.js +198 -211
- package/server/logger.js.map +1 -0
- package/server/mcp/analysis.d.ts +29 -0
- package/server/mcp/analysis.js +99 -120
- package/server/mcp/analysis.js.map +1 -0
- package/server/mcp/http.d.ts +9 -0
- package/server/mcp/http.js +128 -137
- package/server/mcp/http.js.map +1 -0
- package/server/mcp/runner.d.ts +68 -0
- package/server/mcp/runner.js +208 -218
- package/server/mcp/runner.js.map +1 -0
- package/server/mcp/server.d.ts +29 -0
- package/server/mcp/server.js +166 -179
- package/server/mcp/server.js.map +1 -0
- package/server/mcp/standalone.d.ts +1 -0
- package/server/mcp/standalone.js +8 -10
- package/server/mcp/standalone.js.map +1 -0
- package/server/mcp/tools.d.ts +2020 -0
- package/server/mcp/tools.js +523 -574
- package/server/mcp/tools.js.map +1 -0
- package/server/paths.d.ts +3 -0
- package/server/paths.js +17 -15
- package/server/paths.js.map +1 -0
- package/server/pidfile.d.ts +9 -0
- package/server/pidfile.js +43 -45
- package/server/pidfile.js.map +1 -0
- package/server/review.d.ts +5 -0
- package/server/review.js +35 -0
- package/server/review.js.map +1 -0
- package/server/router.d.ts +33 -0
- package/server/router.js +191 -197
- package/server/router.js.map +1 -0
- package/server/scanRequest.d.ts +3 -0
- package/server/scanRequest.js +36 -0
- package/server/scanRequest.js.map +1 -0
- package/server/searchIndex.d.ts +17 -0
- package/server/searchIndex.js +83 -80
- package/server/searchIndex.js.map +1 -0
- package/server/sessions.d.ts +14 -0
- package/server/sessions.js +62 -70
- package/server/sessions.js.map +1 -0
- package/server/startup.d.ts +118 -0
- package/server/startup.js +143 -148
- package/server/startup.js.map +1 -0
- package/server/static.d.ts +6 -0
- package/server/static.js +28 -31
- package/server/static.js.map +1 -0
- package/server/tools/install.d.ts +4 -0
- package/server/tools/install.js +176 -185
- package/server/tools/install.js.map +1 -0
- package/server/tools/parse.d.ts +8 -0
- package/server/tools/parse.js +112 -114
- package/server/tools/parse.js.map +1 -0
- package/server/tools/platform.d.ts +9 -0
- package/server/tools/platform.js +49 -47
- package/server/tools/platform.js.map +1 -0
- package/server/tools/registry.d.ts +137 -0
- package/server/tools/registry.js +173 -172
- package/server/tools/registry.js.map +1 -0
- package/server/tools/scan.d.ts +34 -0
- package/server/tools/scan.js +89 -98
- package/server/tools/scan.js.map +1 -0
- package/server/tools.d.ts +34 -0
- package/server/tools.js +94 -107
- package/server/tools.js.map +1 -0
- package/server/tunnel.d.ts +29 -0
- package/server/tunnel.js +61 -66
- package/server/tunnel.js.map +1 -0
- package/shared/analyzer/docs.d.ts +16 -0
- package/shared/analyzer/docs.js +99 -93
- package/shared/analyzer/docs.js.map +1 -0
- package/shared/analyzer/explainLocal.d.ts +4 -0
- package/shared/analyzer/explainLocal.js +122 -142
- package/shared/analyzer/explainLocal.js.map +1 -0
- package/shared/analyzer/github.d.ts +37 -0
- package/shared/analyzer/github.js +41 -43
- package/shared/analyzer/github.js.map +1 -0
- package/shared/analyzer/graph.d.ts +41 -0
- package/shared/analyzer/graph.js +393 -400
- package/shared/analyzer/graph.js.map +1 -0
- package/shared/analyzer/health.d.ts +33 -0
- package/shared/analyzer/health.js +197 -193
- package/shared/analyzer/health.js.map +1 -0
- package/shared/analyzer/history.d.ts +29 -0
- package/shared/analyzer/history.js +110 -111
- package/shared/analyzer/history.js.map +1 -0
- package/shared/analyzer/jsonConfig.d.ts +2 -0
- package/shared/analyzer/jsonConfig.js +61 -0
- package/shared/analyzer/jsonConfig.js.map +1 -0
- package/shared/analyzer/languages/csharp.d.ts +26 -0
- package/shared/analyzer/languages/csharp.js +83 -88
- package/shared/analyzer/languages/csharp.js.map +1 -0
- package/shared/analyzer/languages/generic.d.ts +23 -0
- package/shared/analyzer/languages/generic.js +94 -105
- package/shared/analyzer/languages/generic.js.map +1 -0
- package/shared/analyzer/languages/go.d.ts +24 -0
- package/shared/analyzer/languages/go.js +45 -54
- package/shared/analyzer/languages/go.js.map +1 -0
- package/shared/analyzer/languages/index.d.ts +6 -0
- package/shared/analyzer/languages/index.js +19 -20
- package/shared/analyzer/languages/index.js.map +1 -0
- package/shared/analyzer/languages/java.d.ts +20 -0
- package/shared/analyzer/languages/java.js +73 -78
- package/shared/analyzer/languages/java.js.map +1 -0
- package/shared/analyzer/languages/javascript.d.ts +12 -0
- package/shared/analyzer/languages/javascript.js +258 -209
- package/shared/analyzer/languages/javascript.js.map +1 -0
- package/shared/analyzer/languages/python.d.ts +23 -0
- package/shared/analyzer/languages/python.js +92 -100
- package/shared/analyzer/languages/python.js.map +1 -0
- package/shared/analyzer/languages/rust.d.ts +17 -0
- package/shared/analyzer/languages/rust.js +96 -98
- package/shared/analyzer/languages/rust.js.map +1 -0
- package/shared/analyzer/languages/typescript.d.ts +11 -0
- package/shared/analyzer/languages/typescript.js +117 -116
- package/shared/analyzer/languages/typescript.js.map +1 -0
- package/shared/analyzer/licenses.d.ts +18 -0
- package/shared/analyzer/licenses.js +130 -133
- package/shared/analyzer/licenses.js.map +1 -0
- package/shared/analyzer/metrics.d.ts +20 -0
- package/shared/analyzer/metrics.js +112 -104
- package/shared/analyzer/metrics.js.map +1 -0
- package/shared/analyzer/pathUtil.d.ts +10 -0
- package/shared/analyzer/pathUtil.js +29 -35
- package/shared/analyzer/pathUtil.js.map +1 -0
- package/shared/analyzer/patterns.d.ts +11 -0
- package/shared/analyzer/patterns.js +231 -253
- package/shared/analyzer/patterns.js.map +1 -0
- package/shared/analyzer/scan.d.ts +62 -0
- package/shared/analyzer/scan.js +451 -442
- package/shared/analyzer/scan.js.map +1 -0
- package/shared/analyzer/scanControl.d.ts +11 -0
- package/shared/analyzer/scanControl.js +62 -0
- package/shared/analyzer/scanControl.js.map +1 -0
- package/shared/analyzer/security.d.ts +18 -0
- package/shared/analyzer/security.js +159 -159
- package/shared/analyzer/security.js.map +1 -0
- package/shared/analyzer/services.d.ts +5 -0
- package/shared/analyzer/services.js +141 -138
- package/shared/analyzer/services.js.map +1 -0
- package/shared/analyzer/stack.d.ts +6 -0
- package/shared/analyzer/stack.js +134 -141
- package/shared/analyzer/stack.js.map +1 -0
- package/shared/analyzer/tour.d.ts +2 -0
- package/shared/analyzer/tour.js +45 -53
- package/shared/analyzer/tour.js.map +1 -0
- package/shared/analyzer/util.d.ts +8 -0
- package/shared/analyzer/util.js +130 -76
- package/shared/analyzer/util.js.map +1 -0
- package/shared/analyzer/workflows.d.ts +8 -0
- package/shared/analyzer/workflows.js +139 -134
- package/shared/analyzer/workflows.js.map +1 -0
- package/shared/contracts.d.ts +250 -0
- package/shared/contracts.js +2 -0
- package/shared/contracts.js.map +1 -0
- package/shared/diagram/aiFacts.d.ts +35 -0
- package/shared/diagram/aiFacts.js +102 -105
- package/shared/diagram/aiFacts.js.map +1 -0
- package/shared/diagram/aiMermaid.d.ts +5 -0
- package/shared/diagram/aiMermaid.js +46 -45
- package/shared/diagram/aiMermaid.js.map +1 -0
- package/shared/diagram/atlas.d.ts +16 -0
- package/shared/diagram/atlas.js +51 -60
- package/shared/diagram/atlas.js.map +1 -0
- package/shared/diagram/mermaid.d.ts +43 -0
- package/shared/diagram/mermaid.js +348 -370
- package/shared/diagram/mermaid.js.map +1 -0
- package/shared/review/contracts.d.ts +95 -0
- package/shared/review/contracts.js +2 -0
- package/shared/review/contracts.js.map +1 -0
- package/shared/review/review.d.ts +10 -0
- package/shared/review/review.js +184 -0
- package/shared/review/review.js.map +1 -0
- package/shared/search/query.d.ts +32 -0
- package/shared/search/query.js +395 -388
- package/shared/search/query.js.map +1 -0
package/server/apiSearch.js
CHANGED
|
@@ -16,238 +16,222 @@
|
|
|
16
16
|
// palette uses) and enforces anything the person actually decided: filters,
|
|
17
17
|
// phrases, regexes, the case toggle. A half-remembered name should still find
|
|
18
18
|
// the file; `ext:js -vendor` should not be negotiated with.
|
|
19
|
-
|
|
20
19
|
import { getSession } from './sessions.js';
|
|
21
20
|
import { sendError, sendJSON } from './http.js';
|
|
22
|
-
import {
|
|
23
|
-
isAdvanced, lineOfIndex, matchesPathFilters, parseQuery, queryIsEmpty,
|
|
24
|
-
scoreContent, scorePath, snippetAt,
|
|
25
|
-
} from '../shared/search/query.js';
|
|
26
|
-
|
|
21
|
+
import { isAdvanced, lineOfIndex, matchesPathFilters, parseQuery, queryIsEmpty, scoreContent, scorePath, snippetAt, } from '../shared/search/query.js';
|
|
27
22
|
export function buildTfIdfIndex(documents) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
23
|
+
// documents: [{ path, content }]
|
|
24
|
+
const index = new Map();
|
|
25
|
+
const docCounts = new Map();
|
|
26
|
+
let totalDocs = 0;
|
|
27
|
+
for (const doc of documents) {
|
|
28
|
+
if (!doc.content || typeof doc.content !== 'string')
|
|
29
|
+
continue;
|
|
30
|
+
const tokens = doc.content.toLowerCase().split(/\W+/).filter((t) => t.length > 1);
|
|
31
|
+
if (!tokens.length)
|
|
32
|
+
continue;
|
|
33
|
+
totalDocs++;
|
|
34
|
+
const tf = new Map();
|
|
35
|
+
for (const t of tokens) {
|
|
36
|
+
tf.set(t, (tf.get(t) || 0) + 1);
|
|
37
|
+
}
|
|
38
|
+
for (const t of tf.keys()) {
|
|
39
|
+
docCounts.set(t, (docCounts.get(t) || 0) + 1);
|
|
40
|
+
}
|
|
41
|
+
index.set(doc.path, { tf, content: doc.content, tokenCount: tokens.length });
|
|
45
42
|
}
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return { index, docCounts, totalDocs };
|
|
43
|
+
return { index, docCounts, totalDocs };
|
|
50
44
|
}
|
|
51
|
-
|
|
52
45
|
export function searchIndex(indexData, queryString, limit = 10) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const df = docCounts.get(t) || 0;
|
|
63
|
-
idf.set(t, df === 0 ? 0 : Math.log(1 + totalDocs / df));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const results = [];
|
|
67
|
-
for (const [docPath, data] of index.entries()) {
|
|
68
|
-
let score = 0;
|
|
69
|
-
let matchCount = 0;
|
|
46
|
+
if (!indexData || !queryString)
|
|
47
|
+
return [];
|
|
48
|
+
const terms = queryString.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
|
|
49
|
+
if (!terms.length)
|
|
50
|
+
return [];
|
|
51
|
+
const { index, docCounts, totalDocs } = indexData;
|
|
52
|
+
if (!totalDocs)
|
|
53
|
+
return [];
|
|
54
|
+
const idf = new Map();
|
|
70
55
|
for (const t of terms) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
matchCount++;
|
|
74
|
-
// Normalized TF * IDF
|
|
75
|
-
score += (tf / Math.sqrt(data.tokenCount)) * (idf.get(t) || 1);
|
|
76
|
-
}
|
|
56
|
+
const df = docCounts.get(t) || 0;
|
|
57
|
+
idf.set(t, df === 0 ? 0 : Math.log(1 + totalDocs / df));
|
|
77
58
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const [docPath, data] of index.entries()) {
|
|
61
|
+
let score = 0;
|
|
62
|
+
let matchCount = 0;
|
|
63
|
+
for (const t of terms) {
|
|
64
|
+
const tf = data.tf.get(t) || 0;
|
|
65
|
+
if (tf > 0) {
|
|
66
|
+
matchCount++;
|
|
67
|
+
// Normalized TF * IDF
|
|
68
|
+
score += (tf / Math.sqrt(data.tokenCount)) * (idf.get(t) || 1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (score > 0) {
|
|
72
|
+
// Find best snippet
|
|
73
|
+
const lowerContent = data.content.toLowerCase();
|
|
74
|
+
let bestIdx = -1;
|
|
75
|
+
for (const t of terms) {
|
|
76
|
+
const idx = lowerContent.indexOf(t);
|
|
77
|
+
if (idx !== -1 && (bestIdx === -1 || idx < bestIdx)) {
|
|
78
|
+
bestIdx = idx;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
let snippet = '';
|
|
82
|
+
let line = 1;
|
|
83
|
+
if (bestIdx !== -1) {
|
|
84
|
+
const linesBefore = data.content.slice(0, bestIdx).split('\n');
|
|
85
|
+
line = linesBefore.length;
|
|
86
|
+
const allLines = data.content.split('\n');
|
|
87
|
+
const targetLine = (allLines[line - 1] || '').trim();
|
|
88
|
+
snippet = targetLine.length > 120 ? targetLine.slice(0, 117) + '…' : targetLine;
|
|
89
|
+
}
|
|
90
|
+
results.push({
|
|
91
|
+
path: docPath,
|
|
92
|
+
score: score * (matchCount / terms.length), // Boost docs containing all terms
|
|
93
|
+
snippet,
|
|
94
|
+
line,
|
|
95
|
+
});
|
|
87
96
|
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let snippet = '';
|
|
91
|
-
let line = 1;
|
|
92
|
-
if (bestIdx !== -1) {
|
|
93
|
-
const linesBefore = data.content.slice(0, bestIdx).split('\n');
|
|
94
|
-
line = linesBefore.length;
|
|
95
|
-
const allLines = data.content.split('\n');
|
|
96
|
-
const targetLine = (allLines[line - 1] || '').trim();
|
|
97
|
-
snippet = targetLine.length > 120 ? targetLine.slice(0, 117) + '…' : targetLine;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
results.push({
|
|
101
|
-
path: docPath,
|
|
102
|
-
score: score * (matchCount / terms.length), // Boost docs containing all terms
|
|
103
|
-
snippet,
|
|
104
|
-
line,
|
|
105
|
-
});
|
|
106
97
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
results.sort((a, b) => b.score - a.score);
|
|
110
|
-
return results.slice(0, limit);
|
|
98
|
+
results.sort((a, b) => b.score - a.score);
|
|
99
|
+
return results.slice(0, limit);
|
|
111
100
|
}
|
|
112
|
-
|
|
113
101
|
// The strict pass: filters are gates, not hints, and every term has to land.
|
|
114
102
|
// Ranking is positional — `scorePath` and `scoreContent` reward the file whose
|
|
115
103
|
// name matches and the file where the word appears early — because a query with
|
|
116
104
|
// a regex or a filter in it is a person who knows what they want, and does not
|
|
117
105
|
// need the corpus statistics of `searchIndex` second-guessing them.
|
|
118
106
|
function strictSearch(indexData, parsed) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return results;
|
|
107
|
+
// `kind:` is a statement about symbols, and content cannot answer it. A query
|
|
108
|
+
// that is *only* a kind filter is answered by the palette's symbol pass and
|
|
109
|
+
// by nothing here, which is the honest result rather than "every file".
|
|
110
|
+
const kindOnly = parsed.kinds.length > 0
|
|
111
|
+
&& !parsed.terms.length && !parsed.phrases.length && !parsed.regex;
|
|
112
|
+
const results = [];
|
|
113
|
+
for (const [docPath, doc] of indexData.index.entries()) {
|
|
114
|
+
if (kindOnly)
|
|
115
|
+
break;
|
|
116
|
+
if (!matchesPathFilters(parsed, docPath))
|
|
117
|
+
continue;
|
|
118
|
+
const pathScore = scorePath(parsed, docPath);
|
|
119
|
+
const content = scoreContent(parsed, doc.content);
|
|
120
|
+
if (!pathScore && !content.score)
|
|
121
|
+
continue;
|
|
122
|
+
const at = content.index;
|
|
123
|
+
results.push({
|
|
124
|
+
path: docPath,
|
|
125
|
+
score: pathScore + content.score,
|
|
126
|
+
line: at >= 0 ? lineOfIndex(doc.content, at) : 1,
|
|
127
|
+
snippet: snippetAt(doc.content, at >= 0 ? at : 0),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
results.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
|
|
131
|
+
return results;
|
|
145
132
|
}
|
|
146
|
-
|
|
147
133
|
// What the index could not read, in the shape the palette can say out loud —
|
|
148
134
|
// "searched 127 files, 3 skipped" beats a mystery file that never turns up.
|
|
149
135
|
function indexStats(indexData) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
136
|
+
const skipped = indexData && indexData.skipped;
|
|
137
|
+
if (!skipped)
|
|
138
|
+
return null;
|
|
139
|
+
return { bytes: indexData.totalBytes ?? 0, skipped: { ...skipped }, cap: indexData.cap ?? null };
|
|
153
140
|
}
|
|
154
|
-
|
|
155
141
|
// The serializable half of a parsed query. `parsed.regex` is a RegExp and would
|
|
156
142
|
// go over the wire as `{}`, so the pattern travels as the text it was typed as.
|
|
157
143
|
function querySummary(parsed) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
144
|
+
return {
|
|
145
|
+
terms: parsed.terms,
|
|
146
|
+
phrases: parsed.phrases,
|
|
147
|
+
negatives: parsed.negatives,
|
|
148
|
+
exts: parsed.exts,
|
|
149
|
+
paths: parsed.paths,
|
|
150
|
+
kinds: parsed.kinds,
|
|
151
|
+
isTest: parsed.isTest,
|
|
152
|
+
isSource: parsed.isSource,
|
|
153
|
+
regex: parsed.regexSource ? `/${parsed.regexSource}/${parsed.regexFlags}` : null,
|
|
154
|
+
caseSensitive: parsed.caseSensitive,
|
|
155
|
+
advanced: isAdvanced(parsed),
|
|
156
|
+
};
|
|
171
157
|
}
|
|
172
|
-
|
|
173
158
|
// The one entry point the route uses, kept separate from `searchIndex` so the
|
|
174
159
|
// forgiving ranking that shipped first survives intact: a query of bare words
|
|
175
160
|
// is still answered by that function, partial matches and all. Only a query the
|
|
176
161
|
// person made decisions in — a filter, a phrase, a regex, the case toggle —
|
|
177
162
|
// goes down the strict path, where those decisions are enforced.
|
|
178
163
|
export function searchDocuments(indexData, rawQuery, options = {}) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
164
|
+
const limit = Number.isFinite(options.limit) ? Math.max(1, Math.floor(options.limit)) : 15;
|
|
165
|
+
const parsed = parseQuery(rawQuery, { caseSensitive: !!options.caseSensitive });
|
|
166
|
+
const advanced = isAdvanced(parsed);
|
|
167
|
+
const base = {
|
|
168
|
+
results: [],
|
|
169
|
+
total: 0,
|
|
170
|
+
indexed: indexData?.totalDocs ?? 0,
|
|
171
|
+
capped: false,
|
|
172
|
+
advanced,
|
|
173
|
+
query: querySummary(parsed),
|
|
174
|
+
error: parsed.error,
|
|
175
|
+
stats: indexStats(indexData),
|
|
176
|
+
};
|
|
177
|
+
if (!indexData || !indexData.totalDocs)
|
|
178
|
+
return base;
|
|
179
|
+
if (queryIsEmpty(parsed))
|
|
180
|
+
return base;
|
|
181
|
+
// A pattern that would not compile is the whole answer. Reporting "no
|
|
182
|
+
// results" instead would send someone hunting for a file sitting right there.
|
|
183
|
+
if (parsed.error)
|
|
184
|
+
return base;
|
|
185
|
+
if (!advanced) {
|
|
186
|
+
const ranked = searchIndex(indexData, parsed.terms.join(' '), limit);
|
|
187
|
+
return { ...base, results: ranked, total: ranked.length, capped: ranked.length >= limit };
|
|
188
|
+
}
|
|
189
|
+
const all = strictSearch(indexData, parsed);
|
|
190
|
+
return {
|
|
191
|
+
...base,
|
|
192
|
+
results: all.slice(0, limit),
|
|
193
|
+
total: all.length,
|
|
194
|
+
capped: all.length > limit,
|
|
195
|
+
};
|
|
211
196
|
}
|
|
212
|
-
|
|
213
197
|
export async function handleSearch(res, body) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
198
|
+
const { scanId, query, limit = 15, caseSensitive = false } = body || {};
|
|
199
|
+
if (!scanId)
|
|
200
|
+
return sendError(res, 400, 'Missing scanId.');
|
|
201
|
+
const session = getSession(scanId);
|
|
202
|
+
if (!session)
|
|
203
|
+
return sendError(res, 404, 'Scan not found.');
|
|
204
|
+
const q = (query || '').trim();
|
|
205
|
+
if (!q) {
|
|
206
|
+
return sendJSON(res, 200, { results: [], total: 0, indexed: session.searchIndex?.totalDocs ?? 0 });
|
|
207
|
+
}
|
|
208
|
+
// No index means the scan was opened before this change shipped, or the
|
|
209
|
+
// caller is using a session that was never given a scan-time index. The
|
|
210
|
+
// honest answer is "no results" rather than rebuilding the whole thing on
|
|
211
|
+
// the request thread.
|
|
212
|
+
if (!session.searchIndex || session.searchIndex.totalDocs === 0) {
|
|
213
|
+
return sendJSON(res, 200, {
|
|
214
|
+
results: [],
|
|
215
|
+
total: 0,
|
|
216
|
+
indexed: 0,
|
|
217
|
+
note: 'Nothing was indexed for this scan.',
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
const out = searchDocuments(session.searchIndex, q, { limit, caseSensitive });
|
|
222
|
+
return sendJSON(res, 200, {
|
|
223
|
+
results: out.results,
|
|
224
|
+
total: out.total,
|
|
225
|
+
indexed: out.indexed,
|
|
226
|
+
capped: out.capped,
|
|
227
|
+
advanced: out.advanced,
|
|
228
|
+
query: out.query,
|
|
229
|
+
error: out.error || null,
|
|
230
|
+
stats: out.stats || null,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
return sendError(res, 500, 'Search failed: ' + err.message);
|
|
235
|
+
}
|
|
252
236
|
}
|
|
253
|
-
|
|
237
|
+
//# sourceMappingURL=apiSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiSearch.js","sourceRoot":"","sources":["../src/server/apiSearch.ts"],"names":[],"mappings":"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","sourcesContent":["// POST /api/search — runs a TF-IDF query against the index built at scan\n// time. The work that used to live here (re-listing the tree, re-reading\n// every file, parsing its tokens) now lives in `searchIndex.js`, which\n// `apiScan.js` invokes once when the scan finishes. What is left in this\n// module is the request shape: validate, look up the session, score, send.\n//\n// The pure scoring functions (`buildTfIdfIndex` for one-off in-memory\n// indexes used by tests, and `searchIndex` for the score-and-snippet pass)\n// are still exported so the front end and tests can construct indexes\n// directly when they need to.\n//\n// There are two ways through, and which one a query takes is the point:\n// `searchIndex` answers a query of bare words the forgiving way it always\n// did — partial matches, ranked by TF-IDF — while `searchDocuments` parses\n// the shared query language (`shared/search/query.js`, the same module the\n// palette uses) and enforces anything the person actually decided: filters,\n// phrases, regexes, the case toggle. A half-remembered name should still find\n// the file; `ext:js -vendor` should not be negotiated with.\n\nimport { getSession } from './sessions.js';\nimport { sendError, sendJSON } from './http.js';\nimport {\n isAdvanced, lineOfIndex, matchesPathFilters, parseQuery, queryIsEmpty,\n scoreContent, scorePath, snippetAt,\n} from '../shared/search/query.js';\n\nexport function buildTfIdfIndex(documents) {\n // documents: [{ path, content }]\n const index = new Map();\n const docCounts = new Map();\n let totalDocs = 0;\n\n for (const doc of documents) {\n if (!doc.content || typeof doc.content !== 'string') continue;\n const tokens = doc.content.toLowerCase().split(/\\W+/).filter((t) => t.length > 1);\n if (!tokens.length) continue;\n totalDocs++;\n\n const tf = new Map();\n for (const t of tokens) {\n tf.set(t, (tf.get(t) || 0) + 1);\n }\n for (const t of tf.keys()) {\n docCounts.set(t, (docCounts.get(t) || 0) + 1);\n }\n index.set(doc.path, { tf, content: doc.content, tokenCount: tokens.length });\n }\n\n return { index, docCounts, totalDocs };\n}\n\nexport function searchIndex(indexData, queryString, limit = 10) {\n if (!indexData || !queryString) return [];\n const terms = queryString.toLowerCase().split(/\\s+/).filter((t) => t.length > 0);\n if (!terms.length) return [];\n\n const { index, docCounts, totalDocs } = indexData;\n if (!totalDocs) return [];\n\n const idf = new Map();\n for (const t of terms) {\n const df = docCounts.get(t) || 0;\n idf.set(t, df === 0 ? 0 : Math.log(1 + totalDocs / df));\n }\n\n const results = [];\n for (const [docPath, data] of index.entries()) {\n let score = 0;\n let matchCount = 0;\n for (const t of terms) {\n const tf = data.tf.get(t) || 0;\n if (tf > 0) {\n matchCount++;\n // Normalized TF * IDF\n score += (tf / Math.sqrt(data.tokenCount)) * (idf.get(t) || 1);\n }\n }\n\n if (score > 0) {\n // Find best snippet\n const lowerContent = data.content.toLowerCase();\n let bestIdx = -1;\n for (const t of terms) {\n const idx = lowerContent.indexOf(t);\n if (idx !== -1 && (bestIdx === -1 || idx < bestIdx)) {\n bestIdx = idx;\n }\n }\n\n let snippet = '';\n let line = 1;\n if (bestIdx !== -1) {\n const linesBefore = data.content.slice(0, bestIdx).split('\\n');\n line = linesBefore.length;\n const allLines = data.content.split('\\n');\n const targetLine = (allLines[line - 1] || '').trim();\n snippet = targetLine.length > 120 ? targetLine.slice(0, 117) + '…' : targetLine;\n }\n\n results.push({\n path: docPath,\n score: score * (matchCount / terms.length), // Boost docs containing all terms\n snippet,\n line,\n });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n}\n\n// The strict pass: filters are gates, not hints, and every term has to land.\n// Ranking is positional — `scorePath` and `scoreContent` reward the file whose\n// name matches and the file where the word appears early — because a query with\n// a regex or a filter in it is a person who knows what they want, and does not\n// need the corpus statistics of `searchIndex` second-guessing them.\nfunction strictSearch(indexData, parsed) {\n // `kind:` is a statement about symbols, and content cannot answer it. A query\n // that is *only* a kind filter is answered by the palette's symbol pass and\n // by nothing here, which is the honest result rather than \"every file\".\n const kindOnly = parsed.kinds.length > 0\n && !parsed.terms.length && !parsed.phrases.length && !parsed.regex;\n\n const results = [];\n for (const [docPath, doc] of indexData.index.entries()) {\n if (kindOnly) break;\n if (!matchesPathFilters(parsed, docPath)) continue;\n\n const pathScore = scorePath(parsed, docPath);\n const content = scoreContent(parsed, doc.content);\n if (!pathScore && !content.score) continue;\n\n const at = content.index;\n results.push({\n path: docPath,\n score: pathScore + content.score,\n line: at >= 0 ? lineOfIndex(doc.content, at) : 1,\n snippet: snippetAt(doc.content, at >= 0 ? at : 0),\n });\n }\n\n results.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));\n return results;\n}\n\n// What the index could not read, in the shape the palette can say out loud —\n// \"searched 127 files, 3 skipped\" beats a mystery file that never turns up.\nfunction indexStats(indexData) {\n const skipped = indexData && indexData.skipped;\n if (!skipped) return null;\n return { bytes: indexData.totalBytes ?? 0, skipped: { ...skipped }, cap: indexData.cap ?? null };\n}\n\n// The serializable half of a parsed query. `parsed.regex` is a RegExp and would\n// go over the wire as `{}`, so the pattern travels as the text it was typed as.\nfunction querySummary(parsed) {\n return {\n terms: parsed.terms,\n phrases: parsed.phrases,\n negatives: parsed.negatives,\n exts: parsed.exts,\n paths: parsed.paths,\n kinds: parsed.kinds,\n isTest: parsed.isTest,\n isSource: parsed.isSource,\n regex: parsed.regexSource ? `/${parsed.regexSource}/${parsed.regexFlags}` : null,\n caseSensitive: parsed.caseSensitive,\n advanced: isAdvanced(parsed),\n };\n}\n\n// The one entry point the route uses, kept separate from `searchIndex` so the\n// forgiving ranking that shipped first survives intact: a query of bare words\n// is still answered by that function, partial matches and all. Only a query the\n// person made decisions in — a filter, a phrase, a regex, the case toggle —\n// goes down the strict path, where those decisions are enforced.\nexport function searchDocuments(indexData, rawQuery, options: Record<string, any> = {}) {\n const limit = Number.isFinite(options.limit) ? Math.max(1, Math.floor(options.limit)) : 15;\n const parsed = parseQuery(rawQuery, { caseSensitive: !!options.caseSensitive });\n const advanced = isAdvanced(parsed);\n const base = {\n results: [],\n total: 0,\n indexed: indexData?.totalDocs ?? 0,\n capped: false,\n advanced,\n query: querySummary(parsed),\n error: parsed.error,\n stats: indexStats(indexData),\n };\n\n if (!indexData || !indexData.totalDocs) return base;\n if (queryIsEmpty(parsed)) return base;\n // A pattern that would not compile is the whole answer. Reporting \"no\n // results\" instead would send someone hunting for a file sitting right there.\n if (parsed.error) return base;\n\n if (!advanced) {\n const ranked = searchIndex(indexData, parsed.terms.join(' '), limit);\n return { ...base, results: ranked, total: ranked.length, capped: ranked.length >= limit };\n }\n\n const all = strictSearch(indexData, parsed);\n return {\n ...base,\n results: all.slice(0, limit),\n total: all.length,\n capped: all.length > limit,\n };\n}\n\nexport async function handleSearch(res, body) {\n const { scanId, query, limit = 15, caseSensitive = false } = body || {};\n if (!scanId) return sendError(res, 400, 'Missing scanId.');\n const session = getSession(scanId);\n if (!session) return sendError(res, 404, 'Scan not found.');\n\n const q = (query || '').trim();\n if (!q) {\n return sendJSON(res, 200, { results: [], total: 0, indexed: session.searchIndex?.totalDocs ?? 0 });\n }\n\n // No index means the scan was opened before this change shipped, or the\n // caller is using a session that was never given a scan-time index. The\n // honest answer is \"no results\" rather than rebuilding the whole thing on\n // the request thread.\n if (!session.searchIndex || session.searchIndex.totalDocs === 0) {\n return sendJSON(res, 200, {\n results: [],\n total: 0,\n indexed: 0,\n note: 'Nothing was indexed for this scan.',\n });\n }\n\n try {\n const out = searchDocuments(session.searchIndex, q, { limit, caseSensitive });\n return sendJSON(res, 200, {\n results: out.results,\n total: out.total,\n indexed: out.indexed,\n capped: out.capped,\n advanced: out.advanced,\n query: out.query,\n error: out.error || null,\n stats: out.stats || null,\n });\n } catch (err) {\n return sendError(res, 500, 'Search failed: ' + err.message);\n }\n}\n\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function handleGetSettings(req: any, res: any, config: any): Promise<void>;
|
|
2
|
+
export declare function handleUpdateSettings(res: any, body: any, config: any): Promise<void>;
|
|
3
|
+
export declare function handleRotateAccessKey(req: any, res: any, config: any): Promise<void>;
|
|
4
|
+
export declare function validatePatch(patch: any): import("../shared/contracts.js").Settings;
|