@@ -19,6 +19,7 @@ import (
1919 "encoding/json"
2020 "errors"
2121 "fmt"
22+ "io"
2223 "os"
2324 "slices"
2425 "time"
@@ -33,17 +34,30 @@ import (
3334)
3435
3536const (
36- usageCreate = "Ability to create or delete rooms"
37- usageList = "Ability to list rooms"
38- usageJoin = "Ability to join a room (requires --room and --identity)"
39- usageAdmin = "Ability to moderate a room (requires --room)"
40- usageEgress = "Ability to interact with Egress services"
41- usageIngress = "Ability to interact with Ingress services"
37+ usageCreate = "Ability to create or delete rooms"
38+ usageList = "Ability to list rooms"
39+ usageJoin = "Ability to join a room (requires --room and --identity)"
40+ usageAdmin = "Ability to moderate a room (requires --room)"
41+ usageEgress = "Ability to interact with Egress services"
42+ usageIngress = "Ability to interact with Ingress services"
4243 usageMetadata = "Ability to update their own name and metadata"
4344 usageInference = "Ability to perform inference (AI endpoints)"
4445)
4546
4647var (
48+ tokenOnlyFlag = & cli.BoolFlag {
49+ Name : "token-only" ,
50+ Usage : "Output only the access token" ,
51+ }
52+
53+ tokenOutputMutuallyExclusiveFlags = []cli.MutuallyExclusiveFlags {{
54+ Flags : [][]cli.Flag {{
55+ jsonFlag ,
56+ }, {
57+ tokenOnlyFlag ,
58+ }},
59+ }}
60+
4761 TokenCommands = []* cli.Command {
4862 {
4963 Name : "token" ,
@@ -131,6 +145,7 @@ var (
131145 Usage : "Metadata attached to job dispatched to the agent (ctx.job.metadata)" ,
132146 },
133147 },
148+ MutuallyExclusiveFlags : tokenOutputMutuallyExclusiveFlags ,
134149 },
135150 },
136151 },
@@ -217,11 +232,17 @@ var (
217232 Usage : "Additional `VIDEO_GRANT` fields. It'll be merged with other arguments (JSON formatted)" ,
218233 },
219234 },
235+ MutuallyExclusiveFlags : tokenOutputMutuallyExclusiveFlags ,
220236 },
221237 }
222238)
223239
224240func createToken (ctx context.Context , c * cli.Command ) error {
241+ tokenOnly := c .Bool ("token-only" )
242+ jsonOutput := c .Bool ("json" )
243+ stdout := c .Root ().Writer
244+ stderr := c .Root ().ErrWriter
245+
225246 name := c .String ("name" )
226247 metadata := c .String ("metadata" )
227248 validFor := c .String ("valid-for" )
@@ -254,13 +275,17 @@ func createToken(ctx context.Context, c *cli.Command) error {
254275 participant := c .String ("identity" )
255276 if participant == "" {
256277 participant = util .ExpandTemplate ("participant-%x" )
257- fmt .Printf ("Using generated participant identity [%s]\n " , util .Accented (participant ))
278+ if ! tokenOnly && ! jsonOutput {
279+ fmt .Fprintf (stderr , "Using generated participant identity [%s]\n " , util .Accented (participant ))
280+ }
258281 }
259282
260283 room := c .String ("room" )
261284 if room == "" {
262285 room = util .ExpandTemplate ("room-%t" )
263- fmt .Printf ("Using generated room name [%s]\n " , util .Accented (room ))
286+ if ! tokenOnly && ! jsonOutput {
287+ fmt .Fprintf (stderr , "Using generated room name [%s]\n " , util .Accented (room ))
288+ }
264289 }
265290
266291 grant := & auth.VideoGrant {
@@ -419,7 +444,9 @@ func createToken(ctx context.Context, c *cli.Command) error {
419444 at .SetName (name )
420445 if validFor != "" {
421446 if dur , err := time .ParseDuration (validFor ); err == nil {
422- fmt .Println ("valid for (mins): " , int (dur / time .Minute ))
447+ if ! tokenOnly && ! jsonOutput {
448+ fmt .Fprintf (stderr , "valid for (mins): %d\n " , int (dur / time .Minute ))
449+ }
423450 at .SetValidFor (dur )
424451 } else {
425452 return err
@@ -431,13 +458,16 @@ func createToken(ctx context.Context, c *cli.Command) error {
431458 return err
432459 }
433460
434- fmt .Println ("Token grants:" )
435- util .PrintJSON (at .GetGrants ())
436- fmt .Println ()
437- if project .URL != "" {
438- fmt .Println ("Project URL:" , project .URL )
461+ if err = printTokenCreateOutput (stdout , tokenOnly , jsonOutput , tokenCreateOutput {
462+ AccessToken : token ,
463+ ProjectURL : project .URL ,
464+ Identity : participant ,
465+ Name : name ,
466+ Room : room ,
467+ Grants : at .GetGrants (),
468+ }); err != nil {
469+ return err
439470 }
440- fmt .Println ("Access token:" , token )
441471
442472 if c .IsSet ("open" ) {
443473 switch c .String ("open" ) {
@@ -459,3 +489,33 @@ func accessToken(apiKey, apiSecret string, grant *auth.VideoGrant, identity stri
459489 SetIdentity (identity )
460490 return at
461491}
492+
493+ type tokenCreateOutput struct {
494+ AccessToken string `json:"access_token"`
495+ ProjectURL string `json:"project_url,omitempty"`
496+ Identity string `json:"identity"`
497+ Name string `json:"name"`
498+ Room string `json:"room"`
499+ Grants * auth.ClaimGrants `json:"grants"`
500+ }
501+
502+ func printTokenCreateOutput (w io.Writer , tokenOnly , jsonOutput bool , out tokenCreateOutput ) error {
503+ switch {
504+ case tokenOnly :
505+ _ , _ = fmt .Fprintln (w , out .AccessToken )
506+ case jsonOutput :
507+ return util .PrintJSONTo (w , out )
508+ default :
509+ _ , _ = fmt .Fprintln (w , "Token grants:" )
510+ if err := util .PrintJSONTo (w , out .Grants ); err != nil {
511+ return err
512+ }
513+ _ , _ = fmt .Fprintln (w )
514+ if out .ProjectURL != "" {
515+ _ , _ = fmt .Fprintln (w , "Project URL:" , out .ProjectURL )
516+ }
517+ _ , _ = fmt .Fprintln (w , "Access token:" , out .AccessToken )
518+ }
519+
520+ return nil
521+ }
0 commit comments