@@ -141,66 +141,88 @@ func ServerJSONToRemoteServerMetadata(serverJSON *upstream.ServerJSON) (*registr
141141
142142// extractImageExtensions extracts publisher-provided extensions into ImageMetadata
143143func extractImageExtensions (serverJSON * upstream.ServerJSON , imageMetadata * registry.ImageMetadata ) {
144- if serverJSON .Meta == nil || serverJSON .Meta .PublisherProvided == nil {
144+ extensions := getStacklokExtensions (serverJSON )
145+ if extensions == nil {
145146 return
146147 }
147148
149+ extractBasicImageFields (extensions , imageMetadata )
150+ extractImageMetadataField (extensions , imageMetadata )
151+ extractComplexImageFields (extensions , imageMetadata )
152+ }
153+
154+ // getStacklokExtensions retrieves the first stacklok extension data from ServerJSON
155+ func getStacklokExtensions (serverJSON * upstream.ServerJSON ) map [string ]interface {} {
156+ if serverJSON .Meta == nil || serverJSON .Meta .PublisherProvided == nil {
157+ return nil
158+ }
159+
148160 stacklokData , ok := serverJSON .Meta .PublisherProvided ["io.github.stacklok" ].(map [string ]interface {})
149161 if ! ok {
150- return
162+ return nil
151163 }
152164
153- // Find the extension data (keyed by image reference)
165+ // Return first extension data (keyed by image reference or URL )
154166 for _ , extensionsData := range stacklokData {
155- extensions , ok := extensionsData .(map [string ]interface {})
156- if ! ok {
157- continue
167+ if extensions , ok := extensionsData .(map [string ]interface {}); ok {
168+ return extensions
158169 }
170+ }
171+ return nil
172+ }
159173
160- // Extract fields
161- if status , ok := extensions ["status" ].(string ); ok {
162- imageMetadata .Status = status
163- }
164- if tier , ok := extensions ["tier" ].(string ); ok {
165- imageMetadata .Tier = tier
166- }
167- if toolsData , ok := extensions ["tools" ].([]interface {}); ok {
168- imageMetadata .Tools = interfaceSliceToStringSlice (toolsData )
169- }
170- if tagsData , ok := extensions ["tags" ].([]interface {}); ok {
171- imageMetadata .Tags = interfaceSliceToStringSlice (tagsData )
172- }
173- if metadataData , ok := extensions ["metadata" ].(map [string ]interface {}); ok {
174- imageMetadata .Metadata = & registry.Metadata {}
175- if stars , ok := metadataData ["stars" ].(float64 ); ok {
176- imageMetadata .Metadata .Stars = int (stars )
177- }
178- if pulls , ok := metadataData ["pulls" ].(float64 ); ok {
179- imageMetadata .Metadata .Pulls = int (pulls )
180- }
181- if lastUpdated , ok := metadataData ["last_updated" ].(string ); ok {
182- imageMetadata .Metadata .LastUpdated = lastUpdated
183- }
184- }
174+ // extractBasicImageFields extracts basic string and slice fields
175+ func extractBasicImageFields (extensions map [string ]interface {}, imageMetadata * registry.ImageMetadata ) {
176+ if status , ok := extensions ["status" ].(string ); ok {
177+ imageMetadata .Status = status
178+ }
179+ if tier , ok := extensions ["tier" ].(string ); ok {
180+ imageMetadata .Tier = tier
181+ }
182+ if toolsData , ok := extensions ["tools" ].([]interface {}); ok {
183+ imageMetadata .Tools = interfaceSliceToStringSlice (toolsData )
184+ }
185+ if tagsData , ok := extensions ["tags" ].([]interface {}); ok {
186+ imageMetadata .Tags = interfaceSliceToStringSlice (tagsData )
187+ }
188+ }
185189
186- // Extract args (fallback if PackageArguments wasn't used )
187- if len ( imageMetadata . Args ) == 0 {
188- if argsData , ok := extensions ["args " ].([ ]interface {}); ok {
189- imageMetadata . Args = interfaceSliceToStringSlice ( argsData )
190- }
191- }
190+ // extractImageMetadataField extracts the metadata object (stars, pulls, last_updated )
191+ func extractImageMetadataField ( extensions map [ string ] interface {}, imageMetadata * registry. ImageMetadata ) {
192+ metadataData , ok := extensions ["metadata " ].(map [ string ]interface {})
193+ if ! ok {
194+ return
195+ }
192196
193- // Extract permissions using JSON round-trip
194- if permsData , ok := extensions ["permissions" ]; ok {
195- imageMetadata .Permissions = remarshalToType [* permissions.Profile ](permsData )
196- }
197+ imageMetadata .Metadata = & registry.Metadata {}
198+ if stars , ok := metadataData ["stars" ].(float64 ); ok {
199+ imageMetadata .Metadata .Stars = int (stars )
200+ }
201+ if pulls , ok := metadataData ["pulls" ].(float64 ); ok {
202+ imageMetadata .Metadata .Pulls = int (pulls )
203+ }
204+ if lastUpdated , ok := metadataData ["last_updated" ].(string ); ok {
205+ imageMetadata .Metadata .LastUpdated = lastUpdated
206+ }
207+ }
197208
198- // Extract provenance using JSON round-trip
199- if provData , ok := extensions ["provenance" ]; ok {
200- imageMetadata .Provenance = remarshalToType [* registry.Provenance ](provData )
209+ // extractComplexImageFields extracts complex fields (args, permissions, provenance)
210+ func extractComplexImageFields (extensions map [string ]interface {}, imageMetadata * registry.ImageMetadata ) {
211+ // Extract args (fallback if PackageArguments wasn't used)
212+ if len (imageMetadata .Args ) == 0 {
213+ if argsData , ok := extensions ["args" ].([]interface {}); ok {
214+ imageMetadata .Args = interfaceSliceToStringSlice (argsData )
201215 }
216+ }
202217
203- break // Only process first entry
218+ // Extract permissions using JSON round-trip
219+ if permsData , ok := extensions ["permissions" ]; ok {
220+ imageMetadata .Permissions = remarshalToType [* permissions.Profile ](permsData )
221+ }
222+
223+ // Extract provenance using JSON round-trip
224+ if provData , ok := extensions ["provenance" ]; ok {
225+ imageMetadata .Provenance = remarshalToType [* registry.Provenance ](provData )
204226 }
205227}
206228
0 commit comments