@@ -333,9 +333,10 @@ public ProxyHost()
333333 ProxyCommandHandler . Configuration . ConfigFile = ConfigFile ;
334334 }
335335
336- public RootCommand GetRootCommand ( ILogger logger )
336+ public RootCommand GetRootCommand ( 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,87 @@ 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" ) ;
375+ command . AddCommands ( commands . OrderByName ( ) ) ;
376+ return command ;
377+ }
369378
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 ) ;
379+ private static Command CreateCertCommand ( ILogger logger )
380+ {
381+ var certCommand = new Command ( "cert" , "Manage the Dev Proxy certificate" ) ;
375382
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 ) ;
383+ var sortedCommands = new [ ] {
384+ CreateCertEnsureCommand ( logger )
385+ } . OrderByName ( ) ;
385386
386- var configOpenCommand = new Command ( "open" , "Open devproxyrc.json" ) ;
387- configOpenCommand . SetHandler ( ( ) =>
388- {
389- var cfgPsi = new ProcessStartInfo ( ConfigFile )
390- {
391- UseShellExecute = true
392- } ;
393- Process . Start ( cfgPsi ) ;
394- } ) ;
395- configCommand . Add ( configOpenCommand ) ;
396-
397- command . Add ( configCommand ) ;
387+ certCommand . AddCommands ( sortedCommands ) ;
388+ return certCommand ;
389+ }
398390
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 ) ;
391+ private static Command CreateCertEnsureCommand ( ILogger logger )
392+ {
393+ var certEnsureCommand = new Command ( "ensure" , "Ensure certificates are setup (creates root if required). Also makes root certificate trusted." ) ;
394+ certEnsureCommand . SetHandler ( async ( ) => await CertEnsureCommandHandler . EnsureCertAsync ( logger ) ) ;
395+ return certEnsureCommand ;
396+ }
404397
398+ private static Command CreateJwtCommand ( )
399+ {
405400 var jwtCommand = new Command ( "jwt" , "Manage JSON Web Tokens" ) ;
401+
402+ var sortedCommands = new [ ] {
403+ CreateJwtCreateCommand ( )
404+ } . OrderByName ( ) ;
405+
406+ jwtCommand . AddCommands ( sortedCommands ) ;
407+ return jwtCommand ;
408+ }
409+
410+ private static Command CreateJwtCreateCommand ( )
411+ {
406412 var jwtCreateCommand = new Command ( "create" , "Create a new JWT token" ) ;
413+
407414 var jwtNameOption = new Option < string > ( "--name" , "The name of the user to create the token for." ) ;
408415 jwtNameOption . AddAlias ( "-n" ) ;
409- jwtCreateCommand . AddOption ( jwtNameOption ) ;
410416
411417 var jwtAudienceOption = new Option < IEnumerable < string > > ( "--audience" , "The audiences to create the token for. Specify once for each audience" )
412418 {
413419 AllowMultipleArgumentsPerToken = true
414420 } ;
415421 jwtAudienceOption . AddAlias ( "-a" ) ;
416- jwtCreateCommand . AddOption ( jwtAudienceOption ) ;
417422
418423 var jwtIssuerOption = new Option < string > ( "--issuer" , "The issuer of the token." ) ;
419424 jwtIssuerOption . AddAlias ( "-i" ) ;
420- jwtCreateCommand . AddOption ( jwtIssuerOption ) ;
421425
422426 var jwtRolesOption = new Option < IEnumerable < string > > ( "--roles" , "A role claim to add to the token. Specify once for each role." )
423427 {
424428 AllowMultipleArgumentsPerToken = true
425429 } ;
426430 jwtRolesOption . AddAlias ( "-r" ) ;
427- jwtCreateCommand . AddOption ( jwtRolesOption ) ;
428431
429432 var jwtScopesOption = new Option < IEnumerable < string > > ( "--scopes" , "A scope claim to add to the token. Specify once for each scope." )
430433 {
431434 AllowMultipleArgumentsPerToken = true
432435 } ;
433436 jwtScopesOption . AddAlias ( "-s" ) ;
434- jwtCreateCommand . AddOption ( jwtScopesOption ) ;
435437
436438 var jwtClaimsOption = new Option < Dictionary < string , string > > ( "--claims" ,
437439 description : "Claims to add to the token. Specify once for each claim in the format \" name:value\" ." ,
@@ -464,11 +466,9 @@ public RootCommand GetRootCommand(ILogger logger)
464466 {
465467 AllowMultipleArgumentsPerToken = true ,
466468 } ;
467- jwtCreateCommand . AddOption ( jwtClaimsOption ) ;
468469
469470 var jwtValidForOption = new Option < double > ( "--valid-for" , "The duration for which the token is valid. Duration is set in minutes." ) ;
470471 jwtValidForOption . AddAlias ( "-v" ) ;
471- jwtCreateCommand . AddOption ( jwtValidForOption ) ;
472472
473473 var jwtSigningKeyOption = new Option < string > ( "--signing-key" , "The signing key to sign the token. Minimum length is 32 characters." ) ;
474474 jwtSigningKeyOption . AddAlias ( "-k" ) ;
@@ -487,7 +487,6 @@ public RootCommand GetRootCommand(ILogger logger)
487487 input . ErrorMessage = ex . Message ;
488488 }
489489 } ) ;
490- jwtCreateCommand . AddOption ( jwtSigningKeyOption ) ;
491490
492491 jwtCreateCommand . SetHandler (
493492 JwtCommandHandler . GetToken ,
@@ -502,17 +501,92 @@ public RootCommand GetRootCommand(ILogger logger)
502501 jwtSigningKeyOption
503502 )
504503 ) ;
505- jwtCommand . Add ( jwtCreateCommand ) ;
506504
507- command . Add ( jwtCommand ) ;
505+ var sortedOptions = new Option [ ] {
506+ jwtNameOption ,
507+ jwtAudienceOption ,
508+ jwtIssuerOption ,
509+ jwtRolesOption ,
510+ jwtScopesOption ,
511+ jwtClaimsOption ,
512+ jwtValidForOption ,
513+ jwtSigningKeyOption
514+ } . OrderByName ( ) ;
515+
516+ jwtCreateCommand . AddOptions ( sortedOptions ) ;
517+ return jwtCreateCommand ;
518+ }
508519
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 ) ;
520+ private static Command CreateOutdatedCommand ( ILogger logger )
521+ {
522+ var outdatedCommand = new Command ( "outdated" , "Check for new version" ) ;
523+ var outdatedShortOption = new Option < bool > ( "--short" , "Return version only" ) ;
524+ outdatedCommand . SetHandler ( async versionOnly => await OutdatedCommandHandler . CheckVersionAsync ( versionOnly , logger ) , outdatedShortOption ) ;
514525
515- return command ;
526+ var sortedOptions = new [ ] {
527+ outdatedShortOption
528+ } . OrderByName ( ) ;
529+
530+ outdatedCommand . AddOptions ( sortedOptions ) ;
531+ return outdatedCommand ;
532+ }
533+
534+ private static Command CreateConfigCommand ( ILogger logger )
535+ {
536+ var configCommand = new Command ( "config" , "Manage Dev Proxy configs" ) ;
537+
538+ var sortedCommands = new [ ] {
539+ CreateConfigGetCommand ( logger ) ,
540+ CreateConfigNewCommand ( logger ) ,
541+ CreateConfigOpenCommand ( )
542+ } . OrderByName ( ) ;
543+
544+ configCommand . AddCommands ( sortedCommands ) ;
545+ return configCommand ;
546+ }
547+
548+ private static Command CreateConfigGetCommand ( ILogger logger )
549+ {
550+ var configGetCommand = new Command ( "get" , "Download the specified config from the Sample Solution Gallery" ) ;
551+ var configIdArgument = new Argument < string > ( "config-id" , "The ID of the config to download" ) ;
552+ configGetCommand . AddArgument ( configIdArgument ) ;
553+ configGetCommand . SetHandler ( async configId => await ConfigGetCommandHandler . DownloadConfigAsync ( configId , logger ) , configIdArgument ) ;
554+ return configGetCommand ;
555+ }
556+
557+ private static Command CreateConfigNewCommand ( ILogger logger )
558+ {
559+ var configNewCommand = new Command ( "new" , "Create new Dev Proxy configuration file" ) ;
560+ var nameArgument = new Argument < string > ( "name" , "Name of the configuration file" )
561+ {
562+ Arity = ArgumentArity . ZeroOrOne
563+ } ;
564+ nameArgument . SetDefaultValue ( "devproxyrc.json" ) ;
565+ configNewCommand . AddArgument ( nameArgument ) ;
566+ configNewCommand . SetHandler ( async name => await ConfigNewCommandHandler . CreateConfigFileAsync ( name , logger ) , nameArgument ) ;
567+ return configNewCommand ;
568+ }
569+
570+ private static Command CreateConfigOpenCommand ( )
571+ {
572+ var configOpenCommand = new Command ( "open" , "Open devproxyrc.json" ) ;
573+ configOpenCommand . SetHandler ( ( ) =>
574+ {
575+ var cfgPsi = new ProcessStartInfo ( ConfigFile )
576+ {
577+ UseShellExecute = true
578+ } ;
579+ Process . Start ( cfgPsi ) ;
580+ } ) ;
581+ return configOpenCommand ;
582+ }
583+
584+ private static Command CreateMsGraphDbCommand ( ILogger logger )
585+ {
586+ return new Command ( "msgraphdb" , "Generate a local SQLite database with Microsoft Graph API metadata" )
587+ {
588+ Handler = new MSGraphDbCommandHandler ( logger )
589+ } ;
516590 }
517591
518592 public ProxyCommandHandler GetCommandHandler ( PluginEvents pluginEvents , Option [ ] optionsFromPlugins , ISet < UrlToWatch > urlsToWatch , ILogger logger ) => new (
0 commit comments