@@ -3,12 +3,21 @@ import path from 'node:path'
33import { logger } from '@socketsecurity/registry/lib/logger'
44
55import { handleScanReach } from './handle-scan-reach.mts'
6+ import { reachabilityFlags } from './reachability-flags.mts'
7+ import { suggestTarget } from './suggest_target.mts'
68import constants from '../../constants.mts'
7- import { commonFlags , outputFlags } from '../../flags.mts'
9+ import { type MeowFlags , commonFlags , outputFlags } from '../../flags.mts'
810import { checkCommandInput } from '../../utils/check-input.mts'
11+ import { cmdFlagValueToArray } from '../../utils/cmd.mts'
12+ import { determineOrgSlug } from '../../utils/determine-org-slug.mts'
13+ import {
14+ type EcosystemString ,
15+ getEcosystemChoicesForMeow ,
16+ } from '../../utils/ecosystem.mts'
917import { getOutputKind } from '../../utils/get-output-kind.mts'
1018import { meowOrExit } from '../../utils/meow-with-subcommands.mts'
1119import { getFlagListOutput } from '../../utils/output-formatting.mts'
20+ import { hasDefaultToken } from '../../utils/sdk.mts'
1221
1322import type { CliCommandConfig } from '../../utils/meow-with-subcommands.mts'
1423
@@ -21,18 +30,51 @@ const config: CliCommandConfig = {
2130 flags : {
2231 ...commonFlags ,
2332 ...outputFlags ,
33+ cwd : {
34+ type : 'string' ,
35+ description : 'working directory, defaults to process.cwd()' ,
36+ } ,
37+ org : {
38+ type : 'string' ,
39+ description :
40+ 'Force override the organization slug, overrides the default org from config' ,
41+ } ,
42+ ...reachabilityFlags ,
2443 } ,
25- help : ( command , config ) => `
44+ help : ( command , config ) => {
45+ const allFlags = config . flags || { }
46+ const generalFlags : MeowFlags = { }
47+
48+ // Separate general flags from reachability flags
49+ for ( const [ key , value ] of Object . entries ( allFlags ) ) {
50+ if ( ! reachabilityFlags [ key ] ) {
51+ generalFlags [ key ] = value
52+ }
53+ }
54+
55+ return `
2656 Usage
2757 $ ${ command } [options] [CWD=.]
2858
2959 Options
30- ${ getFlagListOutput ( config . flags ) }
60+ ${ getFlagListOutput ( generalFlags ) }
61+
62+ Reachability Options
63+ ${ getFlagListOutput ( reachabilityFlags ) }
64+
65+ Runs the Socket reachability analysis without creating a scan in Socket.
66+ The output is written to .socket.facts.json in the current working directory.
67+
68+ Note: Manifest files are uploaded to Socket's backend services because the
69+ reachability analysis requires creating a Software Bill of Materials (SBOM)
70+ from these files before the analysis can run.
3171
3272 Examples
3373 $ ${ command }
3474 $ ${ command } ./proj
35- ` ,
75+ $ ${ command } ./proj --reach-ecosystems npm,pypi
76+ `
77+ } ,
3678}
3779
3880export const cmdScanReach = {
@@ -53,11 +95,85 @@ async function run(
5395 parentName,
5496 } )
5597
56- const { dryRun, json, markdown } = cli . flags
98+ const {
99+ cwd : cwdOverride ,
100+ dryRun = false ,
101+ interactive = true ,
102+ json,
103+ markdown,
104+ org : orgFlag ,
105+ reachAnalysisMemoryLimit,
106+ reachAnalysisTimeout,
107+ reachContinueOnFailingProjects,
108+ reachDisableAnalytics,
109+ } = cli . flags as {
110+ cwd : string
111+ dryRun : boolean
112+ interactive : boolean
113+ json : boolean
114+ markdown : boolean
115+ org : string
116+ reachAnalysisTimeout ?: number
117+ reachAnalysisMemoryLimit ?: number
118+ reachContinueOnFailingProjects : boolean
119+ reachDisableAnalytics : boolean
120+ }
121+
122+ // Process comma-separated values for isMultiple flags
123+ const reachEcosystemsRaw = cmdFlagValueToArray ( cli . flags [ 'reachEcosystems' ] )
124+ const reachExcludePaths = cmdFlagValueToArray ( cli . flags [ 'reachExcludePaths' ] )
125+
126+ // Validate ecosystem values
127+ const validEcosystems = getEcosystemChoicesForMeow ( )
128+ const reachEcosystems : EcosystemString [ ] = [ ]
129+ for ( const ecosystem of reachEcosystemsRaw ) {
130+ if ( ! validEcosystems . includes ( ecosystem ) ) {
131+ throw new Error (
132+ `Invalid ecosystem: "${ ecosystem } ". Valid values are: ${ validEcosystems . join ( ', ' ) } ` ,
133+ )
134+ }
135+ reachEcosystems . push ( ecosystem as EcosystemString )
136+ }
57137
58138 const outputKind = getOutputKind ( json , markdown )
59139
60- const wasValidInput = checkCommandInput ( outputKind )
140+ const cwd =
141+ cwdOverride && cwdOverride !== 'process.cwd()'
142+ ? path . resolve ( process . cwd ( ) , String ( cwdOverride ) )
143+ : process . cwd ( )
144+
145+ // Accept zero or more paths. Default to cwd() if none given.
146+ let targets = cli . input || [ cwd ]
147+
148+ // Use suggestTarget if no targets specified and in interactive mode
149+ if ( ! targets . length && ! dryRun && interactive ) {
150+ targets = await suggestTarget ( )
151+ }
152+
153+ // Determine org slug
154+ const [ orgSlug ] = await determineOrgSlug (
155+ String ( orgFlag || '' ) ,
156+ interactive ,
157+ dryRun ,
158+ )
159+
160+ const hasApiToken = hasDefaultToken ( )
161+
162+ const wasValidInput = checkCommandInput (
163+ outputKind ,
164+ {
165+ nook : true ,
166+ test : ! ! orgSlug ,
167+ message : 'Org name by default setting, --org, or auto-discovered' ,
168+ fail : 'missing' ,
169+ } ,
170+ {
171+ nook : true ,
172+ test : hasApiToken ,
173+ message : 'This command requires an API token for access' ,
174+ fail : 'missing (try `socket login`)' ,
175+ } ,
176+ )
61177 if ( ! wasValidInput ) {
62178 return
63179 }
@@ -67,16 +183,19 @@ async function run(
67183 return
68184 }
69185
70- const { unknownFlags } = cli
71-
72- let [ cwd = '.' ] = cli . input
73- // Note: path.resolve vs .join:
74- // If given path is absolute then cwd should not affect it.
75- cwd = path . resolve ( process . cwd ( ) , cwd )
76-
77186 await handleScanReach ( {
78187 cwd,
188+ orgSlug,
79189 outputKind,
80- unknownFlags,
190+ targets,
191+ interactive,
192+ reachabilityOptions : {
193+ reachContinueOnFailingProjects : Boolean ( reachContinueOnFailingProjects ) ,
194+ reachDisableAnalytics : Boolean ( reachDisableAnalytics ) ,
195+ reachAnalysisTimeout : Number ( reachAnalysisTimeout ) ,
196+ reachAnalysisMemoryLimit : Number ( reachAnalysisMemoryLimit ) ,
197+ reachEcosystems,
198+ reachExcludePaths,
199+ } ,
81200 } )
82201}
0 commit comments