@@ -5,6 +5,7 @@ package main
55import (
66 "encoding/json"
77 "fmt"
8+ "strings"
89 "text/tabwriter"
910
1011 "github.com/mendixlabs/mxcli/internal/auth"
@@ -38,6 +39,18 @@ Examples:
3839 RunE : runCatalogSearch ,
3940}
4041
42+ var catalogShowCmd = & cobra.Command {
43+ Use : "show <uuid>" ,
44+ Short : "Show detailed endpoint metadata" ,
45+ Long : `Display detailed metadata for a Catalog endpoint including entities, actions, and contract.
46+
47+ Examples:
48+ mxcli catalog show a7f3c2d1-4b5e-6c7f-8d9e-0a1b2c3d4e5f
49+ mxcli catalog show a7f3c2d1 --json` ,
50+ Args : cobra .ExactArgs (1 ),
51+ RunE : runCatalogShow ,
52+ }
53+
4154func init () {
4255 catalogSearchCmd .Flags ().String ("profile" , auth .ProfileDefault , "credential profile name" )
4356 catalogSearchCmd .Flags ().String ("service-type" , "" , "filter by service type (OData, REST, SOAP)" )
@@ -47,7 +60,11 @@ func init() {
4760 catalogSearchCmd .Flags ().Int ("offset" , 0 , "pagination offset" )
4861 catalogSearchCmd .Flags ().Bool ("json" , false , "output as JSON array" )
4962
63+ catalogShowCmd .Flags ().String ("profile" , auth .ProfileDefault , "credential profile name" )
64+ catalogShowCmd .Flags ().Bool ("json" , false , "output full JSON response" )
65+
5066 catalogCmd .AddCommand (catalogSearchCmd )
67+ catalogCmd .AddCommand (catalogShowCmd )
5168 rootCmd .AddCommand (catalogCmd )
5269}
5370
@@ -113,10 +130,7 @@ func outputTable(cmd *cobra.Command, resp *catalog.SearchResponse) error {
113130 if item .Environment .Type == "Production" {
114131 prod = "Yes"
115132 }
116- uuid := item .UUID
117- if len (uuid ) >= 8 {
118- uuid = uuid [:8 ] // Short UUID
119- }
133+ uuid := item .UUID // Full UUID (36 chars) so users can use it with `show`
120134
121135 fmt .Fprintf (w , "%s\t %s\t %s\t %s\t %s\t %s\t %s\n " ,
122136 name , typ , version , app , env , prod , uuid )
@@ -134,6 +148,109 @@ func outputJSON(cmd *cobra.Command, data []catalog.SearchResult) error {
134148 return enc .Encode (data )
135149}
136150
151+ func runCatalogShow (cmd * cobra.Command , args []string ) error {
152+ uuid := args [0 ]
153+ profile , _ := cmd .Flags ().GetString ("profile" )
154+ asJSON , _ := cmd .Flags ().GetBool ("json" )
155+
156+ // Create client
157+ client , err := catalog .NewClient (cmd .Context (), profile )
158+ if err != nil {
159+ if _ , ok := err .(* auth.ErrNoCredential ); ok {
160+ return fmt .Errorf ("no credential found. Run: mxcli auth login" )
161+ }
162+ return err
163+ }
164+
165+ // Get endpoint details
166+ endpoint , err := client .GetEndpoint (cmd .Context (), uuid )
167+ if err != nil {
168+ if _ , ok := err .(* auth.ErrUnauthenticated ); ok {
169+ return fmt .Errorf ("authentication failed. Run: mxcli auth login" )
170+ }
171+ return err
172+ }
173+
174+ // Output
175+ if asJSON {
176+ enc := json .NewEncoder (cmd .OutOrStdout ())
177+ enc .SetIndent ("" , " " )
178+ return enc .Encode (endpoint )
179+ }
180+ return outputEndpointDetails (cmd , endpoint )
181+ }
182+
183+ func outputEndpointDetails (cmd * cobra.Command , ep * catalog.EndpointDetails ) error {
184+ w := cmd .OutOrStdout ()
185+ sv := ep .ServiceVersion
186+
187+ // Basic info
188+ fmt .Fprintf (w , "Name: %s\n " , sv .Description )
189+ fmt .Fprintf (w , "Type: %s\n " , sv .Type )
190+ fmt .Fprintf (w , "Version: %s\n " , sv .Version )
191+ fmt .Fprintf (w , "Application: %s\n " , ep .Environment .Application .Name )
192+ fmt .Fprintf (w , "Environment: %s (%s)\n " , ep .Environment .Type , ep .Environment .Location )
193+ if ep .Location != "" {
194+ fmt .Fprintf (w , "Location: %s\n " , ep .Location )
195+ }
196+ fmt .Fprintf (w , "\n " )
197+
198+ // Security
199+ if sv .SecurityScheme != nil && len (sv .SecurityScheme .SecurityTypes ) > 0 {
200+ var types []string
201+ for _ , st := range sv .SecurityScheme .SecurityTypes {
202+ types = append (types , st .Name )
203+ }
204+ fmt .Fprintf (w , "Security: %s\n " , strings .Join (types , ", " ))
205+ }
206+ fmt .Fprintf (w , "Validated: %v\n " , ep .Validated )
207+ fmt .Fprintf (w , "Last Updated: %s\n " , ep .LastUpdated )
208+ fmt .Fprintf (w , "\n " )
209+
210+ // Entities (OData only)
211+ if sv .TotalEntities > 0 {
212+ fmt .Fprintf (w , "Entities (%d):\n " , sv .TotalEntities )
213+ for _ , ent := range sv .Entities {
214+ fmt .Fprintf (w , " - %s (%d attributes" , ent .Name , ent .TotalAttributes )
215+ if ent .TotalAssociations > 0 {
216+ fmt .Fprintf (w , ", %d associations" , ent .TotalAssociations )
217+ }
218+ fmt .Fprintf (w , ")\n " )
219+
220+ // Show first 3 attributes
221+ if len (ent .Attributes ) > 0 {
222+ var attrNames []string
223+ for i , attr := range ent .Attributes {
224+ if i >= 3 {
225+ break
226+ }
227+ attrNames = append (attrNames , attr .Name )
228+ }
229+ fmt .Fprintf (w , " Attributes: %s" , strings .Join (attrNames , ", " ))
230+ if len (ent .Attributes ) > 3 {
231+ fmt .Fprintf (w , ", ..." )
232+ }
233+ fmt .Fprintf (w , "\n " )
234+ }
235+ }
236+ fmt .Fprintf (w , "\n " )
237+ }
238+
239+ // Actions (OData only)
240+ if sv .TotalActions > 0 {
241+ fmt .Fprintf (w , "Actions (%d):\n " , sv .TotalActions )
242+ for _ , action := range sv .Actions {
243+ fmt .Fprintf (w , " - %s" , action .Name )
244+ if action .TotalParameters > 0 {
245+ fmt .Fprintf (w , " (%d parameters)" , action .TotalParameters )
246+ }
247+ fmt .Fprintf (w , "\n " )
248+ }
249+ }
250+
251+ return nil
252+ }
253+
137254func truncate (s string , max int ) string {
138255 if len (s ) <= max {
139256 return s
0 commit comments