package surf import ( "context" "encoding/json" "strconv" "strings" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/bonfire" "git.golem15.com/golem15/summercms/modules/party" ) // jsonFlagName is route:list's --json flag. const jsonFlagName = "json" // routeJSON is one route of route:list --json. type routeJSON struct { Method string `json:"method"` Pattern string `json:"pattern"` Plugin string `json:"plugin"` Middleware []string `json:"middleware"` Raw bool `json:"raw"` } // RouteListCommand builds the router the same way ServeCommand does, then // renders Routes() as a table instead of serving, followed by the admin // status line. func RouteListCommand(app *backpack.App, plugins []party.Plugin) bonfire.Command { return bonfire.Command{ Name: "route:list", Description: "List registered HTTP routes", Long: `Builds the router the way serve does, without opening the database or listening, and prints every route: method, pattern, the plugin that registered it, its named middleware and whether it is raw (no JSON envelope). The admin status line follows. --json prints the routes as a JSON array for scripts.`, Flags: []bonfire.Flag{{Name: jsonFlagName, Description: "Print the routes as JSON", Bare: true}}, Examples: []bonfire.Example{ {Command: "route:list", Description: "Show every route as a table"}, {Command: "route:list --json", Description: "Machine-readable route list"}, }, Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error { r, err := BuildRouter(app, plugins) if err != nil { return err } infos := r.Routes() if in != nil { if v, _ := in.Flag(jsonFlagName); v == "true" { list := make([]routeJSON, 0, len(infos)) for _, rt := range infos { mw := rt.Middleware if mw == nil { mw = []string{} } list = append(list, routeJSON{Method: rt.Method, Pattern: rt.Pattern, Plugin: rt.PluginID, Middleware: mw, Raw: rt.Raw}) } b, err := json.MarshalIndent(list, "", " ") if err != nil { return err } out.Println(string(b)) return nil } } rows := make([][]string, 0, len(infos)) for _, rt := range infos { rows = append(rows, []string{ rt.Method, rt.Pattern, rt.PluginID, strings.Join(rt.Middleware, ","), strconv.FormatBool(rt.Raw), }) } out.Table([]string{"Method", "Pattern", "Plugin", "Middleware", "Raw"}, rows) if prefix, mounted := r.AdminPrefix(); mounted { out.Info("admin: mounted at " + prefix) } else { out.Info(adminOffText) } return nil }, } }