refactor(plugins): reorganize and sort type definitions for consistency

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2025-12-30 12:16:13 -05:00
parent f221c01bd9
commit 6ee64ceeec
7 changed files with 205 additions and 199 deletions

View File

@ -5,9 +5,11 @@ import (
"go/ast"
"go/parser"
"go/token"
"maps"
"os"
"path/filepath"
"regexp"
"slices"
"strings"
)
@ -180,15 +182,18 @@ func parseCapabilityFile(fset *token.FileSet, path string) ([]Capability, error)
// Recursively collect all struct dependencies
collectAllStructDependencies(referencedTypes, structMap)
// Sort type names for stable output order
sortedTypeNames := slices.Sorted(maps.Keys(referencedTypes))
// Attach referenced structs to the capability
for typeName := range referencedTypes {
for _, typeName := range sortedTypeNames {
if s, exists := structMap[typeName]; exists {
capability.Structs = append(capability.Structs, s)
}
}
// Attach referenced type aliases
for typeName := range referencedTypes {
for _, typeName := range sortedTypeNames {
if a, exists := aliasMap[typeName]; exists {
capability.TypeAliases = append(capability.TypeAliases, a)
}
@ -197,7 +202,8 @@ func parseCapabilityFile(fset *token.FileSet, path string) ([]Capability, error)
// Also attach type aliases prefixed with interface name (e.g., ScrobblerError for Scrobbler interface)
// This supports error types that are not directly referenced in method signatures
interfaceName := typeSpec.Name.Name
for typeName, a := range aliasMap {
for _, typeName := range slices.Sorted(maps.Keys(aliasMap)) {
a := aliasMap[typeName]
if strings.HasPrefix(typeName, interfaceName) && !referencedTypes[typeName] {
capability.TypeAliases = append(capability.TypeAliases, a)
referencedTypes[typeName] = true // Mark as referenced for const lookup
@ -368,8 +374,8 @@ func parseFile(fset *token.FileSet, path string) ([]Service, error) {
}
}
// Attach referenced structs to the service
for typeName := range referencedTypes {
// Attach referenced structs to the service (sorted for stable output)
for _, typeName := range slices.Sorted(maps.Keys(referencedTypes)) {
if s, exists := structMap[typeName]; exists {
service.Structs = append(service.Structs, s)
}

View File

@ -11,35 +11,9 @@ import (
pdk "github.com/extism/go-pdk"
)
// ArtistBiographyResponse is the response for GetArtistBiography.
type ArtistBiographyResponse struct {
// Biography is the artist biography text.
Biography string `json:"biography"`
}
// SimilarArtistsResponse is the response for GetSimilarArtists.
type SimilarArtistsResponse struct {
// Artists is the list of similar artists.
Artists []ArtistRef `json:"artists"`
}
// TopSongsResponse is the response for GetArtistTopSongs.
type TopSongsResponse struct {
// Songs is the list of top songs.
Songs []SongRef `json:"songs"`
}
// ArtistRef is a reference to an artist with name and optional MBID.
type ArtistRef struct {
// Name is the artist name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid,omitempty"`
}
// ArtistImagesResponse is the response for GetArtistImages.
type ArtistImagesResponse struct {
// Images is the list of artist images.
// AlbumImagesResponse is the response for GetAlbumImages.
type AlbumImagesResponse struct {
// Images is the list of album images.
Images []ImageInfo `json:"images"`
}
@ -55,34 +29,28 @@ type AlbumInfoResponse struct {
URL string `json:"url"`
}
// ImageInfo represents an image with URL and size.
type ImageInfo struct {
// URL is the URL of the image.
URL string `json:"url"`
// Size is the size of the image in pixels (width or height).
Size int32 `json:"size"`
}
// ArtistMBIDResponse is the response for GetArtistMBID.
type ArtistMBIDResponse struct {
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid"`
}
// ArtistURLResponse is the response for GetArtistURL.
type ArtistURLResponse struct {
// URL is the external URL for the artist.
URL string `json:"url"`
}
// SongRef is a reference to a song with name and optional MBID.
type SongRef struct {
// Name is the song name.
// AlbumRequest is the common request for album-related functions.
type AlbumRequest struct {
// Name is the album name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the song.
// Artist is the album artist name.
Artist string `json:"artist"`
// MBID is the MusicBrainz ID for the album (if known).
MBID string `json:"mbid,omitempty"`
}
// ArtistBiographyResponse is the response for GetArtistBiography.
type ArtistBiographyResponse struct {
// Biography is the artist biography text.
Biography string `json:"biography"`
}
// ArtistImagesResponse is the response for GetArtistImages.
type ArtistImagesResponse struct {
// Images is the list of artist images.
Images []ImageInfo `json:"images"`
}
// ArtistMBIDRequest is the request for GetArtistMBID.
type ArtistMBIDRequest struct {
// ID is the internal Navidrome artist ID.
@ -91,6 +59,20 @@ type ArtistMBIDRequest struct {
Name string `json:"name"`
}
// ArtistMBIDResponse is the response for GetArtistMBID.
type ArtistMBIDResponse struct {
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid"`
}
// ArtistRef is a reference to an artist with name and optional MBID.
type ArtistRef struct {
// Name is the artist name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid,omitempty"`
}
// ArtistRequest is the common request for artist-related functions.
type ArtistRequest struct {
// ID is the internal Navidrome artist ID.
@ -101,6 +83,20 @@ type ArtistRequest struct {
MBID string `json:"mbid,omitempty"`
}
// ArtistURLResponse is the response for GetArtistURL.
type ArtistURLResponse struct {
// URL is the external URL for the artist.
URL string `json:"url"`
}
// ImageInfo represents an image with URL and size.
type ImageInfo struct {
// URL is the URL of the image.
URL string `json:"url"`
// Size is the size of the image in pixels (width or height).
Size int32 `json:"size"`
}
// SimilarArtistsRequest is the request for GetSimilarArtists.
type SimilarArtistsRequest struct {
// ID is the internal Navidrome artist ID.
@ -113,6 +109,20 @@ type SimilarArtistsRequest struct {
Limit int32 `json:"limit"`
}
// SimilarArtistsResponse is the response for GetSimilarArtists.
type SimilarArtistsResponse struct {
// Artists is the list of similar artists.
Artists []ArtistRef `json:"artists"`
}
// SongRef is a reference to a song with name and optional MBID.
type SongRef struct {
// Name is the song name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the song.
MBID string `json:"mbid,omitempty"`
}
// TopSongsRequest is the request for GetArtistTopSongs.
type TopSongsRequest struct {
// ID is the internal Navidrome artist ID.
@ -125,20 +135,10 @@ type TopSongsRequest struct {
Count int32 `json:"count"`
}
// AlbumRequest is the common request for album-related functions.
type AlbumRequest struct {
// Name is the album name.
Name string `json:"name"`
// Artist is the album artist name.
Artist string `json:"artist"`
// MBID is the MusicBrainz ID for the album (if known).
MBID string `json:"mbid,omitempty"`
}
// AlbumImagesResponse is the response for GetAlbumImages.
type AlbumImagesResponse struct {
// Images is the list of album images.
Images []ImageInfo `json:"images"`
// TopSongsResponse is the response for GetArtistTopSongs.
type TopSongsResponse struct {
// Songs is the list of top songs.
Songs []SongRef `json:"songs"`
}
// Metadata is the marker interface for metadata plugins.

View File

@ -8,35 +8,9 @@
package metadata
// ArtistBiographyResponse is the response for GetArtistBiography.
type ArtistBiographyResponse struct {
// Biography is the artist biography text.
Biography string `json:"biography"`
}
// SimilarArtistsResponse is the response for GetSimilarArtists.
type SimilarArtistsResponse struct {
// Artists is the list of similar artists.
Artists []ArtistRef `json:"artists"`
}
// TopSongsResponse is the response for GetArtistTopSongs.
type TopSongsResponse struct {
// Songs is the list of top songs.
Songs []SongRef `json:"songs"`
}
// ArtistRef is a reference to an artist with name and optional MBID.
type ArtistRef struct {
// Name is the artist name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid,omitempty"`
}
// ArtistImagesResponse is the response for GetArtistImages.
type ArtistImagesResponse struct {
// Images is the list of artist images.
// AlbumImagesResponse is the response for GetAlbumImages.
type AlbumImagesResponse struct {
// Images is the list of album images.
Images []ImageInfo `json:"images"`
}
@ -52,34 +26,28 @@ type AlbumInfoResponse struct {
URL string `json:"url"`
}
// ImageInfo represents an image with URL and size.
type ImageInfo struct {
// URL is the URL of the image.
URL string `json:"url"`
// Size is the size of the image in pixels (width or height).
Size int32 `json:"size"`
}
// ArtistMBIDResponse is the response for GetArtistMBID.
type ArtistMBIDResponse struct {
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid"`
}
// ArtistURLResponse is the response for GetArtistURL.
type ArtistURLResponse struct {
// URL is the external URL for the artist.
URL string `json:"url"`
}
// SongRef is a reference to a song with name and optional MBID.
type SongRef struct {
// Name is the song name.
// AlbumRequest is the common request for album-related functions.
type AlbumRequest struct {
// Name is the album name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the song.
// Artist is the album artist name.
Artist string `json:"artist"`
// MBID is the MusicBrainz ID for the album (if known).
MBID string `json:"mbid,omitempty"`
}
// ArtistBiographyResponse is the response for GetArtistBiography.
type ArtistBiographyResponse struct {
// Biography is the artist biography text.
Biography string `json:"biography"`
}
// ArtistImagesResponse is the response for GetArtistImages.
type ArtistImagesResponse struct {
// Images is the list of artist images.
Images []ImageInfo `json:"images"`
}
// ArtistMBIDRequest is the request for GetArtistMBID.
type ArtistMBIDRequest struct {
// ID is the internal Navidrome artist ID.
@ -88,6 +56,20 @@ type ArtistMBIDRequest struct {
Name string `json:"name"`
}
// ArtistMBIDResponse is the response for GetArtistMBID.
type ArtistMBIDResponse struct {
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid"`
}
// ArtistRef is a reference to an artist with name and optional MBID.
type ArtistRef struct {
// Name is the artist name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the artist.
MBID string `json:"mbid,omitempty"`
}
// ArtistRequest is the common request for artist-related functions.
type ArtistRequest struct {
// ID is the internal Navidrome artist ID.
@ -98,6 +80,20 @@ type ArtistRequest struct {
MBID string `json:"mbid,omitempty"`
}
// ArtistURLResponse is the response for GetArtistURL.
type ArtistURLResponse struct {
// URL is the external URL for the artist.
URL string `json:"url"`
}
// ImageInfo represents an image with URL and size.
type ImageInfo struct {
// URL is the URL of the image.
URL string `json:"url"`
// Size is the size of the image in pixels (width or height).
Size int32 `json:"size"`
}
// SimilarArtistsRequest is the request for GetSimilarArtists.
type SimilarArtistsRequest struct {
// ID is the internal Navidrome artist ID.
@ -110,6 +106,20 @@ type SimilarArtistsRequest struct {
Limit int32 `json:"limit"`
}
// SimilarArtistsResponse is the response for GetSimilarArtists.
type SimilarArtistsResponse struct {
// Artists is the list of similar artists.
Artists []ArtistRef `json:"artists"`
}
// SongRef is a reference to a song with name and optional MBID.
type SongRef struct {
// Name is the song name.
Name string `json:"name"`
// MBID is the MusicBrainz ID for the song.
MBID string `json:"mbid,omitempty"`
}
// TopSongsRequest is the request for GetArtistTopSongs.
type TopSongsRequest struct {
// ID is the internal Navidrome artist ID.
@ -122,20 +132,10 @@ type TopSongsRequest struct {
Count int32 `json:"count"`
}
// AlbumRequest is the common request for album-related functions.
type AlbumRequest struct {
// Name is the album name.
Name string `json:"name"`
// Artist is the album artist name.
Artist string `json:"artist"`
// MBID is the MusicBrainz ID for the album (if known).
MBID string `json:"mbid,omitempty"`
}
// AlbumImagesResponse is the response for GetAlbumImages.
type AlbumImagesResponse struct {
// Images is the list of album images.
Images []ImageInfo `json:"images"`
// TopSongsResponse is the response for GetArtistTopSongs.
type TopSongsResponse struct {
// Songs is the list of top songs.
Songs []SongRef `json:"songs"`
}
// Metadata is the marker interface for metadata plugins.

View File

@ -26,6 +26,20 @@ const (
// Error implements the error interface for ScrobblerError.
func (e ScrobblerError) Error() string { return string(e) }
// IsAuthorizedRequest is the request for authorization check.
type IsAuthorizedRequest struct {
// UserID is the internal Navidrome user ID.
UserID string `json:"userId"`
// Username is the username of the user.
Username string `json:"username"`
}
// IsAuthorizedResponse is the response for authorization check.
type IsAuthorizedResponse struct {
// Authorized indicates whether the user is authorized to scrobble.
Authorized bool `json:"authorized"`
}
// NowPlayingRequest is the request for now playing notification.
type NowPlayingRequest struct {
// UserID is the internal Navidrome user ID.
@ -82,20 +96,6 @@ type TrackInfo struct {
MBZReleaseTrackID string `json:"mbzReleaseTrackId,omitempty"`
}
// IsAuthorizedRequest is the request for authorization check.
type IsAuthorizedRequest struct {
// UserID is the internal Navidrome user ID.
UserID string `json:"userId"`
// Username is the username of the user.
Username string `json:"username"`
}
// IsAuthorizedResponse is the response for authorization check.
type IsAuthorizedResponse struct {
// Authorized indicates whether the user is authorized to scrobble.
Authorized bool `json:"authorized"`
}
// Scrobbler requires all methods to be implemented.
// Scrobbler provides scrobbling functionality to external services.
// This capability allows plugins to submit listening history to services like Last.fm,

View File

@ -23,6 +23,20 @@ const (
// Error implements the error interface for ScrobblerError.
func (e ScrobblerError) Error() string { return string(e) }
// IsAuthorizedRequest is the request for authorization check.
type IsAuthorizedRequest struct {
// UserID is the internal Navidrome user ID.
UserID string `json:"userId"`
// Username is the username of the user.
Username string `json:"username"`
}
// IsAuthorizedResponse is the response for authorization check.
type IsAuthorizedResponse struct {
// Authorized indicates whether the user is authorized to scrobble.
Authorized bool `json:"authorized"`
}
// NowPlayingRequest is the request for now playing notification.
type NowPlayingRequest struct {
// UserID is the internal Navidrome user ID.
@ -79,20 +93,6 @@ type TrackInfo struct {
MBZReleaseTrackID string `json:"mbzReleaseTrackId,omitempty"`
}
// IsAuthorizedRequest is the request for authorization check.
type IsAuthorizedRequest struct {
// UserID is the internal Navidrome user ID.
UserID string `json:"userId"`
// Username is the username of the user.
Username string `json:"username"`
}
// IsAuthorizedResponse is the response for authorization check.
type IsAuthorizedResponse struct {
// Authorized indicates whether the user is authorized to scrobble.
Authorized bool `json:"authorized"`
}
// Scrobbler requires all methods to be implemented.
// Scrobbler provides scrobbling functionality to external services.
// This capability allows plugins to submit listening history to services like Last.fm,

View File

@ -11,14 +11,6 @@ import (
pdk "github.com/extism/go-pdk"
)
// OnTextMessageRequest is the request provided when a text message is received.
type OnTextMessageRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that received the message.
ConnectionID string `json:"connectionId"`
// Message is the text message content received from the WebSocket.
Message string `json:"message"`
}
// OnBinaryMessageRequest is the request provided when a binary message is received.
type OnBinaryMessageRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that received the message.
@ -27,14 +19,6 @@ type OnBinaryMessageRequest struct {
Data string `json:"data"`
}
// OnErrorRequest is the request provided when an error occurs on a WebSocket connection.
type OnErrorRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection where the error occurred.
ConnectionID string `json:"connectionId"`
// Error is the error message describing what went wrong.
Error string `json:"error"`
}
// OnCloseRequest is the request provided when a WebSocket connection is closed.
type OnCloseRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that was closed.
@ -46,6 +30,22 @@ type OnCloseRequest struct {
Reason string `json:"reason"`
}
// OnErrorRequest is the request provided when an error occurs on a WebSocket connection.
type OnErrorRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection where the error occurred.
ConnectionID string `json:"connectionId"`
// Error is the error message describing what went wrong.
Error string `json:"error"`
}
// OnTextMessageRequest is the request provided when a text message is received.
type OnTextMessageRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that received the message.
ConnectionID string `json:"connectionId"`
// Message is the text message content received from the WebSocket.
Message string `json:"message"`
}
// WebSocket is the marker interface for websocket plugins.
// Implement one or more of the provider interfaces below.
// WebSocketCallback provides WebSocket message handling.

View File

@ -8,14 +8,6 @@
package websocket
// OnTextMessageRequest is the request provided when a text message is received.
type OnTextMessageRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that received the message.
ConnectionID string `json:"connectionId"`
// Message is the text message content received from the WebSocket.
Message string `json:"message"`
}
// OnBinaryMessageRequest is the request provided when a binary message is received.
type OnBinaryMessageRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that received the message.
@ -24,14 +16,6 @@ type OnBinaryMessageRequest struct {
Data string `json:"data"`
}
// OnErrorRequest is the request provided when an error occurs on a WebSocket connection.
type OnErrorRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection where the error occurred.
ConnectionID string `json:"connectionId"`
// Error is the error message describing what went wrong.
Error string `json:"error"`
}
// OnCloseRequest is the request provided when a WebSocket connection is closed.
type OnCloseRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that was closed.
@ -43,6 +27,22 @@ type OnCloseRequest struct {
Reason string `json:"reason"`
}
// OnErrorRequest is the request provided when an error occurs on a WebSocket connection.
type OnErrorRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection where the error occurred.
ConnectionID string `json:"connectionId"`
// Error is the error message describing what went wrong.
Error string `json:"error"`
}
// OnTextMessageRequest is the request provided when a text message is received.
type OnTextMessageRequest struct {
// ConnectionID is the unique identifier for the WebSocket connection that received the message.
ConnectionID string `json:"connectionId"`
// Message is the text message content received from the WebSocket.
Message string `json:"message"`
}
// WebSocket is the marker interface for websocket plugins.
// Implement one or more of the provider interfaces below.
// WebSocketCallback provides WebSocket message handling.