@@ -333,9 +333,10 @@ public ProxyHost()
333333 ProxyCommandHandler . Configuration . ConfigFile = ConfigFile ;
334334 }
335335
336- public RootCommand GetRootCommand ( ILogger logger )
336+ public RootCommand CreateRootCommand ( ILogger logger , Option [ ] pluginOptions , Command [ ] pluginCommands )
337337 {
338- var command = new RootCommand {
338+ var command = new RootCommand ( "Dev Proxy is a command line tool for testing Microsoft Graph, SharePoint Online and any other HTTP APIs." ) ;
339+ var options = ( Option [ ] ) [
339340 _portOption ,
340341 _ipAddressOption ,
341342 _recordOption ,
@@ -352,86 +353,89 @@ public RootCommand GetRootCommand(ILogger logger)
352353 _urlsToWatchOption ! ,
353354 _timeoutOption ,
354355 _discoverOption ,
355- _envOption
356- } ;
357- command . Description = "Dev Proxy is a command line tool for testing Microsoft Graph, SharePoint Online and any other HTTP APIs." ;
356+ _envOption ,
357+ ..pluginOptions
358+ ] ;
359+
360+ command . AddOptions ( options . OrderByName ( ) ) ;
361+
358362 // _logLevelOption is set while initializing the Program
359363 // As such, it's always set here
360364 command . AddGlobalOption ( _logLevelOption ! ) ;
361365
362- var msGraphDbCommand = new Command ( "msgraphdb" , "Generate a local SQLite database with Microsoft Graph API metadata" )
363- {
364- Handler = new MSGraphDbCommandHandler ( logger )
365- } ;
366- command . Add ( msGraphDbCommand ) ;
366+ var commands = ( Command [ ] ) [
367+ CreateMsGraphDbCommand ( logger ) ,
368+ CreateConfigCommand ( logger ) ,
369+ CreateOutdatedCommand ( logger ) ,
370+ CreateJwtCommand ( ) ,
371+ CreateCertCommand ( logger ) ,
372+ ..pluginCommands
373+ ] ;
367374
368- var configCommand = new Command ( "config" , "Manage Dev Proxy configs" ) ;
369-
370- var configGetCommand = new Command ( "get" , "Download the specified config from the Sample Solution Gallery" ) ;
371- var configIdArgument = new Argument < string > ( "config-id" , "The ID of the config to download" ) ;
372- configGetCommand . AddArgument ( configIdArgument ) ;
373- configGetCommand . SetHandler ( async configId => await ConfigGetCommandHandler . DownloadConfigAsync ( configId , logger ) , configIdArgument ) ;
374- configCommand . Add ( configGetCommand ) ;
375+ command . AddCommands ( commands . OrderByName ( ) ) ;
376+ return command ;
377+ }
375378
376- var configNewCommand = new Command ( "new" , "Create new Dev Proxy configuration file" ) ;
377- var nameArgument = new Argument < string > ( "name" , "Name of the configuration file" )
378- {
379- Arity = ArgumentArity . ZeroOrOne
380- } ;
381- nameArgument . SetDefaultValue ( "devproxyrc.json" ) ;
382- configNewCommand . AddArgument ( nameArgument ) ;
383- configNewCommand . SetHandler ( async name => await ConfigNewCommandHandler . CreateConfigFileAsync ( name , logger ) , nameArgument ) ;
384- configCommand . Add ( configNewCommand ) ;
379+ private static Command CreateCertCommand ( ILogger logger )
380+ {
381+ var certCommand = new Command ( "cert" , "Manage the Dev Proxy certificate" ) ;
385382
386- var configOpenCommand = new Command ( "open" , "Open devproxyrc.json" ) ;
387- configOpenCommand . SetHandler ( ( ) =>
383+ var sortedCommands = new [ ]
388384 {
389- var cfgPsi = new ProcessStartInfo ( ConfigFile )
390- {
391- UseShellExecute = true
392- } ;
393- Process . Start ( cfgPsi ) ;
394- } ) ;
395- configCommand . Add ( configOpenCommand ) ;
385+ CreateCertEnsureCommand ( logger )
386+ } . OrderByName ( ) ;
396387
397- command . Add ( configCommand ) ;
388+ certCommand . AddCommands ( sortedCommands ) ;
389+ return certCommand ;
390+ }
398391
399- var outdatedCommand = new Command ( "outdated" , "Check for new version" ) ;
400- var outdatedShortOption = new Option < bool > ( "--short" , "Return version only" ) ;
401- outdatedCommand . AddOption ( outdatedShortOption ) ;
402- outdatedCommand . SetHandler ( async versionOnly => await OutdatedCommandHandler . CheckVersionAsync ( versionOnly , logger ) , outdatedShortOption ) ;
403- command . Add ( outdatedCommand ) ;
392+ private static Command CreateCertEnsureCommand ( ILogger logger )
393+ {
394+ var certEnsureCommand = new Command ( "ensure" , "Ensure certificates are setup (creates root if required). Also makes root certificate trusted." ) ;
395+ certEnsureCommand . SetHandler ( async ( ) => await CertEnsureCommandHandler . EnsureCertAsync ( logger ) ) ;
396+ return certEnsureCommand ;
397+ }
404398
399+ private static Command CreateJwtCommand ( )
400+ {
405401 var jwtCommand = new Command ( "jwt" , "Manage JSON Web Tokens" ) ;
402+
403+ var sortedCommands = new [ ]
404+ {
405+ CreateJwtCreateCommand ( )
406+ } . OrderByName ( ) ;
407+
408+ jwtCommand . AddCommands ( sortedCommands ) ;
409+ return jwtCommand ;
410+ }
411+
412+ private static Command CreateJwtCreateCommand ( )
413+ {
406414 var jwtCreateCommand = new Command ( "create" , "Create a new JWT token" ) ;
415+
407416 var jwtNameOption = new Option < string > ( "--name" , "The name of the user to create the token for." ) ;
408417 jwtNameOption . AddAlias ( "-n" ) ;
409- jwtCreateCommand . AddOption ( jwtNameOption ) ;
410418
411419 var jwtAudienceOption = new Option < IEnumerable < string > > ( "--audience" , "The audiences to create the token for. Specify once for each audience" )
412420 {
413421 AllowMultipleArgumentsPerToken = true
414422 } ;
415423 jwtAudienceOption . AddAlias ( "-a" ) ;
416- jwtCreateCommand . AddOption ( jwtAudienceOption ) ;
417424
418425 var jwtIssuerOption = new Option < string > ( "--issuer" , "The issuer of the token." ) ;
419426 jwtIssuerOption . AddAlias ( "-i" ) ;
420- jwtCreateCommand . AddOption ( jwtIssuerOption ) ;
421427
422428 var jwtRolesOption = new Option < IEnumerable < string > > ( "--roles" , "A role claim to add to the token. Specify once for each role." )
423429 {
424430 AllowMultipleArgumentsPerToken = true
425431 } ;
426432 jwtRolesOption . AddAlias ( "-r" ) ;
427- jwtCreateCommand . AddOption ( jwtRolesOption ) ;
428433
429434 var jwtScopesOption = new Option < IEnumerable < string > > ( "--scopes" , "A scope claim to add to the token. Specify once for each scope." )
430435 {
431436 AllowMultipleArgumentsPerToken = true
432437 } ;
433438 jwtScopesOption . AddAlias ( "-s" ) ;
434- jwtCreateCommand . AddOption ( jwtScopesOption ) ;
435439
436440 var jwtClaimsOption = new Option < Dictionary < string , string > > ( "--claims" ,
437441 description : "Claims to add to the token. Specify once for each claim in the format \" name:value\" ." ,
@@ -464,11 +468,9 @@ public RootCommand GetRootCommand(ILogger logger)
464468 {
465469 AllowMultipleArgumentsPerToken = true ,
466470 } ;
467- jwtCreateCommand . AddOption ( jwtClaimsOption ) ;
468471
469472 var jwtValidForOption = new Option < double > ( "--valid-for" , "The duration for which the token is valid. Duration is set in minutes." ) ;
470473 jwtValidForOption . AddAlias ( "-v" ) ;
471- jwtCreateCommand . AddOption ( jwtValidForOption ) ;
472474
473475 var jwtSigningKeyOption = new Option < string > ( "--signing-key" , "The signing key to sign the token. Minimum length is 32 characters." ) ;
474476 jwtSigningKeyOption . AddAlias ( "-k" ) ;
@@ -487,7 +489,6 @@ public RootCommand GetRootCommand(ILogger logger)
487489 input . ErrorMessage = ex . Message ;
488490 }
489491 } ) ;
490- jwtCreateCommand . AddOption ( jwtSigningKeyOption ) ;
491492
492493 jwtCreateCommand . SetHandler (
493494 JwtCommandHandler . GetToken ,
@@ -502,17 +503,95 @@ public RootCommand GetRootCommand(ILogger logger)
502503 jwtSigningKeyOption
503504 )
504505 ) ;
505- jwtCommand . Add ( jwtCreateCommand ) ;
506506
507- command . Add ( jwtCommand ) ;
507+ var sortedOptions = new Option [ ]
508+ {
509+ jwtNameOption ,
510+ jwtAudienceOption ,
511+ jwtIssuerOption ,
512+ jwtRolesOption ,
513+ jwtScopesOption ,
514+ jwtClaimsOption ,
515+ jwtValidForOption ,
516+ jwtSigningKeyOption
517+ } . OrderByName ( ) ;
518+
519+ jwtCreateCommand . AddOptions ( sortedOptions ) ;
520+ return jwtCreateCommand ;
521+ }
508522
509- var certCommand = new Command ( "cert" , "Manage the Dev Proxy certificate" ) ;
510- var certEnsureCommand = new Command ( "ensure" , "Ensure certificates are setup (creates root if required). Also makes root certificate trusted." ) ;
511- certEnsureCommand . SetHandler ( async ( ) => await CertEnsureCommandHandler . EnsureCertAsync ( logger ) ) ;
512- certCommand . Add ( certEnsureCommand ) ;
513- command . Add ( certCommand ) ;
523+ private static Command CreateOutdatedCommand ( ILogger logger )
524+ {
525+ var outdatedCommand = new Command ( "outdated" , "Check for new version" ) ;
526+ var outdatedShortOption = new Option < bool > ( "--short" , "Return version only" ) ;
527+ outdatedCommand . SetHandler ( async versionOnly => await OutdatedCommandHandler . CheckVersionAsync ( versionOnly , logger ) , outdatedShortOption ) ;
514528
515- return command ;
529+ var sortedOptions = new [ ]
530+ {
531+ outdatedShortOption
532+ } . OrderByName ( ) ;
533+
534+ outdatedCommand . AddOptions ( sortedOptions ) ;
535+ return outdatedCommand ;
536+ }
537+
538+ private static Command CreateConfigCommand ( ILogger logger )
539+ {
540+ var configCommand = new Command ( "config" , "Manage Dev Proxy configs" ) ;
541+
542+ var sortedCommands = new [ ]
543+ {
544+ CreateConfigGetCommand ( logger ) ,
545+ CreateConfigNewCommand ( logger ) ,
546+ CreateConfigOpenCommand ( )
547+ } . OrderByName ( ) ;
548+
549+ configCommand . AddCommands ( sortedCommands ) ;
550+ return configCommand ;
551+ }
552+
553+ private static Command CreateConfigGetCommand ( ILogger logger )
554+ {
555+ var configGetCommand = new Command ( "get" , "Download the specified config from the Sample Solution Gallery" ) ;
556+ var configIdArgument = new Argument < string > ( "config-id" , "The ID of the config to download" ) ;
557+ configGetCommand . AddArgument ( configIdArgument ) ;
558+ configGetCommand . SetHandler ( async configId => await ConfigGetCommandHandler . DownloadConfigAsync ( configId , logger ) , configIdArgument ) ;
559+ return configGetCommand ;
560+ }
561+
562+ private static Command CreateConfigNewCommand ( ILogger logger )
563+ {
564+ var configNewCommand = new Command ( "new" , "Create new Dev Proxy configuration file" ) ;
565+ var nameArgument = new Argument < string > ( "name" , "Name of the configuration file" )
566+ {
567+ Arity = ArgumentArity . ZeroOrOne
568+ } ;
569+ nameArgument . SetDefaultValue ( "devproxyrc.json" ) ;
570+ configNewCommand . AddArgument ( nameArgument ) ;
571+ configNewCommand . SetHandler ( async name => await ConfigNewCommandHandler . CreateConfigFileAsync ( name , logger ) , nameArgument ) ;
572+ return configNewCommand ;
573+ }
574+
575+ private static Command CreateConfigOpenCommand ( )
576+ {
577+ var configOpenCommand = new Command ( "open" , "Open devproxyrc.json" ) ;
578+ configOpenCommand . SetHandler ( ( ) =>
579+ {
580+ var cfgPsi = new ProcessStartInfo ( ConfigFile )
581+ {
582+ UseShellExecute = true
583+ } ;
584+ Process . Start ( cfgPsi ) ;
585+ } ) ;
586+ return configOpenCommand ;
587+ }
588+
589+ private static Command CreateMsGraphDbCommand ( ILogger logger )
590+ {
591+ return new Command ( "msgraphdb" , "Generate a local SQLite database with Microsoft Graph API metadata" )
592+ {
593+ Handler = new MSGraphDbCommandHandler ( logger )
594+ } ;
516595 }
517596
518597 public ProxyCommandHandler GetCommandHandler ( PluginEvents pluginEvents , Option [ ] optionsFromPlugins , ISet < UrlToWatch > urlsToWatch , ILogger logger ) => new (
0 commit comments