From 8abb99ac91a7bb3350799161f2567e85a1ad311d Mon Sep 17 00:00:00 2001 From: zarzet Date: Fri, 10 Jul 2026 06:26:45 +0700 Subject: [PATCH] chore(backend): modernize interface{} to any, silence lint noise gofmt -r rewrite of all 506 interface{} occurrences to the any alias (identical semantics), drop unused spec constants into comments, rename unused parameters to _, convert three if-else chains to tagged switches, and use slices.ContainsFunc for the private-IP check. No behavior change; the whole package is now gofmt-clean. --- go_backend/ac4_config.go | 5 +- go_backend/ac4_metadata.go | 10 +- go_backend/ape_tags.go | 7 +- go_backend/cross_extension_share.go | 4 +- go_backend/cross_extension_share_test.go | 8 +- go_backend/deezer.go | 4 +- go_backend/exports.go | 4 +- go_backend/exports_deezer.go | 12 +- go_backend/exports_extensions.go | 120 ++++++------- go_backend/exports_lyrics.go | 10 +- go_backend/exports_metadata.go | 4 +- go_backend/exports_reenrich.go | 6 +- ...exports_songlink_lyrics_supplement_test.go | 7 +- go_backend/extension_fallback.go | 6 +- go_backend/extension_goja_convert.go | 6 +- go_backend/extension_health.go | 10 +- .../extension_health_misc_supplement_test.go | 2 +- go_backend/extension_manager.go | 30 ++-- .../extension_manager_supplement_test.go | 4 +- go_backend/extension_manifest.go | 6 +- .../extension_provider_supplement_test.go | 10 +- go_backend/extension_provider_types.go | 14 +- go_backend/extension_provider_wrapper.go | 16 +- go_backend/extension_providers.go | 4 +- go_backend/extension_runtime.go | 21 +-- go_backend/extension_runtime_auth.go | 70 ++++---- go_backend/extension_runtime_binary.go | 66 ++++---- go_backend/extension_runtime_ffmpeg.go | 18 +- go_backend/extension_runtime_file.go | 160 +++++++++--------- go_backend/extension_runtime_http.go | 80 ++++----- go_backend/extension_runtime_polyfills.go | 22 +-- go_backend/extension_runtime_storage.go | 32 ++-- go_backend/extension_runtime_storage_test.go | 8 +- .../extension_runtime_supplement_test.go | 108 ++++++------ go_backend/extension_runtime_utils.go | 54 +++--- go_backend/extension_settings.go | 26 +-- go_backend/extension_signed_session.go | 44 ++--- go_backend/filename.go | 32 ++-- go_backend/filename_test.go | 12 +- go_backend/logbuffer.go | 10 +- go_backend/lyrics.go | 6 +- go_backend/metadata.go | 7 +- go_backend/metadata_types.go | 2 +- go_backend/misc_coverage_supplement_test.go | 18 +- go_backend/output_fd_windows.go | 4 +- go_backend/progress.go | 2 +- go_backend/wav_aiff.go | 9 +- 47 files changed, 559 insertions(+), 561 deletions(-) diff --git a/go_backend/ac4_config.go b/go_backend/ac4_config.go index cdf82a3e..edd2a452 100644 --- a/go_backend/ac4_config.go +++ b/go_backend/ac4_config.go @@ -25,13 +25,14 @@ func readMP4Box(data []byte, pos int64) (mp4Box, bool) { size := int64(binary.BigEndian.Uint32(data[pos : pos+4])) typ := string(data[pos+4 : pos+8]) hdr := int64(8) - if size == 1 { + switch size { + case 1: if pos+16 > n { return mp4Box{}, false } size = int64(binary.BigEndian.Uint64(data[pos+8 : pos+16])) hdr = 16 - } else if size == 0 { + case 0: size = n - pos } if size < hdr || pos+size > n { diff --git a/go_backend/ac4_metadata.go b/go_backend/ac4_metadata.go index cf6b0862..d87b5087 100644 --- a/go_backend/ac4_metadata.go +++ b/go_backend/ac4_metadata.go @@ -67,12 +67,12 @@ func itunesCoverTag(image []byte) []byte { func itunesMetadataHandler() []byte { payload := make([]byte, 0, 25) - payload = append(payload, 0, 0, 0, 0) // version + flags - payload = append(payload, 0, 0, 0, 0) // pre_defined - payload = append(payload, []byte("mdir")...) // handler type - payload = append(payload, []byte("appl")...) // reserved[0] + payload = append(payload, 0, 0, 0, 0) // version + flags + payload = append(payload, 0, 0, 0, 0) // pre_defined + payload = append(payload, []byte("mdir")...) // handler type + payload = append(payload, []byte("appl")...) // reserved[0] payload = append(payload, 0, 0, 0, 0, 0, 0, 0, 0) // reserved[1..2] - payload = append(payload, 0) // empty name + payload = append(payload, 0) // empty name return buildM4AAtom("hdlr", payload) } diff --git a/go_backend/ape_tags.go b/go_backend/ape_tags.go index f210daf3..a8e449ad 100644 --- a/go_backend/ape_tags.go +++ b/go_backend/ape_tags.go @@ -16,9 +16,8 @@ const ( apeTagFlagHeader = 1 << 29 // bit 29: this is the header, not the footer apeTagFlagReadOnly = 1 << 0 // Item flags: bits 1-2 encode content type - apeItemFlagUTF8 = 0 << 1 // 00: UTF-8 text - apeItemFlagBinary = 1 << 1 // 01: binary data - apeItemFlagLink = 2 << 1 // 10: external link + // (00: UTF-8 text, 01: binary data, 10: external link) + apeItemFlagBinary = 1 << 1 ) // APETagItem represents a single key-value item in an APEv2 tag. @@ -563,7 +562,7 @@ func ReadAPETagsFromReader(r io.ReaderAt, fileSize int64) (*APETag, error) { return nil, fmt.Errorf("no APEv2 tag found") } -func parseAPETagFromFooter(r io.ReaderAt, fileSize, footerOffset int64, footer []byte) (*APETag, error) { +func parseAPETagFromFooter(r io.ReaderAt, _, footerOffset int64, footer []byte) (*APETag, error) { version := binary.LittleEndian.Uint32(footer[8:12]) tagSize := binary.LittleEndian.Uint32(footer[12:16]) itemCount := binary.LittleEndian.Uint32(footer[16:20]) diff --git a/go_backend/cross_extension_share.go b/go_backend/cross_extension_share.go index 7ae2c3f1..18cdb11c 100644 --- a/go_backend/cross_extension_share.go +++ b/go_backend/cross_extension_share.go @@ -241,7 +241,7 @@ func searchCollectionCandidates(provider *extensionProviderWrapper, itemType str } if filter != "" { - tracks, err := provider.CustomSearch(query, map[string]interface{}{ + tracks, err := provider.CustomSearch(query, map[string]any{ "filter": filter, "limit": 10, }) @@ -409,7 +409,7 @@ func templateShareURL(ext *loadedExtension, itemType string, id string) string { return "" } - templates, ok := ext.Manifest.Capabilities["shareUrlTemplates"].(map[string]interface{}) + templates, ok := ext.Manifest.Capabilities["shareUrlTemplates"].(map[string]any) if !ok { return "" } diff --git a/go_backend/cross_extension_share_test.go b/go_backend/cross_extension_share_test.go index 76271d64..ac936221 100644 --- a/go_backend/cross_extension_share_test.go +++ b/go_backend/cross_extension_share_test.go @@ -5,8 +5,8 @@ import "testing" func TestCrossExtensionShareUsesAlbumCollectionItems(t *testing.T) { ext := &loadedExtension{ Manifest: &ExtensionManifest{ - Capabilities: map[string]interface{}{ - "shareUrlTemplates": map[string]interface{}{ + Capabilities: map[string]any{ + "shareUrlTemplates": map[string]any{ "album": "https://music.apple.com/us/album/{id}", }, }, @@ -33,8 +33,8 @@ func TestCrossExtensionShareUsesAlbumCollectionItems(t *testing.T) { func TestCrossExtensionShareUsesArtistCollectionItems(t *testing.T) { ext := &loadedExtension{ Manifest: &ExtensionManifest{ - Capabilities: map[string]interface{}{ - "shareUrlTemplates": map[string]interface{}{ + Capabilities: map[string]any{ + "shareUrlTemplates": map[string]any{ "artist": "https://music.youtube.com/browse/{id}", }, }, diff --git a/go_backend/deezer.go b/go_backend/deezer.go index 8506afd8..ab13ac58 100644 --- a/go_backend/deezer.go +++ b/go_backend/deezer.go @@ -1263,7 +1263,7 @@ func (c *DeezerClient) GetExtendedMetadataByISRC(ctx context.Context, isrc strin return c.GetExtendedMetadataByTrackID(ctx, deezerID) } -func (c *DeezerClient) getJSON(ctx context.Context, endpoint string, dst interface{}) error { +func (c *DeezerClient) getJSON(ctx context.Context, endpoint string, dst any) error { var lastErr error for attempt := 0; attempt <= deezerMaxRetries; attempt++ { @@ -1309,7 +1309,7 @@ func isDeezerRetryableError(err error) bool { return false } -func (c *DeezerClient) doGetJSON(ctx context.Context, endpoint string, dst interface{}) error { +func (c *DeezerClient) doGetJSON(ctx context.Context, endpoint string, dst any) error { req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil) if err != nil { return err diff --git a/go_backend/exports.go b/go_backend/exports.go index 4759e736..70fa89f0 100644 --- a/go_backend/exports.go +++ b/go_backend/exports.go @@ -39,7 +39,7 @@ func AllowDownloadDir(path string) { func CheckDuplicate(outputDir, isrc string) (string, error) { existingFile, exists := CheckISRCExists(outputDir, isrc) - result := map[string]interface{}{ + result := map[string]any{ "exists": exists, "filepath": existingFile, } @@ -65,7 +65,7 @@ func InvalidateDuplicateIndex(outputDir string) { } func BuildFilename(template string, metadataJSON string) (string, error) { - var metadata map[string]interface{} + var metadata map[string]any if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil { return "", err } diff --git a/go_backend/exports_deezer.go b/go_backend/exports_deezer.go index 1c9c379e..c7d8763d 100644 --- a/go_backend/exports_deezer.go +++ b/go_backend/exports_deezer.go @@ -34,7 +34,7 @@ func PreWarmTrackCacheJSON(tracksJSON string) (string, error) { go PreWarmTrackCache(requests) - resp := map[string]interface{}{ + resp := map[string]any{ "success": true, "message": fmt.Sprintf("Pre-warming cache for %d tracks in background", len(tracks)), } @@ -61,7 +61,7 @@ func GetDeezerRelatedArtists(artistID string, limit int) (string, error) { return "", err } - resp := map[string]interface{}{ + resp := map[string]any{ "artists": artists, } jsonBytes, err := json.Marshal(resp) @@ -76,7 +76,7 @@ func GetDeezerMetadata(resourceType, resourceID string) (string, error) { defer cancel() client := GetDeezerClient() - var data interface{} + var data any var err error switch resourceType { @@ -183,12 +183,12 @@ func buildDeezerExtendedMetadataResult(metadata *AlbumExtendedMetadata) map[stri } } -func buildDeezerISRCSearchResult(track *TrackMetadata) map[string]interface{} { +func buildDeezerISRCSearchResult(track *TrackMetadata) map[string]any { if track == nil { - return map[string]interface{}{} + return map[string]any{} } - result := map[string]interface{}{ + result := map[string]any{ "spotify_id": track.SpotifyID, "artists": track.Artists, "name": track.Name, diff --git a/go_backend/exports_extensions.go b/go_backend/exports_extensions.go index c0384b32..9a96ee6b 100644 --- a/go_backend/exports_extensions.go +++ b/go_backend/exports_extensions.go @@ -15,7 +15,7 @@ func normalizeExtensionTrackMetadataMap( track ExtTrackMetadata, fallbackCover string, fallbackTrackNumber int, -) map[string]interface{} { +) map[string]any { coverURL := track.ResolvedCoverURL() if coverURL == "" { coverURL = fallbackCover @@ -26,7 +26,7 @@ func normalizeExtensionTrackMetadataMap( trackNum = fallbackTrackNumber } - return map[string]interface{}{ + return map[string]any{ "id": track.ID, "name": track.Name, "artists": track.Artists, @@ -57,12 +57,12 @@ func normalizeExtensionTrackMetadataMap( } } -func normalizeExtensionAlbumInfoMap(album *ExtAlbumMetadata) map[string]interface{} { +func normalizeExtensionAlbumInfoMap(album *ExtAlbumMetadata) map[string]any { if album == nil { - return map[string]interface{}{} + return map[string]any{} } - return map[string]interface{}{ + return map[string]any{ "id": album.ID, "name": album.Name, "artists": album.Artists, @@ -79,8 +79,8 @@ func normalizeExtensionAlbumInfoMap(album *ExtAlbumMetadata) map[string]interfac } } -func normalizeExtensionArtistAlbumMap(album ExtAlbumMetadata) map[string]interface{} { - return map[string]interface{}{ +func normalizeExtensionArtistAlbumMap(album ExtAlbumMetadata) map[string]any { + return map[string]any{ "id": album.ID, "name": album.Name, "artists": album.Artists, @@ -97,7 +97,7 @@ func getExtensionProviderMetadataResponse( providerID, resourceType, resourceID string, -) (map[string]interface{}, error) { +) (map[string]any, error) { manager := getExtensionManager() ext, err := manager.GetExtension(providerID) if err != nil { @@ -122,7 +122,7 @@ func getExtensionProviderMetadataResponse( if track == nil { return nil, fmt.Errorf("track not found") } - return map[string]interface{}{ + return map[string]any{ "track": normalizeExtensionTrackMetadataMap(*track, "", 0), }, nil case "album": @@ -134,12 +134,12 @@ func getExtensionProviderMetadataResponse( return nil, fmt.Errorf("album not found") } - tracks := make([]map[string]interface{}, len(album.Tracks)) + tracks := make([]map[string]any, len(album.Tracks)) for i, track := range album.Tracks { tracks[i] = normalizeExtensionTrackMetadataMap(track, album.CoverURL, i+1) } - return map[string]interface{}{ + return map[string]any{ "album_info": normalizeExtensionAlbumInfoMap(album), "track_list": tracks, }, nil @@ -152,13 +152,13 @@ func getExtensionProviderMetadataResponse( return nil, fmt.Errorf("playlist not found") } - tracks := make([]map[string]interface{}, len(playlist.Tracks)) + tracks := make([]map[string]any, len(playlist.Tracks)) for i, track := range playlist.Tracks { tracks[i] = normalizeExtensionTrackMetadataMap(track, playlist.CoverURL, i+1) } - return map[string]interface{}{ - "playlist_info": map[string]interface{}{ + return map[string]any{ + "playlist_info": map[string]any{ "id": playlist.ID, "name": playlist.Name, "images": playlist.CoverURL, @@ -166,7 +166,7 @@ func getExtensionProviderMetadataResponse( "header_image": playlist.HeaderImage, "header_video": playlist.HeaderVideo, "provider_id": playlist.ProviderID, - "owner": map[string]interface{}{ + "owner": map[string]any{ "name": playlist.Artists, "images": playlist.CoverURL, }, @@ -182,13 +182,13 @@ func getExtensionProviderMetadataResponse( return nil, fmt.Errorf("artist not found") } - albums := make([]map[string]interface{}, len(artist.Albums)) + albums := make([]map[string]any, len(artist.Albums)) for i, album := range artist.Albums { albums[i] = normalizeExtensionArtistAlbumMap(album) } - response := map[string]interface{}{ - "artist_info": map[string]interface{}{ + response := map[string]any{ + "artist_info": map[string]any{ "id": artist.ID, "name": artist.Name, "images": firstNonEmptyTrimmed(artist.HeaderImage, artist.ImageURL), @@ -201,7 +201,7 @@ func getExtensionProviderMetadataResponse( } if len(artist.Releases) > 0 { - releases := make([]map[string]interface{}, len(artist.Releases)) + releases := make([]map[string]any, len(artist.Releases)) for i, release := range artist.Releases { releases[i] = normalizeExtensionArtistAlbumMap(release) } @@ -209,12 +209,12 @@ func getExtensionProviderMetadataResponse( } if artist.Listeners > 0 { - artistInfo := response["artist_info"].(map[string]interface{}) + artistInfo := response["artist_info"].(map[string]any) artistInfo["listeners"] = artist.Listeners } if len(artist.TopTracks) > 0 { - topTracks := make([]map[string]interface{}, len(artist.TopTracks)) + topTracks := make([]map[string]any, len(artist.TopTracks)) for i, track := range artist.TopTracks { topTracks[i] = normalizeExtensionTrackMetadataMap(track, artist.ImageURL, i+1) } @@ -269,7 +269,7 @@ func GetProviderMetadataJSON(providerID, resourceType, resourceID string) (strin } } -func getEnabledExtensionProviderMetadataResponse(providerID, resourceType, resourceID string) (map[string]interface{}, bool, error) { +func getEnabledExtensionProviderMetadataResponse(providerID, resourceType, resourceID string) (map[string]any, bool, error) { manager := getExtensionManager() ext, err := manager.GetExtension(providerID) if err != nil || ext == nil || !ext.Enabled || !ext.Manifest.IsMetadataProvider() { @@ -300,7 +300,7 @@ func LoadExtensionsFromDir(dirPath string) (string, error) { manager := getExtensionManager() loaded, errors := manager.LoadExtensionsFromDirectory(dirPath) - result := map[string]interface{}{ + result := map[string]any{ "loaded": loaded, "errors": make([]string, len(errors)), } @@ -324,7 +324,7 @@ func LoadExtensionFromPath(filePath string) (string, error) { return "", err } - result := map[string]interface{}{ + result := map[string]any{ "id": ext.ID, "name": ext.Manifest.Name, "display_name": ext.Manifest.DisplayName, @@ -357,7 +357,7 @@ func UpgradeExtensionFromPath(filePath string) (string, error) { return "", err } - result := map[string]interface{}{ + result := map[string]any{ "id": ext.ID, "display_name": ext.Manifest.DisplayName, "version": ext.Manifest.Version, @@ -462,7 +462,7 @@ func GetExtensionSettingsJSON(extensionID string) (string, error) { } func SetExtensionSettingsJSON(extensionID, settingsJSON string) error { - var settings map[string]interface{} + var settings map[string]any if err := json.Unmarshal([]byte(settingsJSON), &settings); err != nil { return err } @@ -576,7 +576,7 @@ func GetExtensionPendingAuthJSON(extensionID string) (string, error) { return "", nil } - result := map[string]interface{}{ + result := map[string]any{ "extension_id": req.ExtensionID, "auth_url": req.AuthURL, "callback_url": req.CallbackURL, @@ -670,9 +670,9 @@ func GetAllPendingAuthRequestsJSON() (string, error) { pendingAuthRequestsMu.RLock() defer pendingAuthRequestsMu.RUnlock() - requests := make([]map[string]interface{}, 0, len(pendingAuthRequests)) + requests := make([]map[string]any, 0, len(pendingAuthRequests)) for _, req := range pendingAuthRequests { - requests = append(requests, map[string]interface{}{ + requests = append(requests, map[string]any{ "extension_id": req.ExtensionID, "auth_url": req.AuthURL, "callback_url": req.CallbackURL, @@ -693,7 +693,7 @@ func GetPendingFFmpegCommandJSON(commandID string) (string, error) { return "", nil } - result := map[string]interface{}{ + result := map[string]any{ "command_id": commandID, "extension_id": cmd.ExtensionID, "command": cmd.Command, @@ -717,10 +717,10 @@ func GetAllPendingFFmpegCommandsJSON() (string, error) { ffmpegCommandsMu.RLock() defer ffmpegCommandsMu.RUnlock() - commands := make([]map[string]interface{}, 0) + commands := make([]map[string]any, 0) for cmdID, cmd := range ffmpegCommands { if !cmd.Completed { - commands = append(commands, map[string]interface{}{ + commands = append(commands, map[string]any{ "command_id": cmdID, "extension_id": cmd.ExtensionID, "command": cmd.Command, @@ -781,10 +781,10 @@ func CustomSearchWithExtensionJSONWithRequestID(extensionID, query string, optio return "", fmt.Errorf("extension '%s' does not support custom search", extensionID) } - var options map[string]interface{} + var options map[string]any if optionsJSON != "" { if err := json.Unmarshal([]byte(optionsJSON), &options); err != nil { - options = make(map[string]interface{}) + options = make(map[string]any) } } @@ -794,9 +794,9 @@ func CustomSearchWithExtensionJSONWithRequestID(extensionID, query string, optio return "", err } - result := make([]map[string]interface{}, len(tracks)) + result := make([]map[string]any, len(tracks)) for i, track := range tracks { - result[i] = map[string]interface{}{ + result[i] = map[string]any{ "id": track.ID, "name": track.Name, "artists": track.Artists, @@ -832,9 +832,9 @@ func GetSearchProvidersJSON() (string, error) { manager := getExtensionManager() providers := manager.GetSearchProviders() - result := make([]map[string]interface{}, 0, len(providers)) + result := make([]map[string]any, 0, len(providers)) for _, p := range providers { - result = append(result, map[string]interface{}{ + result = append(result, map[string]any{ "id": p.extension.ID, "display_name": p.extension.Manifest.DisplayName, "placeholder": p.extension.Manifest.SearchBehavior.Placeholder, @@ -865,7 +865,7 @@ func HandleURLWithExtensionJSON(url string) (string, error) { return "", fmt.Errorf("extension %s failed to handle URL", extensionID) } - response := map[string]interface{}{ + response := map[string]any{ "type": result.Type, "extension_id": extensionID, "name": result.Name, @@ -875,7 +875,7 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if result.Track != nil { - response["track"] = map[string]interface{}{ + response["track"] = map[string]any{ "id": result.Track.ID, "name": result.Track.Name, "artists": result.Track.Artists, @@ -896,9 +896,9 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if len(result.Tracks) > 0 { - tracks := make([]map[string]interface{}, len(result.Tracks)) + tracks := make([]map[string]any, len(result.Tracks)) for i, track := range result.Tracks { - tracks[i] = map[string]interface{}{ + tracks[i] = map[string]any{ "id": track.ID, "name": track.Name, "artists": track.Artists, @@ -923,7 +923,7 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if result.Album != nil { - response["album"] = map[string]interface{}{ + response["album"] = map[string]any{ "id": result.Album.ID, "name": result.Album.Name, "artists": result.Album.Artists, @@ -939,7 +939,7 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if result.Artist != nil { - artistResponse := map[string]interface{}{ + artistResponse := map[string]any{ "id": result.Artist.ID, "name": result.Artist.Name, "image_url": result.Artist.ImageURL, @@ -950,13 +950,13 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if len(result.Artist.Albums) > 0 { - albums := make([]map[string]interface{}, len(result.Artist.Albums)) + albums := make([]map[string]any, len(result.Artist.Albums)) for i, album := range result.Artist.Albums { albumType := album.AlbumType if albumType == "" { albumType = "album" } - albums[i] = map[string]interface{}{ + albums[i] = map[string]any{ "id": album.ID, "name": album.Name, "artists": album.Artists, @@ -972,13 +972,13 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if len(result.Artist.Releases) > 0 { - releases := make([]map[string]interface{}, len(result.Artist.Releases)) + releases := make([]map[string]any, len(result.Artist.Releases)) for i, release := range result.Artist.Releases { releaseType := release.AlbumType if releaseType == "" { releaseType = "album" } - releases[i] = map[string]interface{}{ + releases[i] = map[string]any{ "id": release.ID, "name": release.Name, "artists": release.Artists, @@ -994,9 +994,9 @@ func HandleURLWithExtensionJSON(url string) (string, error) { } if len(result.Artist.TopTracks) > 0 { - topTracks := make([]map[string]interface{}, len(result.Artist.TopTracks)) + topTracks := make([]map[string]any, len(result.Artist.TopTracks)) for i, track := range result.Artist.TopTracks { - topTracks[i] = map[string]interface{}{ + topTracks[i] = map[string]any{ "id": track.ID, "name": track.Name, "artists": track.Artists, @@ -1043,9 +1043,9 @@ func GetURLHandlersJSON() (string, error) { manager := getExtensionManager() handlers := manager.GetURLHandlers() - result := make([]map[string]interface{}, 0, len(handlers)) + result := make([]map[string]any, 0, len(handlers)) for _, h := range handlers { - result = append(result, map[string]interface{}{ + result = append(result, map[string]any{ "id": h.extension.ID, "display_name": h.extension.Manifest.DisplayName, "patterns": h.extension.Manifest.URLHandler.Patterns, @@ -1061,10 +1061,10 @@ func GetURLHandlersJSON() (string, error) { } func RunPostProcessingJSON(filePath, metadataJSON string) (string, error) { - var metadata map[string]interface{} + var metadata map[string]any if metadataJSON != "" { if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil { - metadata = make(map[string]interface{}) + metadata = make(map[string]any) } } @@ -1083,10 +1083,10 @@ func RunPostProcessingJSON(filePath, metadataJSON string) (string, error) { } func RunPostProcessingV2JSON(inputJSON, metadataJSON string) (string, error) { - var metadata map[string]interface{} + var metadata map[string]any if metadataJSON != "" { if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil { - metadata = make(map[string]interface{}) + metadata = make(map[string]any) } } @@ -1115,11 +1115,11 @@ func GetPostProcessingProvidersJSON() (string, error) { manager := getExtensionManager() providers := manager.GetPostProcessingProviders() - result := make([]map[string]interface{}, 0, len(providers)) + result := make([]map[string]any, 0, len(providers)) for _, p := range providers { - hooks := make([]map[string]interface{}, 0) + hooks := make([]map[string]any, 0) for _, h := range p.extension.Manifest.GetPostProcessingHooks() { - hooks = append(hooks, map[string]interface{}{ + hooks = append(hooks, map[string]any{ "id": h.ID, "name": h.Name, "description": h.Description, @@ -1128,7 +1128,7 @@ func GetPostProcessingProvidersJSON() (string, error) { }) } - result = append(result, map[string]interface{}{ + result = append(result, map[string]any{ "id": p.extension.ID, "display_name": p.extension.Manifest.DisplayName, "hooks": hooks, diff --git a/go_backend/exports_lyrics.go b/go_backend/exports_lyrics.go index 78867381..bdaf985e 100644 --- a/go_backend/exports_lyrics.go +++ b/go_backend/exports_lyrics.go @@ -15,7 +15,7 @@ func FetchLyrics(spotifyID, trackName, artistName string, durationMs int64) (str return "", err } - result := map[string]interface{}{ + result := map[string]any{ "success": true, "source": lyrics.Source, "sync_type": lyrics.SyncType, @@ -63,7 +63,7 @@ func GetLyricsLRCWithSource(spotifyID, trackName, artistName string, filePath st if source == "" { source = "Embedded" } - result := map[string]interface{}{ + result := map[string]any{ "lyrics": lyrics, "source": source, "sync_type": "EMBEDDED", @@ -76,7 +76,7 @@ func GetLyricsLRCWithSource(spotifyID, trackName, artistName string, filePath st return string(jsonBytes), nil } - result := map[string]interface{}{ + result := map[string]any{ "lyrics": "", "source": "", "sync_type": "", @@ -103,7 +103,7 @@ func GetLyricsLRCWithSource(spotifyID, trackName, artistName string, filePath st lrcContent = convertToLRCWithMetadata(lyricsData, trackName, artistName) } - result := map[string]interface{}{ + result := map[string]any{ "lyrics": lrcContent, "source": lyricsData.Source, "sync_type": lyricsData.SyncType, @@ -123,7 +123,7 @@ func EmbedLyricsToFile(filePath, lyrics string) (string, error) { return errorResponse("Failed to embed lyrics: " + err.Error()) } - resp := map[string]interface{}{ + resp := map[string]any{ "success": true, "message": "Lyrics embedded successfully", } diff --git a/go_backend/exports_metadata.go b/go_backend/exports_metadata.go index 6f3e13cf..5f2f278b 100644 --- a/go_backend/exports_metadata.go +++ b/go_backend/exports_metadata.go @@ -21,7 +21,7 @@ func ReadFileMetadata(filePath string) (string, error) { isWav := strings.HasSuffix(lower, ".wav") isAiff := strings.HasSuffix(lower, ".aiff") || strings.HasSuffix(lower, ".aif") || strings.HasSuffix(lower, ".aifc") - result := map[string]interface{}{ + result := map[string]any{ "title": "", "artist": "", "album": "", @@ -621,7 +621,7 @@ func RewriteSplitArtistTagsExport(filePath, artist, albumArtist string) (string, return errorResponse("Failed to rewrite artist tags: " + err.Error()) } - resp := map[string]interface{}{ + resp := map[string]any{ "success": true, "message": "Split artist tags written successfully", } diff --git a/go_backend/exports_reenrich.go b/go_backend/exports_reenrich.go index 1e048a84..9069329c 100644 --- a/go_backend/exports_reenrich.go +++ b/go_backend/exports_reenrich.go @@ -642,7 +642,7 @@ func ReEnrichFile(requestJSON string) (string, error) { // Build enrichedMeta map: only include fields from selected update groups // so that the caller (Dart) does not overwrite non-selected metadata in its // local library database with potentially stale cached values. - enrichedMeta := map[string]interface{}{ + enrichedMeta := map[string]any{ "spotify_id": req.SpotifyID, "duration_ms": req.DurationMs, } @@ -729,7 +729,7 @@ func ReEnrichFile(requestJSON string) (string, error) { GoLog("[ReEnrich] FLAC metadata embedded successfully\n") - result := map[string]interface{}{ + result := map[string]any{ "method": "native", "success": true, "enriched_metadata": enrichedMeta, @@ -747,7 +747,7 @@ func ReEnrichFile(requestJSON string) (string, error) { cleanupCover = false ffmpegMetadata := buildReEnrichFFmpegMetadata(&req, lyricsLRC) - result := map[string]interface{}{ + result := map[string]any{ "method": "ffmpeg", "cover_path": coverTempPath, "lyrics": lyricsLRC, diff --git a/go_backend/exports_songlink_lyrics_supplement_test.go b/go_backend/exports_songlink_lyrics_supplement_test.go index 0dfe3445..5d2c635f 100644 --- a/go_backend/exports_songlink_lyrics_supplement_test.go +++ b/go_backend/exports_songlink_lyrics_supplement_test.go @@ -69,11 +69,12 @@ func TestSongLinkExportWrappersWithFakeClient(t *testing.T) { } globalSongLinkClient = &SongLinkClient{client: &http.Client{Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) { var body string - if req.URL.Host == "api.zarz.moe" { + switch req.URL.Host { + case "api.zarz.moe": body = `{"success":true,"songUrls":{"Spotify":"https://open.spotify.com/track/spotify-1","Deezer":"https://www.deezer.com/track/101","Tidal":"https://listen.tidal.com/track/202","YouTube":"https://youtu.be/yt1","AmazonMusic":"https://music.amazon.com/tracks/amz1","Qobuz":"https://open.qobuz.com/track/303"}}` - } else if req.URL.Host == "api.song.link" { + case "api.song.link": body = `{"linksByPlatform":{"spotify":{"url":"https://open.spotify.com/track/spotify-1"},"deezer":{"url":"https://www.deezer.com/track/101"},"tidal":{"url":"https://listen.tidal.com/track/202"},"youtubeMusic":{"url":"https://music.youtube.com/watch?v=ytm1"},"amazonMusic":{"url":"https://music.amazon.com/tracks/amz1"},"qobuz":{"url":"https://open.qobuz.com/track/303"}}}` - } else { + default: t.Fatalf("unexpected SongLink request: %s", req.URL.String()) } return &http.Response{StatusCode: http.StatusOK, Header: make(http.Header), Body: io.NopCloser(strings.NewReader(body)), Request: req}, nil diff --git a/go_backend/extension_fallback.go b/go_backend/extension_fallback.go index 8e11df26..f58c26f1 100644 --- a/go_backend/extension_fallback.go +++ b/go_backend/extension_fallback.go @@ -18,7 +18,7 @@ func manifestCapabilityStringList(manifest *ExtensionManifest, key string) []str return nil } - values, ok := raw.([]interface{}) + values, ok := raw.([]any) if !ok { return nil } @@ -994,7 +994,7 @@ func buildOutputPath(req DownloadRequest) string { return strings.TrimSpace(req.OutputPath) } - metadata := map[string]interface{}{ + metadata := map[string]any{ "title": req.TrackName, "artist": req.ArtistName, "album": req.AlbumName, @@ -1054,7 +1054,7 @@ func buildOutputPathForExtension(req DownloadRequest, ext *loadedExtension) stri os.MkdirAll(tempDir, 0755) AddAllowedDownloadDir(tempDir) - metadata := map[string]interface{}{ + metadata := map[string]any{ "title": req.TrackName, "artist": req.ArtistName, "album": req.AlbumName, diff --git a/go_backend/extension_goja_convert.go b/go_backend/extension_goja_convert.go index 1b66f5d9..c304000e 100644 --- a/go_backend/extension_goja_convert.go +++ b/go_backend/extension_goja_convert.go @@ -79,13 +79,13 @@ func gojaObjectBool(obj *goja.Object, keys ...string) bool { return false } -func gojaObjectInterfaceMap(obj *goja.Object, keys ...string) map[string]interface{} { +func gojaObjectInterfaceMap(obj *goja.Object, keys ...string) map[string]any { value := gojaObjectValue(obj, keys...) if gojaValueIsEmpty(value) { return nil } - exported, ok := value.Export().(map[string]interface{}) + exported, ok := value.Export().(map[string]any) if !ok || len(exported) == 0 { return nil } @@ -123,7 +123,7 @@ func gojaObjectStringSlice(obj *goja.Object, keys ...string) []string { if gojaValueIsEmpty(value) { return nil } - exported, ok := value.Export().([]interface{}) + exported, ok := value.Export().([]any) if !ok || len(exported) == 0 { return nil } diff --git a/go_backend/extension_health.go b/go_backend/extension_health.go index c005d72f..414ddaa8 100644 --- a/go_backend/extension_health.go +++ b/go_backend/extension_health.go @@ -296,7 +296,7 @@ func classifyExtensionHealthBody(body []byte, serviceKey string) (string, string return "online", "" } - var payload map[string]interface{} + var payload map[string]any if err := json.Unmarshal(body, &payload); err != nil { return "online", "" } @@ -325,12 +325,12 @@ func classifyExtensionHealthBody(body []byte, serviceKey string) (string, string } } -func classifyExtensionHealthService(payload map[string]interface{}, serviceKey string) (string, string, bool) { +func classifyExtensionHealthService(payload map[string]any, serviceKey string) (string, string, bool) { rawServices, ok := payload["services"] if !ok { return "", "", false } - services, ok := rawServices.(map[string]interface{}) + services, ok := rawServices.(map[string]any) if !ok { return "", "", false } @@ -338,7 +338,7 @@ func classifyExtensionHealthService(payload map[string]interface{}, serviceKey s if !ok { return "unknown", fmt.Sprintf("service '%s' not found", serviceKey), true } - service, ok := rawService.(map[string]interface{}) + service, ok := rawService.(map[string]any) if !ok { return "unknown", fmt.Sprintf("service '%s' has invalid health payload", serviceKey), true } @@ -444,7 +444,7 @@ func isTransientHealthStatusCode(code int) bool { } } -func healthNumber(value interface{}) (int, bool) { +func healthNumber(value any) (int, bool) { switch v := value.(type) { case float64: return int(v), true diff --git a/go_backend/extension_health_misc_supplement_test.go b/go_backend/extension_health_misc_supplement_test.go index 067b9d14..776a5b0b 100644 --- a/go_backend/extension_health_misc_supplement_test.go +++ b/go_backend/extension_health_misc_supplement_test.go @@ -20,7 +20,7 @@ func TestExtensionHealthClassificationAndValidation(t *testing.T) { if status, msg := classifyExtensionHealthBody([]byte(`{"services":{"tidal":{"status":401,"label":"Tidal","detail":"auth_required"}}}`), "tidal"); status != "degraded" || !strings.Contains(msg, "Tidal") { t.Fatalf("service status/message = %q/%q", status, msg) } - if status, msg, ok := classifyExtensionHealthService(map[string]interface{}{"services": map[string]interface{}{}}, "missing"); !ok || status != "unknown" || !strings.Contains(msg, "missing") { + if status, msg, ok := classifyExtensionHealthService(map[string]any{"services": map[string]any{}}, "missing"); !ok || status != "unknown" || !strings.Contains(msg, "missing") { t.Fatalf("missing service = %q/%q/%v", status, msg, ok) } if n, ok := healthNumber(json.Number("503")); !ok || n != 503 { diff --git a/go_backend/extension_manager.go b/go_backend/extension_manager.go index a50bd039..61b9b806 100644 --- a/go_backend/extension_manager.go +++ b/go_backend/extension_manager.go @@ -64,13 +64,13 @@ type loadedExtension struct { IconPath string `json:"icon_path"` } -func getExtensionInitSettings(extensionID string) map[string]interface{} { +func getExtensionInitSettings(extensionID string) map[string]any { settings := GetExtensionSettingsStore().GetAll(extensionID) if len(settings) == 0 { return settings } - filtered := make(map[string]interface{}, len(settings)) + filtered := make(map[string]any, len(settings)) for key, value := range settings { if strings.HasPrefix(key, "_") { continue @@ -335,7 +335,7 @@ func initializeVMLocked(ext *loadedExtension) error { console := vm.NewObject() console.Set("log", func(call goja.FunctionCall) goja.Value { - args := make([]interface{}, len(call.Arguments)) + args := make([]any, len(call.Arguments)) for i, arg := range call.Arguments { args[i] = arg.Export() } @@ -384,7 +384,7 @@ func newIsolatedExtensionRuntime(ext *loadedExtension) (*goja.Runtime, *extensio runtime := &extensionRuntime{ extensionID: ext.ID, manifest: ext.Manifest, - settings: make(map[string]interface{}), + settings: make(map[string]any), cookieJar: nil, dataDir: ext.DataDir, vm: vm, @@ -403,7 +403,7 @@ func newIsolatedExtensionRuntime(ext *loadedExtension) (*goja.Runtime, *extensio console := vm.NewObject() console.Set("log", func(call goja.FunctionCall) goja.Value { - args := make([]interface{}, len(call.Arguments)) + args := make([]any, len(call.Arguments)) for i, arg := range call.Arguments { args[i] = arg.Export() } @@ -451,7 +451,7 @@ func (m *extensionManager) initializeVM(ext *loadedExtension) error { func initializeExtensionRuntimeWithSettings( vm *goja.Runtime, extensionID string, - settings map[string]interface{}, + settings map[string]any, ) error { settingsJSON, err := json.Marshal(settings) if err != nil { @@ -481,7 +481,7 @@ func initializeExtensionRuntimeWithSettings( if result != nil && !goja.IsUndefined(result) { exported := result.Export() - if resultMap, ok := exported.(map[string]interface{}); ok { + if resultMap, ok := exported.(map[string]any); ok { if success, ok := resultMap["success"].(bool); ok && !success { errMsg := "unknown error" if e, ok := resultMap["error"].(string); ok { @@ -498,7 +498,7 @@ func initializeExtensionRuntimeWithSettings( func initializeExtensionWithSettingsLocked( ext *loadedExtension, - settings map[string]interface{}, + settings map[string]any, ) error { if ext.VM == nil { return fmt.Errorf("extension failed to load: please reinstall the extension") @@ -553,7 +553,7 @@ func runCleanupOnVM(vm *goja.Runtime) error { if result != nil && !goja.IsUndefined(result) { exported := result.Export() - if resultMap, ok := exported.(map[string]interface{}); ok { + if resultMap, ok := exported.(map[string]any); ok { if success, ok := resultMap["success"].(bool); ok && !success { errMsg := "unknown error" if e, ok := resultMap["error"].(string); ok { @@ -1043,7 +1043,7 @@ func (m *extensionManager) GetInstalledExtensionsJSON() (string, error) { TrackMatching *TrackMatchingConfig `json:"track_matching,omitempty"` PostProcessing *PostProcessingConfig `json:"post_processing,omitempty"` ServiceHealth []ExtensionHealthCheck `json:"service_health,omitempty"` - Capabilities map[string]interface{} `json:"capabilities,omitempty"` + Capabilities map[string]any `json:"capabilities,omitempty"` } infos := make([]ExtensionInfo, len(extensions)) @@ -1114,7 +1114,7 @@ func (m *extensionManager) GetInstalledExtensionsJSON() (string, error) { return string(jsonBytes), nil } -func (m *extensionManager) InitializeExtension(extensionID string, settings map[string]interface{}) error { +func (m *extensionManager) InitializeExtension(extensionID string, settings map[string]any) error { m.mu.Lock() defer m.mu.Unlock() @@ -1169,7 +1169,7 @@ func (m *extensionManager) UnloadAllExtensions() { GoLog("[Extension] All extensions unloaded\n") } -func (m *extensionManager) InvokeAction(extensionID string, actionName string) (map[string]interface{}, error) { +func (m *extensionManager) InvokeAction(extensionID string, actionName string) (map[string]any, error) { m.mu.Lock() defer m.mu.Unlock() @@ -1234,14 +1234,14 @@ func (m *extensionManager) InvokeAction(extensionID string, actionName string) ( } if result == nil || goja.IsUndefined(result) { - return map[string]interface{}{"success": true}, nil + return map[string]any{"success": true}, nil } exported := result.Export() - if resultMap, ok := exported.(map[string]interface{}); ok { + if resultMap, ok := exported.(map[string]any); ok { GoLog("[Extension] InvokeAction %s.%s result: %v\n", extensionID, actionName, resultMap) return resultMap, nil } - return map[string]interface{}{"success": true, "result": exported}, nil + return map[string]any{"success": true, "result": exported}, nil } diff --git a/go_backend/extension_manager_supplement_test.go b/go_backend/extension_manager_supplement_test.go index bb49cfa6..7d91c1f5 100644 --- a/go_backend/extension_manager_supplement_test.go +++ b/go_backend/extension_manager_supplement_test.go @@ -66,7 +66,7 @@ registerExtension({ if err != nil || !strings.Contains(installedJSON, "manager-ext") || !strings.Contains(installedJSON, "icon_path") { t.Fatalf("GetInstalledExtensionsJSON = %q/%v", installedJSON, err) } - var installed []map[string]interface{} + var installed []map[string]any if err := json.Unmarshal([]byte(installedJSON), &installed); err != nil || len(installed) != 1 { t.Fatalf("decode installed = %#v/%v", installed, err) } @@ -80,7 +80,7 @@ registerExtension({ if !ext.Enabled || ext.VM == nil || !ext.initialized { t.Fatalf("enabled extension = %#v", ext) } - if err := manager.InitializeExtension("manager-ext", map[string]interface{}{"quality": "hires"}); err != nil { + if err := manager.InitializeExtension("manager-ext", map[string]any{"quality": "hires"}); err != nil { t.Fatalf("InitializeExtension: %v", err) } action, err := manager.InvokeAction("manager-ext", "doAction") diff --git a/go_backend/extension_manifest.go b/go_backend/extension_manifest.go index 71e3ac5b..0448a452 100644 --- a/go_backend/extension_manifest.go +++ b/go_backend/extension_manifest.go @@ -39,7 +39,7 @@ type ExtensionSetting struct { Description string `json:"description,omitempty"` Required bool `json:"required,omitempty"` Secret bool `json:"secret,omitempty"` - Default interface{} `json:"default,omitempty"` + Default any `json:"default,omitempty"` Options []string `json:"options,omitempty"` Action string `json:"action,omitempty"` } @@ -58,7 +58,7 @@ type QualitySpecificSetting struct { Description string `json:"description,omitempty"` Required bool `json:"required,omitempty"` Secret bool `json:"secret,omitempty"` - Default interface{} `json:"default,omitempty"` + Default any `json:"default,omitempty"` Options []string `json:"options,omitempty"` } @@ -156,7 +156,7 @@ type ExtensionManifest struct { ServiceHealth []ExtensionHealthCheck `json:"serviceHealth,omitempty"` SignedSession *SignedSessionConfig `json:"signedSession,omitempty"` RequiredRuntimeFeatures []string `json:"requiredRuntimeFeatures,omitempty"` - Capabilities map[string]interface{} `json:"capabilities,omitempty"` + Capabilities map[string]any `json:"capabilities,omitempty"` } type ManifestValidationError struct { diff --git a/go_backend/extension_provider_supplement_test.go b/go_backend/extension_provider_supplement_test.go index d46b569d..8a02d1bb 100644 --- a/go_backend/extension_provider_supplement_test.go +++ b/go_backend/extension_provider_supplement_test.go @@ -101,8 +101,8 @@ func TestExtensionProviderWrapperFullSurface(t *testing.T) { } match, err := provider.MatchTrack( - map[string]interface{}{"name": "Song", "artists": "Artist"}, - []map[string]interface{}{{"id": "download-track", "name": "Song"}}, + map[string]any{"name": "Song", "artists": "Artist"}, + []map[string]any{{"id": "download-track", "name": "Song"}}, ) if err != nil { t.Fatalf("MatchTrack: %v", err) @@ -111,7 +111,7 @@ func TestExtensionProviderWrapperFullSurface(t *testing.T) { t.Fatalf("match = %#v", match) } - post, err := provider.PostProcess(filepath.Join(t.TempDir(), "song.flac"), map[string]interface{}{"title": "Song"}, "hook") + post, err := provider.PostProcess(filepath.Join(t.TempDir(), "song.flac"), map[string]any{"title": "Song"}, "hook") if err != nil { t.Fatalf("PostProcess: %v", err) } @@ -121,8 +121,8 @@ func TestExtensionProviderWrapperFullSurface(t *testing.T) { } func TestExtensionProviderAndManagerSelectionHelpers(t *testing.T) { - manifest := &ExtensionManifest{Capabilities: map[string]interface{}{ - "replacesBuiltInProviders": []interface{}{" Deezer ", 7, ""}, + manifest := &ExtensionManifest{Capabilities: map[string]any{ + "replacesBuiltInProviders": []any{" Deezer ", 7, ""}, }} if values := manifestCapabilityStringList(manifest, "replacesBuiltInProviders"); len(values) != 1 || values[0] != "deezer" { t.Fatalf("capability list = %#v", values) diff --git a/go_backend/extension_provider_types.go b/go_backend/extension_provider_types.go index bb882596..f3c16cbe 100644 --- a/go_backend/extension_provider_types.go +++ b/go_backend/extension_provider_types.go @@ -99,12 +99,12 @@ type ExtDownloadURLResult struct { } type DownloadDecryptionInfo struct { - Strategy string `json:"strategy,omitempty"` - Key string `json:"key,omitempty"` - IV string `json:"iv,omitempty"` - InputFormat string `json:"input_format,omitempty"` - OutputExtension string `json:"output_extension,omitempty"` - Options map[string]interface{} `json:"options,omitempty"` + Strategy string `json:"strategy,omitempty"` + Key string `json:"key,omitempty"` + IV string `json:"iv,omitempty"` + InputFormat string `json:"input_format,omitempty"` + OutputExtension string `json:"output_extension,omitempty"` + Options map[string]any `json:"options,omitempty"` } type ExtDownloadResult struct { @@ -157,7 +157,7 @@ func cloneDownloadDecryptionInfo(info *DownloadDecryptionInfo) *DownloadDecrypti OutputExtension: strings.TrimSpace(info.OutputExtension), } if len(info.Options) > 0 { - cloned.Options = make(map[string]interface{}, len(info.Options)) + cloned.Options = make(map[string]any, len(info.Options)) for key, value := range info.Options { cloned.Options[key] = value } diff --git a/go_backend/extension_provider_wrapper.go b/go_backend/extension_provider_wrapper.go index d0cf1d4b..8a37021b 100644 --- a/go_backend/extension_provider_wrapper.go +++ b/go_backend/extension_provider_wrapper.go @@ -648,19 +648,19 @@ func (p *extensionProviderWrapper) Download(trackID, quality, outputPath, itemID return &downloadResult, nil } -func (p *extensionProviderWrapper) CustomSearch(query string, options map[string]interface{}) ([]ExtTrackMetadata, error) { +func (p *extensionProviderWrapper) CustomSearch(query string, options map[string]any) ([]ExtTrackMetadata, error) { return p.customSearch(query, options, "", "") } -func (p *extensionProviderWrapper) CustomSearchForRequestID(query string, options map[string]interface{}, requestID string) ([]ExtTrackMetadata, error) { +func (p *extensionProviderWrapper) CustomSearchForRequestID(query string, options map[string]any, requestID string) ([]ExtTrackMetadata, error) { return p.customSearch(query, options, "", requestID) } -func (p *extensionProviderWrapper) CustomSearchForItemID(query string, options map[string]interface{}, itemID string) ([]ExtTrackMetadata, error) { +func (p *extensionProviderWrapper) CustomSearchForItemID(query string, options map[string]any, itemID string) ([]ExtTrackMetadata, error) { return p.customSearch(query, options, itemID, "") } -func (p *extensionProviderWrapper) customSearch(query string, options map[string]interface{}, itemID, requestID string) ([]ExtTrackMetadata, error) { +func (p *extensionProviderWrapper) customSearch(query string, options map[string]any, itemID, requestID string) ([]ExtTrackMetadata, error) { if !p.extension.Manifest.HasCustomSearch() { return nil, fmt.Errorf("extension '%s' does not support custom search", p.extension.ID) } @@ -701,7 +701,7 @@ func (p *extensionProviderWrapper) customSearch(query string, options map[string } if options == nil { - options = map[string]interface{}{} + options = map[string]any{} } // Avoid embedding user input directly into JS source. Some inputs can trigger @@ -882,7 +882,7 @@ type MatchTrackResult struct { Reason string `json:"reason,omitempty"` } -func (p *extensionProviderWrapper) MatchTrack(sourceTrack map[string]interface{}, candidates []map[string]interface{}) (*MatchTrackResult, error) { +func (p *extensionProviderWrapper) MatchTrack(sourceTrack map[string]any, candidates []map[string]any) (*MatchTrackResult, error) { if !p.extension.Manifest.HasCustomMatching() { return nil, fmt.Errorf("extension '%s' does not support custom matching", p.extension.ID) } @@ -953,7 +953,7 @@ type PostProcessInput struct { const PostProcessTimeout = 2 * time.Minute -func (p *extensionProviderWrapper) PostProcess(filePath string, metadata map[string]interface{}, hookID string) (*PostProcessResult, error) { +func (p *extensionProviderWrapper) PostProcess(filePath string, metadata map[string]any, hookID string) (*PostProcessResult, error) { if !p.extension.Manifest.HasPostProcessing() { return nil, fmt.Errorf("extension '%s' does not support post-processing", p.extension.ID) } @@ -1010,7 +1010,7 @@ func (p *extensionProviderWrapper) PostProcess(filePath string, metadata map[str return &postResult, nil } -func (p *extensionProviderWrapper) PostProcessV2(input PostProcessInput, metadata map[string]interface{}, hookID string) (*PostProcessResult, error) { +func (p *extensionProviderWrapper) PostProcessV2(input PostProcessInput, metadata map[string]any, hookID string) (*PostProcessResult, error) { if !p.extension.Manifest.HasPostProcessing() { return nil, fmt.Errorf("extension '%s' does not support post-processing", p.extension.ID) } diff --git a/go_backend/extension_providers.go b/go_backend/extension_providers.go index 7e5ab025..d2d38589 100644 --- a/go_backend/extension_providers.go +++ b/go_backend/extension_providers.go @@ -252,7 +252,7 @@ func (m *extensionManager) GetPostProcessingProviders() []*extensionProviderWrap return providers } -func (m *extensionManager) RunPostProcessing(filePath string, metadata map[string]interface{}) (*PostProcessResult, error) { +func (m *extensionManager) RunPostProcessing(filePath string, metadata map[string]any) (*PostProcessResult, error) { providers := m.GetPostProcessingProviders() if len(providers) == 0 { return &PostProcessResult{Success: true, NewFilePath: filePath}, nil @@ -297,7 +297,7 @@ func (m *extensionManager) RunPostProcessing(filePath string, metadata map[strin return &PostProcessResult{Success: true, NewFilePath: currentPath}, nil } -func (m *extensionManager) RunPostProcessingV2(input PostProcessInput, metadata map[string]interface{}) (*PostProcessResult, error) { +func (m *extensionManager) RunPostProcessingV2(input PostProcessInput, metadata map[string]any) (*PostProcessResult, error) { providers := m.GetPostProcessingProviders() if len(providers) == 0 { return &PostProcessResult{Success: true, NewFilePath: input.Path, NewFileURI: input.URI}, nil diff --git a/go_backend/extension_runtime.go b/go_backend/extension_runtime.go index 1673ec71..4f783227 100644 --- a/go_backend/extension_runtime.go +++ b/go_backend/extension_runtime.go @@ -5,6 +5,7 @@ import ( "net" "net/http" "net/url" + "slices" "strconv" "strings" "sync" @@ -113,7 +114,7 @@ func SetExtensionTokens(extensionID string, accessToken, refreshToken string, ex type extensionRuntime struct { extensionID string manifest *ExtensionManifest - settings map[string]interface{} + settings map[string]any httpClient *http.Client downloadClient *http.Client cookieJar http.CookieJar @@ -127,14 +128,14 @@ type extensionRuntime struct { activeRequestID string storageMu sync.RWMutex - storageCache map[string]interface{} + storageCache map[string]any storageLoaded bool storageDirty bool storageClosed bool storageTimer *time.Timer credentialsMu sync.RWMutex - credentialsCache map[string]interface{} + credentialsCache map[string]any credentialsLoaded bool storageFlushDelay time.Duration } @@ -161,7 +162,7 @@ func newExtensionRuntime(ext *loadedExtension) *extensionRuntime { runtime := &extensionRuntime{ extensionID: ext.ID, manifest: ext.Manifest, - settings: make(map[string]interface{}), + settings: make(map[string]any), cookieJar: jar, dataDir: ext.DataDir, vm: ext.VM, @@ -199,7 +200,7 @@ func extensionHTTPTimeout(ext *loadedExtension, fallback time.Duration) time.Dur return time.Duration(seconds) * time.Second } -func parseExtensionTimeoutSeconds(raw interface{}) int { +func parseExtensionTimeoutSeconds(raw any) int { switch v := raw.(type) { case int: return v @@ -360,13 +361,7 @@ func isPrivateIP(host string) bool { return false } - isPrivate := false - for _, ip := range ips { - if isPrivateIPAddr(ip) { - isPrivate = true - break - } - } + isPrivate := slices.ContainsFunc(ips, isPrivateIPAddr) setPrivateIPCache(hostLower, isPrivate, privateIPCacheTTL) return isPrivate @@ -456,7 +451,7 @@ func (j *simpleCookieJar) Cookies(u *url.URL) []*http.Cookie { return j.cookies[u.Host] } -func (r *extensionRuntime) SetSettings(settings map[string]interface{}) { +func (r *extensionRuntime) SetSettings(settings map[string]any) { r.settings = settings } diff --git a/go_backend/extension_runtime_auth.go b/go_backend/extension_runtime_auth.go index adc9ea54..83846e02 100644 --- a/go_backend/extension_runtime_auth.go +++ b/go_backend/extension_runtime_auth.go @@ -54,7 +54,7 @@ func summarizeURLForLog(urlStr string) string { func (r *extensionRuntime) authOpenUrl(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "auth URL is required", }) @@ -67,7 +67,7 @@ func (r *extensionRuntime) authOpenUrl(call goja.FunctionCall) goja.Value { } if err := validateExtensionAuthURL(authURL); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -94,7 +94,7 @@ func (r *extensionRuntime) authOpenUrl(call goja.FunctionCall) goja.Value { GoLog("[Extension:%s] Auth URL requested: %s\n", r.extensionID, summarizeURLForLog(authURL)) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "message": "Auth URL will be opened by the app", }) @@ -131,7 +131,7 @@ func (r *extensionRuntime) authSetCode(call goja.FunctionCall) goja.Value { switch v := arg.(type) { case string: state.AuthCode = v - case map[string]interface{}: + case map[string]any: if code, ok := v["code"].(string); ok { state.AuthCode = code } @@ -185,10 +185,10 @@ func (r *extensionRuntime) authGetTokens(call goja.FunctionCall) goja.Value { state, exists := extensionAuthState[r.extensionID] if !exists { - return r.vm.ToValue(map[string]interface{}{}) + return r.vm.ToValue(map[string]any{}) } - result := map[string]interface{}{ + result := map[string]any{ "access_token": state.AccessToken, "refresh_token": state.RefreshToken, "is_authenticated": state.IsAuthenticated, @@ -240,7 +240,7 @@ func (r *extensionRuntime) authGeneratePKCE(call goja.FunctionCall) goja.Value { verifier, err := generatePKCEVerifier(length) if err != nil { GoLog("[Extension:%s] PKCE generation error: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -259,7 +259,7 @@ func (r *extensionRuntime) authGeneratePKCE(call goja.FunctionCall) goja.Value { GoLog("[Extension:%s] PKCE generated (verifier length: %d)\n", r.extensionID, len(verifier)) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "verifier": verifier, "challenge": challenge, "method": "S256", @@ -272,10 +272,10 @@ func (r *extensionRuntime) authGetPKCE(call goja.FunctionCall) goja.Value { state, exists := extensionAuthState[r.extensionID] if !exists || state.PKCEVerifier == "" { - return r.vm.ToValue(map[string]interface{}{}) + return r.vm.ToValue(map[string]any{}) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "verifier": state.PKCEVerifier, "challenge": state.PKCEChallenge, "method": "S256", @@ -284,16 +284,16 @@ func (r *extensionRuntime) authGetPKCE(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) authStartOAuthWithPKCE(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "config object is required", }) } configObj := call.Arguments[0].Export() - config, ok := configObj.(map[string]interface{}) + config, ok := configObj.(map[string]any) if !ok { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "config must be an object", }) @@ -304,24 +304,24 @@ func (r *extensionRuntime) authStartOAuthWithPKCE(call goja.FunctionCall) goja.V redirectURI, _ := config["redirectUri"].(string) if authURL == "" || clientID == "" || redirectURI == "" { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "authUrl, clientId, and redirectUri are required", }) } if err := validateExtensionAuthURL(authURL); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } scope, _ := config["scope"].(string) - extraParams, _ := config["extraParams"].(map[string]interface{}) + extraParams, _ := config["extraParams"].(map[string]any) verifier, err := generatePKCEVerifier(64) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to generate PKCE: %v", err), }) @@ -341,7 +341,7 @@ func (r *extensionRuntime) authStartOAuthWithPKCE(call goja.FunctionCall) goja.V parsedURL, err := url.Parse(authURL) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("invalid authUrl: %v", err), }) @@ -376,10 +376,10 @@ func (r *extensionRuntime) authStartOAuthWithPKCE(call goja.FunctionCall) goja.V GoLog("[Extension:%s] PKCE OAuth started: %s\n", r.extensionID, summarizeURLForLog(fullAuthURL)) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "authUrl": fullAuthURL, - "pkce": map[string]interface{}{ + "pkce": map[string]any{ "verifier": verifier, "challenge": challenge, "method": "S256", @@ -389,16 +389,16 @@ func (r *extensionRuntime) authStartOAuthWithPKCE(call goja.FunctionCall) goja.V func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "config object is required", }) } configObj := call.Arguments[0].Export() - config, ok := configObj.(map[string]interface{}) + config, ok := configObj.(map[string]any) if !ok { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "config must be an object", }) @@ -410,7 +410,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja code, _ := config["code"].(string) if tokenURL == "" || clientID == "" || code == "" { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "tokenUrl, clientId, and code are required", }) @@ -425,14 +425,14 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja extensionAuthStateMu.RUnlock() if verifier == "" { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "no PKCE verifier found - call generatePKCE or startOAuthWithPKCE first", }) } if err := r.validateDomain(tokenURL); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -447,7 +447,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja formData.Set("redirect_uri", redirectURI) } - if extraParams, ok := config["extraParams"].(map[string]interface{}); ok { + if extraParams, ok := config["extraParams"].(map[string]any); ok { for k, v := range extraParams { formData.Set(k, fmt.Sprintf("%v", v)) } @@ -455,7 +455,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja req, err := http.NewRequest("POST", tokenURL, strings.NewReader(formData.Encode())) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -467,7 +467,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja resp, err := r.httpClient.Do(req) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -476,7 +476,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja body, err := io.ReadAll(resp.Body) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -486,9 +486,9 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja bodyPreview = bodyPreview[:1000] + "...[truncated]" } - var tokenResp map[string]interface{} + var tokenResp map[string]any if err := json.Unmarshal(body, &tokenResp); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to parse token response: %v", err), "body": bodyPreview, @@ -497,7 +497,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja if errMsg, ok := tokenResp["error"].(string); ok { errDesc, _ := tokenResp["error_description"].(string) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": errMsg, "error_description": errDesc, @@ -509,7 +509,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja expiresIn, _ := tokenResp["expires_in"].(float64) if accessToken == "" { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "no access_token in response", "body": bodyPreview, @@ -534,7 +534,7 @@ func (r *extensionRuntime) authExchangeCodeWithPKCE(call goja.FunctionCall) goja GoLog("[Extension:%s] PKCE token exchange successful\n", r.extensionID) - result := map[string]interface{}{ + result := map[string]any{ "success": true, "access_token": accessToken, "refresh_token": refreshToken, diff --git a/go_backend/extension_runtime_binary.go b/go_backend/extension_runtime_binary.go index 3c986d7e..dc84538a 100644 --- a/go_backend/extension_runtime_binary.go +++ b/go_backend/extension_runtime_binary.go @@ -23,7 +23,7 @@ type runtimeBlockCipherOptions struct { Padding string } -func parseRuntimeOptionsArgument(call goja.FunctionCall, index int) map[string]interface{} { +func parseRuntimeOptionsArgument(call goja.FunctionCall, index int) map[string]any { if len(call.Arguments) <= index { return nil } @@ -34,13 +34,13 @@ func parseRuntimeOptionsArgument(call goja.FunctionCall, index int) map[string]i } exported := value.Export() - if options, ok := exported.(map[string]interface{}); ok { + if options, ok := exported.(map[string]any); ok { return options } return nil } -func runtimeOptionString(options map[string]interface{}, key, defaultValue string) string { +func runtimeOptionString(options map[string]any, key, defaultValue string) string { if options == nil { return defaultValue } @@ -61,7 +61,7 @@ func runtimeOptionString(options map[string]interface{}, key, defaultValue strin return defaultValue } -func runtimeOptionBool(options map[string]interface{}, key string, defaultValue bool) bool { +func runtimeOptionBool(options map[string]any, key string, defaultValue bool) bool { if options == nil { return defaultValue } @@ -89,7 +89,7 @@ func runtimeOptionBool(options map[string]interface{}, key string, defaultValue return defaultValue } -func runtimeOptionInt64(options map[string]interface{}, key string, defaultValue int64) int64 { +func runtimeOptionInt64(options map[string]any, key string, defaultValue int64) int64 { if options == nil { return defaultValue } @@ -121,7 +121,7 @@ func runtimeOptionInt64(options map[string]interface{}, key string, defaultValue return defaultValue } -func runtimeOptionHasKey(options map[string]interface{}, key string) bool { +func runtimeOptionHasKey(options map[string]any, key string) bool { if options == nil { return false } @@ -150,7 +150,7 @@ func decodeRuntimeBytesString(input, encoding string) ([]byte, error) { } } -func decodeRuntimeBytesValue(raw interface{}, encoding string) ([]byte, error) { +func decodeRuntimeBytesValue(raw any, encoding string) ([]byte, error) { switch value := raw.(type) { case string: return decodeRuntimeBytesString(value, encoding) @@ -163,7 +163,7 @@ func decodeRuntimeBytesValue(raw interface{}, encoding string) ([]byte, error) { cloned := make([]byte, len(src)) copy(cloned, src) return cloned, nil - case []interface{}: + case []any: decoded := make([]byte, len(value)) for i, item := range value { switch num := item.(type) { @@ -196,7 +196,7 @@ func encodeRuntimeBytes(data []byte, encoding string) (string, error) { } } -func parseRuntimeBlockCipherOptions(options map[string]interface{}) (*runtimeBlockCipherOptions, error) { +func parseRuntimeBlockCipherOptions(options map[string]any) (*runtimeBlockCipherOptions, error) { parsed := &runtimeBlockCipherOptions{ Algorithm: strings.ToLower(runtimeOptionString(options, "algorithm", "")), Mode: strings.ToLower(runtimeOptionString(options, "mode", "cbc")), @@ -270,7 +270,7 @@ func removePKCS7Padding(data []byte, blockSize int) ([]byte, error) { func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt bool) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "data and options are required", }) @@ -279,7 +279,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt options := parseRuntimeOptionsArgument(call, 1) parsedOptions, err := parseRuntimeBlockCipherOptions(options) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -287,7 +287,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt switch parsedOptions.Mode { case "cbc", "ctr": default: - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("unsupported block cipher mode: %s", parsedOptions.Mode), }) @@ -295,7 +295,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt inputData, err := decodeRuntimeBytesValue(call.Arguments[0].Export(), parsedOptions.InputEncoding) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -303,7 +303,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt block, err := newRuntimeBlockCipher(parsedOptions) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -314,7 +314,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt if parsedOptions.Mode == "ctr" { ivLabel = "iv (counter)" } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("%s must be %d bytes for %s", ivLabel, block.BlockSize(), parsedOptions.Algorithm), }) @@ -332,7 +332,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt data = applyPKCS7Padding(data, block.BlockSize()) } if len(data)%block.BlockSize() != 0 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("input length must be a multiple of %d bytes", block.BlockSize()), }) @@ -344,7 +344,7 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt if parsedOptions.Padding == "pkcs7" { output, err = removePKCS7Padding(output, block.BlockSize()) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -357,13 +357,13 @@ func (r *extensionRuntime) transformBlockCipher(call goja.FunctionCall, decrypt encoded, err := encodeRuntimeBytes(output, parsedOptions.OutputEncoding) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": encoded, "block_size": block.BlockSize(), @@ -392,18 +392,20 @@ func (r *extensionRuntime) decryptBlockCipher(call goja.FunctionCall) goja.Value // dominant cost under the goja interpreter. // // JS signature: -// utils.decryptCTRSegments(data, { -// algorithm: "aes", // optional, default "aes" -// key: "", keyEncoding: "hex", -// segments: [ { offset: , size: , iv: "" }, ... ], -// ivEncoding: "base64", // encoding of each segment.iv, default base64 -// inputEncoding: "bytes", // "bytes" for ArrayBuffer/Uint8Array, else base64/hex -// outputEncoding: "bytes" // "bytes" -> ArrayBuffer; else base64/hex string -// }) +// +// utils.decryptCTRSegments(data, { +// algorithm: "aes", // optional, default "aes" +// key: "", keyEncoding: "hex", +// segments: [ { offset: , size: , iv: "" }, ... ], +// ivEncoding: "base64", // encoding of each segment.iv, default base64 +// inputEncoding: "bytes", // "bytes" for ArrayBuffer/Uint8Array, else base64/hex +// outputEncoding: "bytes" // "bytes" -> ArrayBuffer; else base64/hex string +// }) +// // Returns { success, data, segments_processed } or { success:false, error }. func (r *extensionRuntime) decryptCTRSegments(call goja.FunctionCall) goja.Value { fail := func(msg string) goja.Value { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": msg, }) @@ -467,14 +469,14 @@ func (r *extensionRuntime) decryptCTRSegments(call goja.FunctionCall) goja.Value if !ok || rawSegments == nil { return fail("segments array is required") } - segments, ok := rawSegments.([]interface{}) + segments, ok := rawSegments.([]any) if !ok { return fail("segments must be an array") } processed := 0 for i, rawSeg := range segments { - seg, ok := rawSeg.(map[string]interface{}) + seg, ok := rawSeg.(map[string]any) if !ok { return fail(fmt.Sprintf("segment %d is not an object", i)) } @@ -514,7 +516,7 @@ func (r *extensionRuntime) decryptCTRSegments(call goja.FunctionCall) goja.Value // Return raw bytes as an ArrayBuffer when requested (zero-copy-ish, no // base64). Otherwise fall back to an encoded string. if outputEncoding == "bytes" || outputEncoding == "raw" { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": r.vm.NewArrayBuffer(data), "segments_processed": processed, @@ -526,7 +528,7 @@ func (r *extensionRuntime) decryptCTRSegments(call goja.FunctionCall) goja.Value return fail(err.Error()) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": encoded, "segments_processed": processed, diff --git a/go_backend/extension_runtime_ffmpeg.go b/go_backend/extension_runtime_ffmpeg.go index d9a9e2a5..c9eb2124 100644 --- a/go_backend/extension_runtime_ffmpeg.go +++ b/go_backend/extension_runtime_ffmpeg.go @@ -52,7 +52,7 @@ func ClearFFmpegCommand(commandID string) { func (r *extensionRuntime) ffmpegExecute(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "command is required", }) @@ -82,7 +82,7 @@ func (r *extensionRuntime) ffmpegExecute(call goja.FunctionCall) goja.Value { if completed { ffmpegCommandsMu.RLock() - result := map[string]interface{}{ + result := map[string]any{ "success": cmd.Success, "output": cmd.Output, } @@ -97,7 +97,7 @@ func (r *extensionRuntime) ffmpegExecute(call goja.FunctionCall) goja.Value { if time.Since(start) > timeout { ClearFFmpegCommand(cmdID) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "FFmpeg command timed out", }) @@ -109,7 +109,7 @@ func (r *extensionRuntime) ffmpegExecute(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) ffmpegGetInfo(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "file path is required", }) @@ -119,13 +119,13 @@ func (r *extensionRuntime) ffmpegGetInfo(call goja.FunctionCall) goja.Value { quality, err := GetAudioQuality(filePath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "bit_depth": quality.BitDepth, "sample_rate": quality.SampleRate, @@ -137,7 +137,7 @@ func (r *extensionRuntime) ffmpegGetInfo(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) ffmpegConvert(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "input and output paths are required", }) @@ -146,9 +146,9 @@ func (r *extensionRuntime) ffmpegConvert(call goja.FunctionCall) goja.Value { inputPath := call.Arguments[0].String() outputPath := call.Arguments[1].String() - options := map[string]interface{}{} + options := map[string]any{} if len(call.Arguments) > 2 && !goja.IsUndefined(call.Arguments[2]) && !goja.IsNull(call.Arguments[2]) { - if opts, ok := call.Arguments[2].Export().(map[string]interface{}); ok { + if opts, ok := call.Arguments[2].Export().(map[string]any); ok { options = opts } } diff --git a/go_backend/extension_runtime_file.go b/go_backend/extension_runtime_file.go index 96270ad4..0ae51856 100644 --- a/go_backend/extension_runtime_file.go +++ b/go_backend/extension_runtime_file.go @@ -109,7 +109,7 @@ func (r *extensionRuntime) validatePath(path string) (string, error) { func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "URL and output path are required", }) @@ -119,7 +119,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { outputPath := call.Arguments[1].String() if err := r.validateDomain(urlStr); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -127,7 +127,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { fullPath, err := r.validatePath(outputPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -140,8 +140,8 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { var chunkSize int64 if len(call.Arguments) > 2 && !goja.IsUndefined(call.Arguments[2]) && !goja.IsNull(call.Arguments[2]) { optionsObj := call.Arguments[2].Export() - if opts, ok := optionsObj.(map[string]interface{}); ok { - if h, ok := opts["headers"].(map[string]interface{}); ok { + if opts, ok := optionsObj.(map[string]any); ok { + if h, ok := opts["headers"].(map[string]any); ok { headers = make(map[string]string) for k, v := range h { headers[k] = fmt.Sprintf("%v", v) @@ -187,7 +187,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { dir := filepath.Dir(fullPath) if err := os.MkdirAll(dir, 0755); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create directory: %v", err), }) @@ -209,7 +209,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { req, err := http.NewRequest("GET", urlStr, nil) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -225,7 +225,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { resp, err := client.Do(req) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -233,7 +233,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("HTTP error: %d", resp.StatusCode), }) @@ -241,7 +241,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { out, err := os.Create(fullPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create file: %v", err), }) @@ -279,18 +279,18 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { written += int64(nw) if ew != nil { if ew == ErrDownloadCancelled { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "download cancelled", }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to write file: %v", ew), }) } if nr != nw { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "short write", }) @@ -302,7 +302,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { } if er != nil { if er != io.EOF { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to read response: %v", er), }) @@ -321,7 +321,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value { GoLog("[Extension:%s] Downloaded %d bytes to %s\n", r.extensionID, written, fullPath) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "path": fullPath, "size": written, @@ -335,7 +335,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full // First, get the total content length with a small probe request probeReq, err := http.NewRequest("GET", urlStr, nil) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("chunked: probe request error: %v", err), }) @@ -351,7 +351,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full probeResp, err := client.Do(probeReq) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("chunked: probe error: %v", err), }) @@ -360,7 +360,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full probeResp.Body.Close() if probeResp.StatusCode != 206 && probeResp.StatusCode != 200 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("chunked: probe HTTP %d", probeResp.StatusCode), }) @@ -388,7 +388,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full out, err := os.Create(fullPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create file: %v", err), }) @@ -426,7 +426,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full for retry := 0; retry < maxRetries; retry++ { chunkReq, err := http.NewRequest("GET", urlStr, nil) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("chunked: request error at offset %d: %v", offset, err), }) @@ -446,7 +446,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full time.Sleep(time.Duration(retry+1) * time.Second) continue } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("chunked: error at offset %d after %d retries: %v", offset, maxRetries, chunkErr), }) @@ -466,7 +466,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full } } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("chunked: HTTP %d at offset %d", chunkResp.StatusCode, offset), }) @@ -488,19 +488,19 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full if ew != nil { chunkResp.Body.Close() if ew == ErrDownloadCancelled { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "download cancelled", }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to write file: %v", ew), }) } if nr != nw { chunkResp.Body.Close() - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "short write", }) @@ -513,7 +513,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full if er != nil { if er != io.EOF { chunkResp.Body.Close() - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to read chunk at offset %d: %v", offset, er), }) @@ -551,7 +551,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full GoLog("[Extension:%s] Chunked download complete: %d bytes to %s\n", r.extensionID, totalWritten, fullPath) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "path": fullPath, "size": totalWritten, @@ -575,7 +575,7 @@ func (r *extensionRuntime) fileExists(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) fileDelete(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "path is required", }) @@ -584,27 +584,27 @@ func (r *extensionRuntime) fileDelete(call goja.FunctionCall) goja.Value { path := call.Arguments[0].String() fullPath, err := r.validatePath(path) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } if err := os.Remove(fullPath); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, }) } func (r *extensionRuntime) fileRead(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "path is required", }) @@ -613,7 +613,7 @@ func (r *extensionRuntime) fileRead(call goja.FunctionCall) goja.Value { path := call.Arguments[0].String() fullPath, err := r.validatePath(path) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -621,13 +621,13 @@ func (r *extensionRuntime) fileRead(call goja.FunctionCall) goja.Value { data, err := os.ReadFile(fullPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": string(data), }) @@ -635,7 +635,7 @@ func (r *extensionRuntime) fileRead(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "path is required", }) @@ -644,7 +644,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { path := call.Arguments[0].String() fullPath, err := r.validatePath(path) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -655,14 +655,14 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { length := runtimeOptionInt64(options, "length", -1) encoding := runtimeOptionString(options, "encoding", "base64") if offset < 0 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "offset must be >= 0", }) } file, err := os.Open(fullPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -671,7 +671,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { info, err := file.Stat() if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -682,7 +682,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { offset = size } if _, err := file.Seek(offset, io.SeekStart); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to seek file: %v", err), }) @@ -696,7 +696,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { buf := make([]byte, int(length)) n, readErr := file.Read(buf) if readErr != nil && readErr != io.EOF { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to read file: %v", readErr), }) @@ -705,7 +705,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { default: data, err = io.ReadAll(file) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to read file: %v", err), }) @@ -716,7 +716,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { strings.EqualFold(strings.TrimSpace(encoding), "raw") { // Return raw bytes as an ArrayBuffer to avoid base64 encode/decode of // large payloads under the goja interpreter. - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": r.vm.NewArrayBuffer(data), "bytes_read": len(data), @@ -728,13 +728,13 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { encoded, err := encodeRuntimeBytes(data, encoding) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": encoded, "bytes_read": len(data), @@ -745,7 +745,7 @@ func (r *extensionRuntime) fileReadBytes(call goja.FunctionCall) goja.Value { } func (r *extensionRuntime) fileWrite(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "path and data are required", }) @@ -756,7 +756,7 @@ func (r *extensionRuntime) fileWrite(call goja.FunctionCall) goja.Value { fullPath, err := r.validatePath(path) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -764,20 +764,20 @@ func (r *extensionRuntime) fileWrite(call goja.FunctionCall) goja.Value { dir := filepath.Dir(fullPath) if err := os.MkdirAll(dir, 0755); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create directory: %v", err), }) } if err := os.WriteFile(fullPath, []byte(data), 0644); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "path": fullPath, }) @@ -785,7 +785,7 @@ func (r *extensionRuntime) fileWrite(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "path and data are required", }) @@ -794,7 +794,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { path := call.Arguments[0].String() fullPath, err := r.validatePath(path) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -808,13 +808,13 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { encoding := runtimeOptionString(options, "encoding", "base64") if appendMode && hasOffset { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "append and offset cannot be used together", }) } if offset < 0 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "offset must be >= 0", }) @@ -822,7 +822,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { data, err := decodeRuntimeBytesValue(call.Arguments[1].Export(), encoding) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -830,7 +830,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { dir := filepath.Dir(fullPath) if err := os.MkdirAll(dir, 0755); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create directory: %v", err), }) @@ -846,7 +846,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { file, err := os.OpenFile(fullPath, flags, 0644) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -855,7 +855,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { if hasOffset && !appendMode { if _, err := file.Seek(offset, io.SeekStart); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to seek file: %v", err), }) @@ -864,7 +864,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { written, err := file.Write(data) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -876,7 +876,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { size = info.Size() } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "path": fullPath, "bytes_written": written, @@ -886,7 +886,7 @@ func (r *extensionRuntime) fileWriteBytes(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "source and destination paths are required", }) @@ -897,7 +897,7 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { fullSrc, err := r.validatePath(srcPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -905,7 +905,7 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { fullDst, err := r.validatePath(dstPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -913,7 +913,7 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { srcFile, err := os.Open(fullSrc) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to read source: %v", err), }) @@ -922,7 +922,7 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { dir := filepath.Dir(fullDst) if err := os.MkdirAll(dir, 0755); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create directory: %v", err), }) @@ -930,7 +930,7 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { dstFile, err := os.OpenFile(fullDst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to open destination: %v", err), }) @@ -938,20 +938,20 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { if _, err := io.Copy(dstFile, srcFile); err != nil { _ = dstFile.Close() - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to copy file: %v", err), }) } if err := dstFile.Close(); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to finalize destination: %v", err), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "path": fullDst, }) @@ -959,7 +959,7 @@ func (r *extensionRuntime) fileCopy(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) fileMove(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "source and destination paths are required", }) @@ -970,7 +970,7 @@ func (r *extensionRuntime) fileMove(call goja.FunctionCall) goja.Value { fullSrc, err := r.validatePath(srcPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -978,7 +978,7 @@ func (r *extensionRuntime) fileMove(call goja.FunctionCall) goja.Value { fullDst, err := r.validatePath(dstPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -986,20 +986,20 @@ func (r *extensionRuntime) fileMove(call goja.FunctionCall) goja.Value { dir := filepath.Dir(fullDst) if err := os.MkdirAll(dir, 0755); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to create directory: %v", err), }) } if err := os.Rename(fullSrc, fullDst); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": fmt.Sprintf("failed to move file: %v", err), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "path": fullDst, }) @@ -1007,7 +1007,7 @@ func (r *extensionRuntime) fileMove(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) fileGetSize(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "path is required", }) @@ -1016,7 +1016,7 @@ func (r *extensionRuntime) fileGetSize(call goja.FunctionCall) goja.Value { path := call.Arguments[0].String() fullPath, err := r.validatePath(path) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -1024,13 +1024,13 @@ func (r *extensionRuntime) fileGetSize(call goja.FunctionCall) goja.Value { info, err := os.Stat(fullPath) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "size": info.Size(), }) diff --git a/go_backend/extension_runtime_http.go b/go_backend/extension_runtime_http.go index 9b58ac71..b6c383a9 100644 --- a/go_backend/extension_runtime_http.go +++ b/go_backend/extension_runtime_http.go @@ -70,7 +70,7 @@ func (r *extensionRuntime) validateDomain(urlStr string) error { func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": "URL is required", }) } @@ -79,7 +79,7 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { if err := r.validateDomain(urlStr); err != nil { GoLog("[Extension:%s] HTTP blocked: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -87,7 +87,7 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { headers := make(map[string]string) if len(call.Arguments) > 1 && !goja.IsUndefined(call.Arguments[1]) && !goja.IsNull(call.Arguments[1]) { headersObj := call.Arguments[1].Export() - if h, ok := headersObj.(map[string]interface{}); ok { + if h, ok := headersObj.(map[string]any); ok { for k, v := range h { headers[k] = fmt.Sprintf("%v", v) } @@ -96,7 +96,7 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { req, err := http.NewRequest("GET", urlStr, nil) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -112,7 +112,7 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { resp, err := r.httpClient.Do(req) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -120,12 +120,12 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { body, err := readExtensionHTTPResponseBody(resp) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } - respHeaders := make(map[string]interface{}) + respHeaders := make(map[string]any) for k, v := range resp.Header { if len(v) == 1 { respHeaders[k] = v[0] @@ -134,7 +134,7 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { } } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "statusCode": resp.StatusCode, "status": resp.StatusCode, "ok": resp.StatusCode >= 200 && resp.StatusCode < 300, @@ -146,7 +146,7 @@ func (r *extensionRuntime) httpGet(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": "URL is required", }) } @@ -155,7 +155,7 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { if err := r.validateDomain(urlStr); err != nil { GoLog("[Extension:%s] HTTP blocked: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -166,10 +166,10 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { switch v := bodyArg.(type) { case string: bodyStr = v - case map[string]interface{}, []interface{}: + case map[string]any, []any: jsonBytes, err := json.Marshal(v) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": fmt.Sprintf("failed to stringify body: %v", err), }) } @@ -182,7 +182,7 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { headers := make(map[string]string) if len(call.Arguments) > 2 && !goja.IsUndefined(call.Arguments[2]) && !goja.IsNull(call.Arguments[2]) { headersObj := call.Arguments[2].Export() - if h, ok := headersObj.(map[string]interface{}); ok { + if h, ok := headersObj.(map[string]any); ok { for k, v := range h { headers[k] = fmt.Sprintf("%v", v) } @@ -191,7 +191,7 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { req, err := http.NewRequest("POST", urlStr, strings.NewReader(bodyStr)) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -210,7 +210,7 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { resp, err := r.httpClient.Do(req) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -218,12 +218,12 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { body, err := readExtensionHTTPResponseBody(resp) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } - respHeaders := make(map[string]interface{}) + respHeaders := make(map[string]any) for k, v := range resp.Header { if len(v) == 1 { respHeaders[k] = v[0] @@ -232,7 +232,7 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { } } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "statusCode": resp.StatusCode, "status": resp.StatusCode, "ok": resp.StatusCode >= 200 && resp.StatusCode < 300, @@ -244,7 +244,7 @@ func (r *extensionRuntime) httpPost(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": "URL is required", }) } @@ -253,7 +253,7 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { if err := r.validateDomain(urlStr); err != nil { GoLog("[Extension:%s] HTTP blocked: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -264,7 +264,7 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { if len(call.Arguments) > 1 && !goja.IsUndefined(call.Arguments[1]) && !goja.IsNull(call.Arguments[1]) { optionsObj := call.Arguments[1].Export() - if opts, ok := optionsObj.(map[string]interface{}); ok { + if opts, ok := optionsObj.(map[string]any); ok { if m, ok := opts["method"].(string); ok { method = strings.ToUpper(m) } @@ -273,10 +273,10 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { switch v := bodyArg.(type) { case string: bodyStr = v - case map[string]interface{}, []interface{}: + case map[string]any, []any: jsonBytes, err := json.Marshal(v) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": fmt.Sprintf("failed to stringify body: %v", err), }) } @@ -286,7 +286,7 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { } } - if h, ok := opts["headers"].(map[string]interface{}); ok { + if h, ok := opts["headers"].(map[string]any); ok { for k, v := range h { headers[k] = fmt.Sprintf("%v", v) } @@ -301,7 +301,7 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { req, err := http.NewRequest(method, urlStr, reqBody) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -320,7 +320,7 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { resp, err := r.httpClient.Do(req) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -328,12 +328,12 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { body, err := readExtensionHTTPResponseBody(resp) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } - respHeaders := make(map[string]interface{}) + respHeaders := make(map[string]any) for k, v := range resp.Header { if len(v) == 1 { respHeaders[k] = v[0] @@ -342,7 +342,7 @@ func (r *extensionRuntime) httpRequest(call goja.FunctionCall) goja.Value { } } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "statusCode": resp.StatusCode, "status": resp.StatusCode, "ok": resp.StatusCode >= 200 && resp.StatusCode < 300, @@ -366,7 +366,7 @@ func (r *extensionRuntime) httpPatch(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": "URL is required", }) } @@ -375,7 +375,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC if err := r.validateDomain(urlStr); err != nil { GoLog("[Extension:%s] HTTP blocked: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -386,7 +386,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC if method == "DELETE" { if len(call.Arguments) > 1 && !goja.IsUndefined(call.Arguments[1]) && !goja.IsNull(call.Arguments[1]) { headersObj := call.Arguments[1].Export() - if h, ok := headersObj.(map[string]interface{}); ok { + if h, ok := headersObj.(map[string]any); ok { for k, v := range h { headers[k] = fmt.Sprintf("%v", v) } @@ -398,10 +398,10 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC switch v := bodyArg.(type) { case string: bodyStr = v - case map[string]interface{}, []interface{}: + case map[string]any, []any: jsonBytes, err := json.Marshal(v) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": fmt.Sprintf("failed to stringify body: %v", err), }) } @@ -413,7 +413,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC if len(call.Arguments) > 2 && !goja.IsUndefined(call.Arguments[2]) && !goja.IsNull(call.Arguments[2]) { headersObj := call.Arguments[2].Export() - if h, ok := headersObj.(map[string]interface{}); ok { + if h, ok := headersObj.(map[string]any); ok { for k, v := range h { headers[k] = fmt.Sprintf("%v", v) } @@ -428,7 +428,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC req, err := http.NewRequest(method, urlStr, reqBody) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -446,7 +446,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC resp, err := r.httpClient.Do(req) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } @@ -454,12 +454,12 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC body, err := readExtensionHTTPResponseBody(resp) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "error": err.Error(), }) } - respHeaders := make(map[string]interface{}) + respHeaders := make(map[string]any) for k, v := range resp.Header { if len(v) == 1 { respHeaders[k] = v[0] @@ -468,7 +468,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC } } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "statusCode": resp.StatusCode, "status": resp.StatusCode, "ok": resp.StatusCode >= 200 && resp.StatusCode < 300, diff --git a/go_backend/extension_runtime_polyfills.go b/go_backend/extension_runtime_polyfills.go index 1e51cde5..7025b2f2 100644 --- a/go_backend/extension_runtime_polyfills.go +++ b/go_backend/extension_runtime_polyfills.go @@ -29,7 +29,7 @@ func (r *extensionRuntime) fetchPolyfill(call goja.FunctionCall) goja.Value { if len(call.Arguments) > 1 && !goja.IsUndefined(call.Arguments[1]) && !goja.IsNull(call.Arguments[1]) { optionsObj := call.Arguments[1].Export() - if opts, ok := optionsObj.(map[string]interface{}); ok { + if opts, ok := optionsObj.(map[string]any); ok { if m, ok := opts["method"].(string); ok { method = strings.ToUpper(m) } @@ -38,7 +38,7 @@ func (r *extensionRuntime) fetchPolyfill(call goja.FunctionCall) goja.Value { switch v := bodyArg.(type) { case string: bodyStr = v - case map[string]interface{}, []interface{}: + case map[string]any, []any: jsonBytes, err := json.Marshal(v) if err != nil { return r.createFetchError(fmt.Sprintf("failed to stringify body: %v", err)) @@ -51,7 +51,7 @@ func (r *extensionRuntime) fetchPolyfill(call goja.FunctionCall) goja.Value { if h, ok := opts["headers"]; ok && h != nil { switch hv := h.(type) { - case map[string]interface{}: + case map[string]any: for k, v := range hv { headers[k] = fmt.Sprintf("%v", v) } @@ -92,7 +92,7 @@ func (r *extensionRuntime) fetchPolyfill(call goja.FunctionCall) goja.Value { return r.createFetchError(err.Error()) } - respHeaders := make(map[string]interface{}) + respHeaders := make(map[string]any) for k, v := range resp.Header { if len(v) == 1 { respHeaders[k] = v[0] @@ -115,7 +115,7 @@ func (r *extensionRuntime) fetchPolyfill(call goja.FunctionCall) goja.Value { }) responseObj.Set("json", func(call goja.FunctionCall) goja.Value { - var result interface{} + var result any if err := json.Unmarshal(body, &result); err != nil { GoLog("[Extension:%s] fetch json() parse error: %v\n", r.extensionID, err) return goja.Undefined() @@ -124,7 +124,7 @@ func (r *extensionRuntime) fetchPolyfill(call goja.FunctionCall) goja.Value { }) responseObj.Set("arrayBuffer", func(call goja.FunctionCall) goja.Value { - byteArray := make([]interface{}, len(body)) + byteArray := make([]any, len(body)) for i, b := range body { byteArray[i] = int(b) } @@ -185,7 +185,7 @@ func (r *extensionRuntime) registerTextEncoderDecoder(vm *goja.Runtime) { input := call.Arguments[0].String() bytes := []byte(input) - result := make([]interface{}, len(bytes)) + result := make([]any, len(bytes)) for i, b := range bytes { result[i] = int(b) } @@ -194,10 +194,10 @@ func (r *extensionRuntime) registerTextEncoderDecoder(vm *goja.Runtime) { encoder.Set("encodeInto", func(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return vm.ToValue(map[string]interface{}{"read": 0, "written": 0}) + return vm.ToValue(map[string]any{"read": 0, "written": 0}) } input := call.Arguments[0].String() - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "read": len(input), "written": len([]byte(input)), }) @@ -228,7 +228,7 @@ func (r *extensionRuntime) registerTextEncoderDecoder(vm *goja.Runtime) { switch v := input.(type) { case []byte: bytes = v - case []interface{}: + case []any: bytes = make([]byte, len(v)) for i, val := range v { switch n := val.(type) { @@ -357,7 +357,7 @@ func (r *extensionRuntime) registerURLClass(vm *goja.Runtime) { case string: parsed, _ := url.ParseQuery(strings.TrimPrefix(v, "?")) values = parsed - case map[string]interface{}: + case map[string]any: for k, val := range v { values.Set(k, fmt.Sprintf("%v", val)) } diff --git a/go_backend/extension_runtime_storage.go b/go_backend/extension_runtime_storage.go index 1454576f..099a17b2 100644 --- a/go_backend/extension_runtime_storage.go +++ b/go_backend/extension_runtime_storage.go @@ -46,11 +46,11 @@ func (r *extensionRuntime) getStoragePath() string { return filepath.Join(r.dataDir, "storage.json") } -func cloneInterfaceMap(src map[string]interface{}) map[string]interface{} { +func cloneInterfaceMap(src map[string]any) map[string]any { if len(src) == 0 { - return make(map[string]interface{}) + return make(map[string]any) } - dst := make(map[string]interface{}, len(src)) + dst := make(map[string]any, len(src)) for k, v := range src { dst[k] = v } @@ -78,19 +78,19 @@ func (r *extensionRuntime) ensureStorageLoaded() error { fileMu.Unlock() if err != nil { if os.IsNotExist(err) { - r.storageCache = make(map[string]interface{}) + r.storageCache = make(map[string]any) r.storageLoaded = true return nil } return err } - var storage map[string]interface{} + var storage map[string]any if err := json.Unmarshal(data, &storage); err != nil { return err } if storage == nil { - storage = make(map[string]interface{}) + storage = make(map[string]any) } r.storageCache = storage @@ -98,7 +98,7 @@ func (r *extensionRuntime) ensureStorageLoaded() error { return nil } -func (r *extensionRuntime) loadStorage() (map[string]interface{}, error) { +func (r *extensionRuntime) loadStorage() (map[string]any, error) { if err := r.ensureStorageLoaded(); err != nil { return nil, err } @@ -118,7 +118,7 @@ func (r *extensionRuntime) queueStorageFlushLocked(delay time.Duration) { r.storageTimer = time.AfterFunc(delay, r.flushStorageDirtyAsync) } -func (r *extensionRuntime) persistStorageSnapshot(storage map[string]interface{}) error { +func (r *extensionRuntime) persistStorageSnapshot(storage map[string]any) error { data, err := json.Marshal(storage) if err != nil { return err @@ -343,7 +343,7 @@ func (r *extensionRuntime) ensureCredentialsLoaded() error { data, err := os.ReadFile(credPath) if err != nil { if os.IsNotExist(err) { - r.credentialsCache = make(map[string]interface{}) + r.credentialsCache = make(map[string]any) r.credentialsLoaded = true return nil } @@ -359,12 +359,12 @@ func (r *extensionRuntime) ensureCredentialsLoaded() error { return fmt.Errorf("failed to decrypt credentials: %w", err) } - var creds map[string]interface{} + var creds map[string]any if err := json.Unmarshal(decrypted, &creds); err != nil { return err } if creds == nil { - creds = make(map[string]interface{}) + creds = make(map[string]any) } r.credentialsCache = creds @@ -372,7 +372,7 @@ func (r *extensionRuntime) ensureCredentialsLoaded() error { return nil } -func (r *extensionRuntime) saveCredentials(creds map[string]interface{}) error { +func (r *extensionRuntime) saveCredentials(creds map[string]any) error { data, err := json.Marshal(creds) if err != nil { return err @@ -405,7 +405,7 @@ func (r *extensionRuntime) saveCredentials(creds map[string]interface{}) error { func (r *extensionRuntime) credentialsStore(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "key and value are required", }) @@ -416,7 +416,7 @@ func (r *extensionRuntime) credentialsStore(call goja.FunctionCall) goja.Value { if err := r.ensureCredentialsLoaded(); err != nil { GoLog("[Extension:%s] Credentials load error: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) @@ -429,13 +429,13 @@ func (r *extensionRuntime) credentialsStore(call goja.FunctionCall) goja.Value { if err := r.saveCredentials(nextCreds); err != nil { GoLog("[Extension:%s] Credentials save error: %v\n", r.extensionID, err) - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, }) } diff --git a/go_backend/extension_runtime_storage_test.go b/go_backend/extension_runtime_storage_test.go index 433ade6b..df33d41d 100644 --- a/go_backend/extension_runtime_storage_test.go +++ b/go_backend/extension_runtime_storage_test.go @@ -11,7 +11,7 @@ import ( "github.com/dop251/goja" ) -func setStorageValue(t *testing.T, runtime *extensionRuntime, key string, value interface{}) { +func setStorageValue(t *testing.T, runtime *extensionRuntime, key string, value any) { t.Helper() result := runtime.storageSet(goja.FunctionCall{ Arguments: []goja.Value{ @@ -24,14 +24,14 @@ func setStorageValue(t *testing.T, runtime *extensionRuntime, key string, value } } -func readStorageMap(t *testing.T, storagePath string) map[string]interface{} { +func readStorageMap(t *testing.T, storagePath string) map[string]any { t.Helper() data, err := os.ReadFile(storagePath) if err != nil { t.Fatalf("failed to read storage file: %v", err) } - var parsed map[string]interface{} + var parsed map[string]any if err := json.Unmarshal(data, &parsed); err != nil { t.Fatalf("failed to unmarshal storage file: %v", err) } @@ -70,7 +70,7 @@ func TestExtensionRuntimeStorage_DebouncedWriteCompactJSON(t *testing.T) { t.Fatalf("storage.json was not written within timeout") } - var parsed map[string]interface{} + var parsed map[string]any if err := json.Unmarshal(raw, &parsed); err != nil { t.Fatalf("failed to unmarshal storage file: %v", err) } diff --git a/go_backend/extension_runtime_supplement_test.go b/go_backend/extension_runtime_supplement_test.go index d626d39a..785387d5 100644 --- a/go_backend/extension_runtime_supplement_test.go +++ b/go_backend/extension_runtime_supplement_test.go @@ -26,7 +26,7 @@ func TestExtensionRuntimeAuthAndPolyfills(t *testing.T) { Network: []string{"auth.example.com", "token.example.com", "api.example.com"}, }, }, - settings: map[string]interface{}{}, + settings: map[string]any{}, httpClient: &http.Client{Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Host { case "token.example.com": @@ -63,7 +63,7 @@ func TestExtensionRuntimeAuthAndPolyfills(t *testing.T) { openResult := runtime.authOpenUrl(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("https://auth.example.com/login"), vm.ToValue("app://callback"), - }}).Export().(map[string]interface{}) + }}).Export().(map[string]any) if openResult["success"] != true { t.Fatalf("authOpenUrl = %#v", openResult) } @@ -73,7 +73,7 @@ func TestExtensionRuntimeAuthAndPolyfills(t *testing.T) { if code := runtime.authGetCode(goja.FunctionCall{}); !goja.IsUndefined(code) { t.Fatalf("expected undefined code, got %v", code) } - if ok := runtime.authSetCode(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(map[string]interface{}{"code": "abc", "access_token": "access", "refresh_token": "refresh", "expires_in": float64(60)})}}); !ok.ToBoolean() { + if ok := runtime.authSetCode(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(map[string]any{"code": "abc", "access_token": "access", "refresh_token": "refresh", "expires_in": float64(60)})}}); !ok.ToBoolean() { t.Fatal("authSetCode returned false") } if code := runtime.authGetCode(goja.FunctionCall{}).String(); code != "abc" { @@ -82,36 +82,36 @@ func TestExtensionRuntimeAuthAndPolyfills(t *testing.T) { if !runtime.authIsAuthenticated(goja.FunctionCall{}).ToBoolean() { t.Fatal("expected authenticated runtime") } - tokens := runtime.authGetTokens(goja.FunctionCall{}).Export().(map[string]interface{}) + tokens := runtime.authGetTokens(goja.FunctionCall{}).Export().(map[string]any) if tokens["access_token"] != "access" { t.Fatalf("tokens = %#v", tokens) } - pkce := runtime.authGeneratePKCE(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(float64(50))}}).Export().(map[string]interface{}) + pkce := runtime.authGeneratePKCE(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(float64(50))}}).Export().(map[string]any) if pkce["method"] != "S256" || pkce["verifier"] == "" || pkce["challenge"] == "" { t.Fatalf("pkce = %#v", pkce) } - if current := runtime.authGetPKCE(goja.FunctionCall{}).Export().(map[string]interface{}); current["verifier"] == "" { + if current := runtime.authGetPKCE(goja.FunctionCall{}).Export().(map[string]any); current["verifier"] == "" { t.Fatalf("current pkce = %#v", current) } - oauthConfig := map[string]interface{}{ + oauthConfig := map[string]any{ "authUrl": "https://auth.example.com/oauth", "clientId": "client", "redirectUri": "app://callback", "scope": "read", - "extraParams": map[string]interface{}{"prompt": "login"}, + "extraParams": map[string]any{"prompt": "login"}, } - oauth := runtime.authStartOAuthWithPKCE(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(oauthConfig)}}).Export().(map[string]interface{}) + oauth := runtime.authStartOAuthWithPKCE(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(oauthConfig)}}).Export().(map[string]any) if oauth["success"] != true || !strings.Contains(oauth["authUrl"].(string), "code_challenge") { t.Fatalf("oauth = %#v", oauth) } - tokenConfig := map[string]interface{}{ + tokenConfig := map[string]any{ "tokenUrl": "https://token.example.com/token", "clientId": "client", "redirectUri": "app://callback", "code": "abc", } - token := runtime.authExchangeCodeWithPKCE(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(tokenConfig)}}).Export().(map[string]interface{}) + token := runtime.authExchangeCodeWithPKCE(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(tokenConfig)}}).Export().(map[string]any) if token["success"] != true || token["access_token"] != "access" { t.Fatalf("token = %#v", token) } @@ -160,7 +160,7 @@ func TestExtensionRuntimeAuthAndPolyfills(t *testing.T) { if err != nil { t.Fatalf("polyfill script: %v", err) } - var result map[string]interface{} + var result map[string]any if err := json.Unmarshal([]byte(value.String()), &result); err != nil { t.Fatalf("decode polyfill result: %v", err) } @@ -380,7 +380,7 @@ func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) { t.Fatal("expected cleared store cache") } - settingsStore := &ExtensionSettingsStore{settings: map[string]map[string]interface{}{}} + settingsStore := &ExtensionSettingsStore{settings: map[string]map[string]any{}} if err := settingsStore.SetDataDir(filepath.Join(dir, "settings")); err != nil { t.Fatalf("SetDataDir: %v", err) } @@ -393,7 +393,7 @@ func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) { if _, err := settingsStore.Get("ext", "missing"); err == nil { t.Fatal("expected missing setting error") } - if err := settingsStore.SetAll("ext", map[string]interface{}{"a": float64(1), "_secret": "hidden"}); err != nil { + if err := settingsStore.SetAll("ext", map[string]any{"a": float64(1), "_secret": "hidden"}); err != nil { t.Fatalf("settings SetAll: %v", err) } if all := settingsStore.GetAll("ext"); all["a"] != float64(1) { @@ -408,7 +408,7 @@ func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) { if jsonText, err := settingsStore.GetAllExtensionSettingsJSON(); err != nil || jsonText == "" { t.Fatalf("settings JSON = %q/%v", jsonText, err) } - reloaded := &ExtensionSettingsStore{settings: map[string]map[string]interface{}{}} + reloaded := &ExtensionSettingsStore{settings: map[string]map[string]any{}} if err := reloaded.SetDataDir(settingsStore.dataDir); err != nil { t.Fatalf("reload settings: %v", err) } @@ -426,10 +426,10 @@ func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) { if got := runtime.storageGet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("missing"), vm.ToValue("fallback")}}).String(); got != "fallback" { t.Fatalf("storage fallback = %q", got) } - if ok := runtime.storageSet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("key"), vm.ToValue(map[string]interface{}{"nested": "value"})}}); !ok.ToBoolean() { + if ok := runtime.storageSet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("key"), vm.ToValue(map[string]any{"nested": "value"})}}); !ok.ToBoolean() { t.Fatal("storageSet false") } - if ok := runtime.storageSet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("key"), vm.ToValue(map[string]interface{}{"nested": "value"})}}); !ok.ToBoolean() { + if ok := runtime.storageSet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("key"), vm.ToValue(map[string]any{"nested": "value"})}}); !ok.ToBoolean() { t.Fatal("storageSet equal false") } loaded, err := runtime.loadStorage() @@ -455,7 +455,7 @@ func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) { if err := os.MkdirAll(credRuntime.dataDir, 0755); err != nil { t.Fatal(err) } - if result := credRuntime.credentialsStore(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("token"), vm.ToValue("secret")}}).Export().(map[string]interface{}); result["success"] != true { + if result := credRuntime.credentialsStore(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("token"), vm.ToValue("secret")}}).Export().(map[string]any); result["success"] != true { t.Fatalf("credentialsStore = %#v", result) } if got := credRuntime.credentialsGet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("token")}}).String(); got != "secret" { @@ -529,14 +529,14 @@ func TestExtensionRuntimeHTTPMatchingAndMetadataHelpers(t *testing.T) { t.Fatalf("expected domain validation error for %s", rawURL) } } - if got := runtime.httpGet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/get"), vm.ToValue(map[string]interface{}{"X-Test": "yes"})}}).Export().(map[string]interface{}); got["status"] != 201 || !strings.Contains(got["body"].(string), "GET") { + if got := runtime.httpGet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/get"), vm.ToValue(map[string]any{"X-Test": "yes"})}}).Export().(map[string]any); got["status"] != 201 || !strings.Contains(got["body"].(string), "GET") { t.Fatalf("httpGet = %#v", got) } - if got := runtime.httpPost(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/post"), vm.ToValue(map[string]interface{}{"a": "b"})}}).Export().(map[string]interface{}); !strings.Contains(got["body"].(string), "POST") { + if got := runtime.httpPost(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/post"), vm.ToValue(map[string]any{"a": "b"})}}).Export().(map[string]any); !strings.Contains(got["body"].(string), "POST") { t.Fatalf("httpPost = %#v", got) } - requestOptions := map[string]interface{}{"method": "patch", "body": []interface{}{"x"}, "headers": map[string]interface{}{"X-Req": "1"}} - if got := runtime.httpRequest(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/request"), vm.ToValue(requestOptions)}}).Export().(map[string]interface{}); !strings.Contains(got["body"].(string), "PATCH") { + requestOptions := map[string]any{"method": "patch", "body": []any{"x"}, "headers": map[string]any{"X-Req": "1"}} + if got := runtime.httpRequest(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/request"), vm.ToValue(requestOptions)}}).Export().(map[string]any); !strings.Contains(got["body"].(string), "PATCH") { t.Fatalf("httpRequest = %#v", got) } for _, method := range []struct { @@ -545,14 +545,14 @@ func TestExtensionRuntimeHTTPMatchingAndMetadataHelpers(t *testing.T) { args []goja.Value }{ {name: "PUT", call: runtime.httpPut, args: []goja.Value{vm.ToValue("https://api.example.com/put"), vm.ToValue("body")}}, - {name: "DELETE", call: runtime.httpDelete, args: []goja.Value{vm.ToValue("https://api.example.com/delete"), vm.ToValue(map[string]interface{}{"X-Delete": "1"})}}, - {name: "PATCH", call: runtime.httpPatch, args: []goja.Value{vm.ToValue("https://api.example.com/patch"), vm.ToValue(map[string]interface{}{"p": "q"})}}, + {name: "DELETE", call: runtime.httpDelete, args: []goja.Value{vm.ToValue("https://api.example.com/delete"), vm.ToValue(map[string]any{"X-Delete": "1"})}}, + {name: "PATCH", call: runtime.httpPatch, args: []goja.Value{vm.ToValue("https://api.example.com/patch"), vm.ToValue(map[string]any{"p": "q"})}}, } { - if got := method.call(goja.FunctionCall{Arguments: method.args}).Export().(map[string]interface{}); !strings.Contains(got["body"].(string), method.name) { + if got := method.call(goja.FunctionCall{Arguments: method.args}).Export().(map[string]any); !strings.Contains(got["body"].(string), method.name) { t.Fatalf("%s = %#v", method.name, got) } } - if got := runtime.httpGet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/huge")}}).Export().(map[string]interface{}); !strings.Contains(got["error"].(string), "exceeds") { + if got := runtime.httpGet(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("https://api.example.com/huge")}}).Export().(map[string]any); !strings.Contains(got["error"].(string), "exceeds") { t.Fatalf("huge response = %#v", got) } if !runtime.httpClearCookies(goja.FunctionCall{}).ToBoolean() { @@ -652,14 +652,14 @@ func TestExtensionRuntimeFileAPIs(t *testing.T) { t.Fatalf("absolute validatePath = %q/%v", got, err) } - write := runtime.fileWrite(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/a.txt"), vm.ToValue("hello")}}).Export().(map[string]interface{}) + write := runtime.fileWrite(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/a.txt"), vm.ToValue("hello")}}).Export().(map[string]any) if write["success"] != true { t.Fatalf("fileWrite = %#v", write) } if !runtime.fileExists(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/a.txt")}}).ToBoolean() { t.Fatal("expected written file to exist") } - read := runtime.fileRead(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/a.txt")}}).Export().(map[string]interface{}) + read := runtime.fileRead(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/a.txt")}}).Export().(map[string]any) if read["data"] != "hello" { t.Fatalf("fileRead = %#v", read) } @@ -667,53 +667,53 @@ func TestExtensionRuntimeFileAPIs(t *testing.T) { writeBytes := runtime.fileWriteBytes(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("nested/bytes.bin"), vm.ToValue("4869"), - vm.ToValue(map[string]interface{}{"encoding": "hex", "truncate": true}), - }}).Export().(map[string]interface{}) + vm.ToValue(map[string]any{"encoding": "hex", "truncate": true}), + }}).Export().(map[string]any) if writeBytes["success"] != true { t.Fatalf("fileWriteBytes = %#v", writeBytes) } appendBytes := runtime.fileWriteBytes(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("nested/bytes.bin"), - vm.ToValue([]interface{}{float64('!')}), - vm.ToValue(map[string]interface{}{"append": true}), - }}).Export().(map[string]interface{}) + vm.ToValue([]any{float64('!')}), + vm.ToValue(map[string]any{"append": true}), + }}).Export().(map[string]any) if appendBytes["success"] != true { t.Fatalf("append fileWriteBytes = %#v", appendBytes) } readBytes := runtime.fileReadBytes(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("nested/bytes.bin"), - vm.ToValue(map[string]interface{}{"encoding": "text", "offset": float64(1), "length": float64(2)}), - }}).Export().(map[string]interface{}) + vm.ToValue(map[string]any{"encoding": "text", "offset": float64(1), "length": float64(2)}), + }}).Export().(map[string]any) if readBytes["data"] != "i!" || readBytes["bytes_read"] != 2 { t.Fatalf("fileReadBytes = %#v", readBytes) } if bad := runtime.fileWriteBytes(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("nested/bad.bin"), vm.ToValue("x"), - vm.ToValue(map[string]interface{}{"append": true, "offset": float64(1)}), - }}).Export().(map[string]interface{}); bad["success"] != false { + vm.ToValue(map[string]any{"append": true, "offset": float64(1)}), + }}).Export().(map[string]any); bad["success"] != false { t.Fatalf("expected append+offset failure, got %#v", bad) } if bad := runtime.fileReadBytes(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("nested/bytes.bin"), - vm.ToValue(map[string]interface{}{"encoding": "bad"}), - }}).Export().(map[string]interface{}); bad["success"] != false { + vm.ToValue(map[string]any{"encoding": "bad"}), + }}).Export().(map[string]any); bad["success"] != false { t.Fatalf("expected bad encoding failure, got %#v", bad) } - copyResult := runtime.fileCopy(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/bytes.bin"), vm.ToValue("nested/copy.bin")}}).Export().(map[string]interface{}) + copyResult := runtime.fileCopy(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/bytes.bin"), vm.ToValue("nested/copy.bin")}}).Export().(map[string]any) if copyResult["success"] != true { t.Fatalf("fileCopy = %#v", copyResult) } - moveResult := runtime.fileMove(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/copy.bin"), vm.ToValue("nested/moved.bin")}}).Export().(map[string]interface{}) + moveResult := runtime.fileMove(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/copy.bin"), vm.ToValue("nested/moved.bin")}}).Export().(map[string]any) if moveResult["success"] != true { t.Fatalf("fileMove = %#v", moveResult) } - sizeResult := runtime.fileGetSize(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/moved.bin")}}).Export().(map[string]interface{}) + sizeResult := runtime.fileGetSize(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/moved.bin")}}).Export().(map[string]any) if sizeResult["success"] != true || sizeResult["size"] != int64(3) { t.Fatalf("fileGetSize = %#v", sizeResult) } - deleteResult := runtime.fileDelete(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/moved.bin")}}).Export().(map[string]interface{}) + deleteResult := runtime.fileDelete(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("nested/moved.bin")}}).Export().(map[string]any) if deleteResult["success"] != true { t.Fatalf("fileDelete = %#v", deleteResult) } @@ -721,7 +721,7 @@ func TestExtensionRuntimeFileAPIs(t *testing.T) { download := runtime.fileDownload(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("https://files.example.com/file"), vm.ToValue("downloads/file.bin"), - }}).Export().(map[string]interface{}) + }}).Export().(map[string]any) if download["success"] != true { t.Fatalf("fileDownload = %#v", download) } @@ -732,8 +732,8 @@ func TestExtensionRuntimeFileAPIs(t *testing.T) { chunked := runtime.fileDownload(goja.FunctionCall{Arguments: []goja.Value{ vm.ToValue("https://files.example.com/chunk"), vm.ToValue("downloads/chunk.bin"), - vm.ToValue(map[string]interface{}{"chunked": float64(2), "headers": map[string]interface{}{"X-Test": "yes"}}), - }}).Export().(map[string]interface{}) + vm.ToValue(map[string]any{"chunked": float64(2), "headers": map[string]any{"X-Test": "yes"}}), + }}).Export().(map[string]any) if chunked["success"] != true { t.Fatalf("chunked fileDownload = %#v", chunked) } @@ -741,7 +741,7 @@ func TestExtensionRuntimeFileAPIs(t *testing.T) { t.Fatalf("chunked data = %q/%v", data, err) } - if missing := runtime.fileDownload(goja.FunctionCall{}).Export().(map[string]interface{}); missing["success"] != false { + if missing := runtime.fileDownload(goja.FunctionCall{}).Export().(map[string]any); missing["success"] != false { t.Fatalf("expected missing download args error, got %#v", missing) } } @@ -759,31 +759,31 @@ func TestExtensionRuntimeUtilityAPIs(t *testing.T) { if runtime.hmacSHA256Base64(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("msg"), vm.ToValue("key")}}).String() == "" { t.Fatal("expected hmac sha256 base64") } - if value := runtime.hmacSHA1(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue([]interface{}{float64(1), float64(2)}), vm.ToValue([]interface{}{float64(3)})}}); len(value.Export().([]interface{})) == 0 { + if value := runtime.hmacSHA1(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue([]any{float64(1), float64(2)}), vm.ToValue([]any{float64(3)})}}); len(value.Export().([]any)) == 0 { t.Fatal("expected hmac sha1 bytes") } if !goja.IsUndefined(runtime.parseJSON(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(`{bad`)}})) { t.Fatal("expected invalid JSON to return undefined") } - parsed := runtime.parseJSON(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(`{"ok":true}`)}}).Export().(map[string]interface{}) + parsed := runtime.parseJSON(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(`{"ok":true}`)}}).Export().(map[string]any) if parsed["ok"] != true { t.Fatalf("parseJSON = %#v", parsed) } - if text := runtime.stringifyJSON(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(map[string]interface{}{"ok": true})}}).String(); !strings.Contains(text, "ok") { + if text := runtime.stringifyJSON(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(map[string]any{"ok": true})}}).String(); !strings.Contains(text, "ok") { t.Fatalf("stringifyJSON = %q", text) } - encrypted := runtime.cryptoEncrypt(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("plain"), vm.ToValue("secret")}}).Export().(map[string]interface{}) + encrypted := runtime.cryptoEncrypt(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("plain"), vm.ToValue("secret")}}).Export().(map[string]any) if encrypted["success"] != true || encrypted["data"] == "" { t.Fatalf("cryptoEncrypt = %#v", encrypted) } - decrypted := runtime.cryptoDecrypt(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(encrypted["data"]), vm.ToValue("secret")}}).Export().(map[string]interface{}) + decrypted := runtime.cryptoDecrypt(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(encrypted["data"]), vm.ToValue("secret")}}).Export().(map[string]any) if decrypted["success"] != true || decrypted["data"] != "plain" { t.Fatalf("cryptoDecrypt = %#v", decrypted) } - if bad := runtime.cryptoDecrypt(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("bad"), vm.ToValue("secret")}}).Export().(map[string]interface{}); bad["success"] != false { + if bad := runtime.cryptoDecrypt(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("bad"), vm.ToValue("secret")}}).Export().(map[string]any); bad["success"] != false { t.Fatalf("expected bad decrypt failure, got %#v", bad) } - key := runtime.cryptoGenerateKey(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(float64(8))}}).Export().(map[string]interface{}) + key := runtime.cryptoGenerateKey(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue(float64(8))}}).Export().(map[string]any) if key["success"] != true || key["key"] == "" || key["hex"] == "" { t.Fatalf("cryptoGenerateKey = %#v", key) } diff --git a/go_backend/extension_runtime_utils.go b/go_backend/extension_runtime_utils.go index 8b568c9b..f7271e02 100644 --- a/go_backend/extension_runtime_utils.go +++ b/go_backend/extension_runtime_utils.go @@ -88,7 +88,7 @@ func (r *extensionRuntime) hmacSHA1(call goja.FunctionCall) goja.Value { switch k := keyArg.(type) { case string: keyBytes = []byte(k) - case []interface{}: + case []any: keyBytes = make([]byte, len(k)) for i, v := range k { if num, ok := v.(int64); ok { @@ -106,7 +106,7 @@ func (r *extensionRuntime) hmacSHA1(call goja.FunctionCall) goja.Value { switch m := msgArg.(type) { case string: msgBytes = []byte(m) - case []interface{}: + case []any: msgBytes = make([]byte, len(m)) for i, v := range m { if num, ok := v.(int64); ok { @@ -123,7 +123,7 @@ func (r *extensionRuntime) hmacSHA1(call goja.FunctionCall) goja.Value { mac.Write(msgBytes) result := mac.Sum(nil) - jsArray := make([]interface{}, len(result)) + jsArray := make([]any, len(result)) for i, b := range result { jsArray[i] = int(b) } @@ -136,7 +136,7 @@ func (r *extensionRuntime) parseJSON(call goja.FunctionCall) goja.Value { } input := call.Arguments[0].String() - var result interface{} + var result any if err := json.Unmarshal([]byte(input), &result); err != nil { GoLog("[Extension:%s] JSON parse error: %v\n", r.extensionID, err) return goja.Undefined() @@ -162,7 +162,7 @@ func (r *extensionRuntime) stringifyJSON(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) cryptoEncrypt(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "plaintext and key are required", }) @@ -175,13 +175,13 @@ func (r *extensionRuntime) cryptoEncrypt(call goja.FunctionCall) goja.Value { encrypted, err := encryptAES([]byte(plaintext), keyHash[:]) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": base64.StdEncoding.EncodeToString(encrypted), }) @@ -189,7 +189,7 @@ func (r *extensionRuntime) cryptoEncrypt(call goja.FunctionCall) goja.Value { func (r *extensionRuntime) cryptoDecrypt(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "ciphertext and key are required", }) @@ -200,7 +200,7 @@ func (r *extensionRuntime) cryptoDecrypt(call goja.FunctionCall) goja.Value { ciphertext, err := base64.StdEncoding.DecodeString(ciphertextB64) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "invalid base64 ciphertext", }) @@ -210,13 +210,13 @@ func (r *extensionRuntime) cryptoDecrypt(call goja.FunctionCall) goja.Value { decrypted, err := decryptAES(ciphertext, keyHash[:]) if err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": "invalid base64 ciphertext", }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "data": string(decrypted), }) @@ -232,13 +232,13 @@ func (r *extensionRuntime) cryptoGenerateKey(call goja.FunctionCall) goja.Value key := make([]byte, length) if _, err := rand.Read(key); err != nil { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": false, "error": err.Error(), }) } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "success": true, "key": base64.StdEncoding.EncodeToString(key), "hex": hex.EncodeToString(key), @@ -397,7 +397,7 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { obj.Set("getAudioQuality", func(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 1 { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": "file path is required", }) } @@ -405,12 +405,12 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { filePath := call.Arguments[0].String() quality, err := GetAudioQuality(filePath) if err != nil { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": err.Error(), }) } - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "bitDepth": quality.BitDepth, "sampleRate": quality.SampleRate, "totalSamples": quality.TotalSamples, @@ -421,7 +421,7 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { obj.Set("getLyricsLRC", func(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 3 { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": "spotifyID, trackName, and artistName are required", }) } @@ -440,19 +440,19 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { lyrics, err := GetLyricsLRC(spotifyID, trackName, artistName, filePath, durationMs) if err != nil { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": err.Error(), }) } - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "lyrics": lyrics, }) }) obj.Set("checkISRCExists", func(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": "outputDir and isrc are required", }) } @@ -460,13 +460,13 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { outputDir := strings.TrimSpace(call.Arguments[0].String()) isrc := strings.TrimSpace(call.Arguments[1].String()) if outputDir == "" || isrc == "" { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": "outputDir and isrc are required", }) } filePath, exists := checkISRCExistsInternal(outputDir, isrc) - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "exists": exists, "filePath": filePath, }) @@ -474,7 +474,7 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { obj.Set("addToISRCIndex", func(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 3 { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": "outputDir, isrc, and filePath are required", }) } @@ -483,13 +483,13 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { isrc := strings.TrimSpace(call.Arguments[1].String()) filePath := strings.TrimSpace(call.Arguments[2].String()) if outputDir == "" || isrc == "" || filePath == "" { - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "error": "outputDir, isrc, and filePath are required", }) } AddToISRCIndex(outputDir, isrc, filePath) - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "success": true, }) }) @@ -502,7 +502,7 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { template := call.Arguments[0].String() metadataObj := call.Arguments[1].Export() - metadata, ok := metadataObj.(map[string]interface{}) + metadata, ok := metadataObj.(map[string]any) if !ok { return vm.ToValue("") } @@ -515,7 +515,7 @@ func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) { _, offsetSeconds := now.Zone() offsetMinutes := offsetSeconds / 60 - return vm.ToValue(map[string]interface{}{ + return vm.ToValue(map[string]any{ "year": now.Year(), "month": int(now.Month()), "day": now.Day(), diff --git a/go_backend/extension_settings.go b/go_backend/extension_settings.go index e241f6e2..2980712a 100644 --- a/go_backend/extension_settings.go +++ b/go_backend/extension_settings.go @@ -11,7 +11,7 @@ import ( type ExtensionSettingsStore struct { mu sync.RWMutex dataDir string - settings map[string]map[string]interface{} // extensionID -> settings + settings map[string]map[string]any // extensionID -> settings } var ( @@ -22,7 +22,7 @@ var ( func GetExtensionSettingsStore() *ExtensionSettingsStore { globalSettingsStoreOnce.Do(func() { globalSettingsStore = &ExtensionSettingsStore{ - settings: make(map[string]map[string]interface{}), + settings: make(map[string]map[string]any), } }) return globalSettingsStore @@ -68,17 +68,17 @@ func (s *ExtensionSettingsStore) loadAllSettings() error { return nil } -func (s *ExtensionSettingsStore) loadSettings(extensionID string) (map[string]interface{}, error) { +func (s *ExtensionSettingsStore) loadSettings(extensionID string) (map[string]any, error) { settingsPath := s.getSettingsPath(extensionID) data, err := os.ReadFile(settingsPath) if err != nil { if os.IsNotExist(err) { - return make(map[string]interface{}), nil + return make(map[string]any), nil } return nil, err } - var settings map[string]interface{} + var settings map[string]any if err := json.Unmarshal(data, &settings); err != nil { return nil, err } @@ -86,7 +86,7 @@ func (s *ExtensionSettingsStore) loadSettings(extensionID string) (map[string]in return settings, nil } -func (s *ExtensionSettingsStore) saveSettings(extensionID string, settings map[string]interface{}) error { +func (s *ExtensionSettingsStore) saveSettings(extensionID string, settings map[string]any) error { settingsPath := s.getSettingsPath(extensionID) dir := filepath.Dir(settingsPath) @@ -102,7 +102,7 @@ func (s *ExtensionSettingsStore) saveSettings(extensionID string, settings map[s return os.WriteFile(settingsPath, data, 0644) } -func (s *ExtensionSettingsStore) Get(extensionID, key string) (interface{}, error) { +func (s *ExtensionSettingsStore) Get(extensionID, key string) (any, error) { s.mu.RLock() defer s.mu.RUnlock() @@ -118,28 +118,28 @@ func (s *ExtensionSettingsStore) Get(extensionID, key string) (interface{}, erro return value, nil } -func (s *ExtensionSettingsStore) GetAll(extensionID string) map[string]interface{} { +func (s *ExtensionSettingsStore) GetAll(extensionID string) map[string]any { s.mu.RLock() defer s.mu.RUnlock() extSettings, exists := s.settings[extensionID] if !exists { - return make(map[string]interface{}) + return make(map[string]any) } - result := make(map[string]interface{}) + result := make(map[string]any) for k, v := range extSettings { result[k] = v } return result } -func (s *ExtensionSettingsStore) Set(extensionID, key string, value interface{}) error { +func (s *ExtensionSettingsStore) Set(extensionID, key string, value any) error { s.mu.Lock() defer s.mu.Unlock() if _, exists := s.settings[extensionID]; !exists { - s.settings[extensionID] = make(map[string]interface{}) + s.settings[extensionID] = make(map[string]any) } s.settings[extensionID][key] = value @@ -147,7 +147,7 @@ func (s *ExtensionSettingsStore) Set(extensionID, key string, value interface{}) return s.saveSettings(extensionID, s.settings[extensionID]) } -func (s *ExtensionSettingsStore) SetAll(extensionID string, settings map[string]interface{}) error { +func (s *ExtensionSettingsStore) SetAll(extensionID string, settings map[string]any) error { s.mu.Lock() defer s.mu.Unlock() diff --git a/go_backend/extension_signed_session.go b/go_backend/extension_signed_session.go index 0b445758..978ecc2e 100644 --- a/go_backend/extension_signed_session.go +++ b/go_backend/extension_signed_session.go @@ -204,17 +204,17 @@ func parseSignedSessionTime(value string) (time.Time, bool) { func (r *extensionRuntime) signedSessionStatus(call goja.FunctionCall) goja.Value { config := signedSessionConfigWithDefaults(r.manifest.SignedSession) if config.Namespace == "" || config.BaseURL == "" { - return r.vm.ToValue(map[string]interface{}{"authenticated": false, "error": "signedSession is not configured"}) + return r.vm.ToValue(map[string]any{"authenticated": false, "error": "signedSession is not configured"}) } record, err := r.loadSignedSession(config) if err != nil { - return r.vm.ToValue(map[string]interface{}{"authenticated": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"authenticated": false, "error": err.Error()}) } authenticated := record.SessionID != "" && record.SessionSecret != "" if expiresAt, ok := parseSignedSessionTime(record.ExpiresAt); ok && time.Now().After(expiresAt) { authenticated = false } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "authenticated": authenticated, "expires_at": record.ExpiresAt, "install_id": record.InstallID, @@ -228,16 +228,16 @@ func (r *extensionRuntime) signedSessionClear(call goja.FunctionCall) goja.Value config := signedSessionConfigWithDefaults(r.manifest.SignedSession) record, err := r.loadSignedSession(config) if err != nil { - return r.vm.ToValue(map[string]interface{}{"success": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"success": false, "error": err.Error()}) } record.SessionID = "" record.SessionSecret = "" record.ExpiresAt = "" if err := r.saveSignedSession(config, record); err != nil { - return r.vm.ToValue(map[string]interface{}{"success": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"success": false, "error": err.Error()}) } ClearPendingAuthRequest(r.extensionID) - return r.vm.ToValue(map[string]interface{}{"success": true}) + return r.vm.ToValue(map[string]any{"success": true}) } func (r *extensionRuntime) signedSessionCompleteGrant(call goja.FunctionCall) goja.Value { @@ -252,13 +252,13 @@ func (r *extensionRuntime) signedSessionCompleteGrant(call goja.FunctionCall) go pendingSignedSessionGrantsMu.Unlock() } if grant == "" { - return r.vm.ToValue(map[string]interface{}{"success": false, "error": "no pending grant"}) + return r.vm.ToValue(map[string]any{"success": false, "error": "no pending grant"}) } if err := r.exchangeSignedSessionGrant(grant); err != nil { - return r.vm.ToValue(map[string]interface{}{"success": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"success": false, "error": err.Error()}) } ClearPendingAuthRequest(r.extensionID) - return r.vm.ToValue(map[string]interface{}{"success": true}) + return r.vm.ToValue(map[string]any{"success": true}) } func (r *extensionRuntime) exchangeSignedSessionGrant(grant string) error { @@ -271,7 +271,7 @@ func (r *extensionRuntime) exchangeSignedSessionGrant(grant string) error { if err != nil { return err } - payload := map[string]interface{}{ + payload := map[string]any{ "grant": grant, "install_id": record.InstallID, "app_version": config.AppVersion, @@ -312,11 +312,11 @@ func (r *extensionRuntime) exchangeSignedSessionGrant(grant string) error { func (r *extensionRuntime) signedSessionFetch(call goja.FunctionCall) goja.Value { if len(call.Arguments) < 2 { - return r.vm.ToValue(map[string]interface{}{"ok": false, "error": "method and path are required"}) + return r.vm.ToValue(map[string]any{"ok": false, "error": "method and path are required"}) } config := signedSessionConfigWithDefaults(r.manifest.SignedSession) if config.Namespace == "" || config.BaseURL == "" { - return r.vm.ToValue(map[string]interface{}{"ok": false, "error": "signedSession is not configured"}) + return r.vm.ToValue(map[string]any{"ok": false, "error": "signedSession is not configured"}) } method := strings.ToUpper(strings.TrimSpace(call.Arguments[0].String())) requestPath := call.Arguments[1].String() @@ -325,10 +325,10 @@ func (r *extensionRuntime) signedSessionFetch(call goja.FunctionCall) goja.Value switch v := call.Arguments[2].Export().(type) { case string: body = []byte(v) - case map[string]interface{}, []interface{}: + case map[string]any, []any: encoded, err := json.Marshal(v) if err != nil { - return r.vm.ToValue(map[string]interface{}{"ok": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"ok": false, "error": err.Error()}) } body = encoded default: @@ -337,7 +337,7 @@ func (r *extensionRuntime) signedSessionFetch(call goja.FunctionCall) goja.Value } extraHeaders := map[string]string{} if len(call.Arguments) > 3 && !goja.IsUndefined(call.Arguments[3]) && !goja.IsNull(call.Arguments[3]) { - if h, ok := call.Arguments[3].Export().(map[string]interface{}); ok { + if h, ok := call.Arguments[3].Export().(map[string]any); ok { for k, v := range h { extraHeaders[k] = fmt.Sprintf("%v", v) } @@ -349,12 +349,12 @@ func (r *extensionRuntime) signedSessionFetch(call goja.FunctionCall) goja.Value if authURL := r.startSignedSessionVerification(config, ""); authURL != "" { return r.signedSessionVerificationRequiredValue(authURL) } - return r.vm.ToValue(map[string]interface{}{"ok": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"ok": false, "error": err.Error()}) } resp, respBody, respHeaders, err := r.doSignedSessionRequest(config, record, method, requestPath, body, extraHeaders) if err != nil { - return r.vm.ToValue(map[string]interface{}{"ok": false, "error": err.Error()}) + return r.vm.ToValue(map[string]any{"ok": false, "error": err.Error()}) } if resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusPreconditionRequired { record.SessionID = "" @@ -365,7 +365,7 @@ func (r *extensionRuntime) signedSessionFetch(call goja.FunctionCall) goja.Value return r.signedSessionVerificationRequiredValue(authURL) } } - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "statusCode": resp.StatusCode, "status": resp.StatusCode, "ok": resp.StatusCode >= 200 && resp.StatusCode < 300, @@ -377,7 +377,7 @@ func (r *extensionRuntime) signedSessionFetch(call goja.FunctionCall) goja.Value } func (r *extensionRuntime) signedSessionVerificationRequiredValue(authURL string) goja.Value { - return r.vm.ToValue(map[string]interface{}{ + return r.vm.ToValue(map[string]any{ "ok": false, "needsVerification": true, "error": "VERIFY_REQUIRED", @@ -441,7 +441,7 @@ func (r *extensionRuntime) refreshSignedSession(config SignedSessionConfig, reco return nil } -func (r *extensionRuntime) startSignedSessionVerification(config SignedSessionConfig, reason string) string { +func (r *extensionRuntime) startSignedSessionVerification(config SignedSessionConfig, _ string) string { record, err := r.loadSignedSession(config) if err != nil { return "" @@ -550,7 +550,7 @@ func (r *extensionRuntime) doSignedSessionRequest( requestPath string, body []byte, extraHeaders map[string]string, -) (*http.Response, []byte, map[string]interface{}, error) { +) (*http.Response, []byte, map[string]any, error) { fullURL, err := signedSessionURL(config, requestPath) if err != nil { return nil, nil, nil, err @@ -612,7 +612,7 @@ func (r *extensionRuntime) doSignedSessionRequest( if err != nil { return nil, nil, nil, err } - headers := make(map[string]interface{}) + headers := make(map[string]any) for k, v := range resp.Header { if len(v) == 1 { headers[k] = v[0] diff --git a/go_backend/filename.go b/go_backend/filename.go index 7b5168b0..4fb2a316 100644 --- a/go_backend/filename.go +++ b/go_backend/filename.go @@ -79,7 +79,7 @@ func truncateUTF8Bytes(value string, maxBytes int) string { return value } -func buildFilenameFromTemplate(template string, metadata map[string]interface{}) string { +func buildFilenameFromTemplate(template string, metadata map[string]any) string { if template == "" { template = "{artist} - {title}" } @@ -94,20 +94,20 @@ func buildFilenameFromTemplate(template string, metadata map[string]interface{}) } placeholders := map[string]string{ - "{title}": getString(metadata, "title"), - "{artist}": getString(metadata, "artist"), - "{album}": getString(metadata, "album"), - "{track}": formatTrackNumber(getInt(metadata, "track")), - "{track_raw}": formatRawNumber(getInt(metadata, "track")), + "{title}": getString(metadata, "title"), + "{artist}": getString(metadata, "artist"), + "{album}": getString(metadata, "album"), + "{track}": formatTrackNumber(getInt(metadata, "track")), + "{track_raw}": formatRawNumber(getInt(metadata, "track")), "{playlist_position}": formatTrackNumber(getPlaylistPosition(metadata)), "{playlist position}": formatTrackNumber(getPlaylistPosition(metadata)), "{playlistPosition}": formatTrackNumber(getPlaylistPosition(metadata)), "{position}": formatTrackNumber(getPlaylistPosition(metadata)), "{playlist_position_raw}": formatRawNumber(getPlaylistPosition(metadata)), - "{year}": yearValue, - "{date}": dateValue, - "{disc}": formatDiscNumber(getInt(metadata, "disc")), - "{disc_raw}": formatRawNumber(getInt(metadata, "disc")), + "{year}": yearValue, + "{date}": dateValue, + "{disc}": formatDiscNumber(getInt(metadata, "disc")), + "{disc_raw}": formatRawNumber(getInt(metadata, "disc")), } for placeholder, value := range placeholders { @@ -117,7 +117,7 @@ func buildFilenameFromTemplate(template string, metadata map[string]interface{}) return result } -func replaceFormattedNumberPlaceholders(template string, metadata map[string]interface{}) string { +func replaceFormattedNumberPlaceholders(template string, metadata map[string]any) string { return formattedNumberPlaceholderExpr.ReplaceAllStringFunc(template, func(match string) string { parts := formattedNumberPlaceholderExpr.FindStringSubmatch(match) if len(parts) != 3 { @@ -137,7 +137,7 @@ func replaceFormattedNumberPlaceholders(template string, metadata map[string]int }) } -func replaceDateFormatPlaceholders(template string, metadata map[string]interface{}) string { +func replaceDateFormatPlaceholders(template string, metadata map[string]any) string { return dateFormatPlaceholderExpr.ReplaceAllStringFunc(template, func(match string) string { parts := dateFormatPlaceholderExpr.FindStringSubmatch(match) if len(parts) != 2 { @@ -148,7 +148,7 @@ func replaceDateFormatPlaceholders(template string, metadata map[string]interfac }) } -func getDateValue(metadata map[string]interface{}) string { +func getDateValue(metadata map[string]any) string { date := getString(metadata, "date") if date != "" { return date @@ -162,7 +162,7 @@ func getDateValue(metadata map[string]interface{}) string { return getString(metadata, "year") } -func getString(m map[string]interface{}, key string) string { +func getString(m map[string]any, key string) string { if v, ok := m[key]; ok { switch value := v.(type) { case string: @@ -178,7 +178,7 @@ func getString(m map[string]interface{}, key string) string { return "" } -func getInt(m map[string]interface{}, key string) int { +func getInt(m map[string]any, key string) int { candidateKeys := []string{key} switch key { case "track": @@ -210,7 +210,7 @@ func getInt(m map[string]interface{}, key string) int { return 0 } -func getPlaylistPosition(metadata map[string]interface{}) int { +func getPlaylistPosition(metadata map[string]any) int { return getInt(metadata, "playlist_position") } diff --git a/go_backend/filename_test.go b/go_backend/filename_test.go index 7e4149f8..2e2de26c 100644 --- a/go_backend/filename_test.go +++ b/go_backend/filename_test.go @@ -7,7 +7,7 @@ import ( ) func TestBuildFilenameFromTemplate_WithRawTrackAndDisc(t *testing.T) { - metadata := map[string]interface{}{ + metadata := map[string]any{ "title": "Song Name", "artist": "Artist Name", "album": "Album Name", @@ -28,7 +28,7 @@ func TestBuildFilenameFromTemplate_WithRawTrackAndDisc(t *testing.T) { } func TestBuildFilenameFromTemplate_RawPlaceholdersEmptyWhenZero(t *testing.T) { - metadata := map[string]interface{}{ + metadata := map[string]any{ "title": "Song Name", "artist": "Artist Name", "track": 0, @@ -43,7 +43,7 @@ func TestBuildFilenameFromTemplate_RawPlaceholdersEmptyWhenZero(t *testing.T) { } func TestBuildFilenameFromTemplate_InlineNumberFormatting(t *testing.T) { - metadata := map[string]interface{}{ + metadata := map[string]any{ "track": 3, "disc": 2, } @@ -56,7 +56,7 @@ func TestBuildFilenameFromTemplate_InlineNumberFormatting(t *testing.T) { } func TestBuildFilenameFromTemplate_PlaylistPositionFormatting(t *testing.T) { - metadata := map[string]interface{}{ + metadata := map[string]any{ "playlist_position": 4, "artist": "Artist Name", "title": "Song Name", @@ -73,7 +73,7 @@ func TestBuildFilenameFromTemplate_PlaylistPositionFormatting(t *testing.T) { } func TestBuildFilenameFromTemplate_DateStrftimeFormatting(t *testing.T) { - metadata := map[string]interface{}{ + metadata := map[string]any{ "artist": "Artist Name", "title": "Song Name", "release_date": "2024-03-09", @@ -92,7 +92,7 @@ func TestBuildFilenameFromTemplate_DateStrftimeFormatting(t *testing.T) { } func TestBuildFilenameFromTemplate_DateStrftimeFormattingWithYearOnly(t *testing.T) { - metadata := map[string]interface{}{ + metadata := map[string]any{ "artist": "Artist Name", "title": "Song Name", "date": "2019", diff --git a/go_backend/logbuffer.go b/go_backend/logbuffer.go index 517cddef..8279317e 100644 --- a/go_backend/logbuffer.go +++ b/go_backend/logbuffer.go @@ -129,23 +129,23 @@ func (lb *LogBuffer) Count() int { return len(lb.entries) } -func LogDebug(tag, format string, args ...interface{}) { +func LogDebug(tag, format string, args ...any) { GetLogBuffer().Add("DEBUG", tag, fmt.Sprintf(format, args...)) } -func LogInfo(tag, format string, args ...interface{}) { +func LogInfo(tag, format string, args ...any) { GetLogBuffer().Add("INFO", tag, fmt.Sprintf(format, args...)) } -func LogWarn(tag, format string, args ...interface{}) { +func LogWarn(tag, format string, args ...any) { GetLogBuffer().Add("WARN", tag, fmt.Sprintf(format, args...)) } -func LogError(tag, format string, args ...interface{}) { +func LogError(tag, format string, args ...any) { GetLogBuffer().Add("ERROR", tag, fmt.Sprintf(format, args...)) } -func GoLog(format string, args ...interface{}) { +func GoLog(format string, args ...any) { message := fmt.Sprintf(format, args...) message = strings.TrimSuffix(message, "\n") diff --git a/go_backend/lyrics.go b/go_backend/lyrics.go index 38c5c418..49008593 100644 --- a/go_backend/lyrics.go +++ b/go_backend/lyrics.go @@ -297,8 +297,8 @@ func GetLyricsProviderOrder() []string { return result } -func GetAvailableLyricsProviders() []map[string]interface{} { - return []map[string]interface{}{ +func GetAvailableLyricsProviders() []map[string]any { + return []map[string]any{ {"id": LyricsProviderLRCLIB, "name": "LRCLIB", "has_proxy_dependency": false, "description": "Open-source synced lyrics database"}, {"id": LyricsProviderNetease, "name": "Netease", "has_proxy_dependency": true, "description": "NetEase Cloud Music lyrics"}, {"id": LyricsProviderMusixmatch, "name": "Musixmatch", "has_proxy_dependency": true, "description": "Musixmatch lyrics"}, @@ -1162,7 +1162,7 @@ func detectLyricsErrorPayload(raw string) (string, bool) { return "", false } - var payload map[string]interface{} + var payload map[string]any if err := json.Unmarshal([]byte(trimmed), &payload); err != nil { return "", false } diff --git a/go_backend/metadata.go b/go_backend/metadata.go index 42e6345f..36162cee 100644 --- a/go_backend/metadata.go +++ b/go_backend/metadata.go @@ -1899,7 +1899,8 @@ func GetM4AQuality(filePath string) (AudioQuality, error) { bitDepth := 0 codec := normalizeM4AAudioCodec(atomType) - if atomType == "alac" { + switch atomType { + case "alac": bitDepth = int(buf[22])<<8 | int(buf[23]) if alacBitDepth, alacSampleRate, ok := readALACSpecificConfig(f, sampleOffset, fileSize); ok { if alacBitDepth > 0 { @@ -1909,7 +1910,7 @@ func GetM4AQuality(filePath string) (AudioQuality, error) { sampleRate = alacSampleRate } } - } else if atomType == "fLaC" { + case "fLaC": bitDepth = int(buf[22])<<8 | int(buf[23]) if flacBitDepth, flacSampleRate, flacTotalSamples, ok := readMP4FLACSpecificConfig(f, sampleOffset, fileSize); ok { if flacBitDepth > 0 { @@ -1976,7 +1977,7 @@ func readM4ADurationSeconds(f *os.File, moovHeader atomHeader, fileSize int64) i return readM4ATrackDurationSeconds(f, moovHeader, fileSize) } -func readMP4DurationAtomSeconds(f *os.File, header atomHeader, fileSize int64) int { +func readMP4DurationAtomSeconds(f *os.File, header atomHeader, _ int64) int { payloadOffset := header.offset + header.headerSize versionBuf := make([]byte, 1) if _, err := f.ReadAt(versionBuf, payloadOffset); err != nil { diff --git a/go_backend/metadata_types.go b/go_backend/metadata_types.go index 4404221c..91940b61 100644 --- a/go_backend/metadata_types.go +++ b/go_backend/metadata_types.go @@ -3,7 +3,7 @@ package gobackend import "time" type cacheEntry struct { - data interface{} + data any expiresAt time.Time } diff --git a/go_backend/misc_coverage_supplement_test.go b/go_backend/misc_coverage_supplement_test.go index 13000c6c..905aada2 100644 --- a/go_backend/misc_coverage_supplement_test.go +++ b/go_backend/misc_coverage_supplement_test.go @@ -92,14 +92,14 @@ func TestMoreSmallConstructorsRuntimeAndMetadataHelpers(t *testing.T) { ClearTrackCache() vm := goja.New() - runtime := &extensionRuntime{extensionID: "misc-runtime", vm: vm, settings: map[string]interface{}{}} + runtime := &extensionRuntime{extensionID: "misc-runtime", vm: vm, settings: map[string]any{}} if parseExtensionTimeoutSeconds(" 42 ") != 42 || parseExtensionTimeoutSeconds("bad") != 0 || parseExtensionTimeoutSeconds(float64(7)) != 7 { t.Fatal("parseExtensionTimeoutSeconds mismatch") } if (&RedirectBlockedError{Domain: "blocked.example"}).Error() == "" || (&RedirectBlockedError{IsPrivate: true}).Error() == "" { t.Fatal("RedirectBlockedError Error mismatch") } - runtime.SetSettings(map[string]interface{}{"quality": "lossless"}) + runtime.SetSettings(map[string]any{"quality": "lossless"}) if runtime.settings["quality"] != "lossless" { t.Fatal("SetSettings mismatch") } @@ -110,16 +110,16 @@ func TestMoreSmallConstructorsRuntimeAndMetadataHelpers(t *testing.T) { t.Fatalf("cookies = %#v", cookies) } - if result := runtime.ffmpegExecute(goja.FunctionCall{}).Export().(map[string]interface{}); result["success"] != false { + if result := runtime.ffmpegExecute(goja.FunctionCall{}).Export().(map[string]any); result["success"] != false { t.Fatalf("ffmpegExecute missing args = %#v", result) } - if result := runtime.ffmpegGetInfo(goja.FunctionCall{}).Export().(map[string]interface{}); result["success"] != false { + if result := runtime.ffmpegGetInfo(goja.FunctionCall{}).Export().(map[string]any); result["success"] != false { t.Fatalf("ffmpegGetInfo missing args = %#v", result) } - if result := runtime.ffmpegGetInfo(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("missing.flac")}}).Export().(map[string]interface{}); result["success"] != false { + if result := runtime.ffmpegGetInfo(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("missing.flac")}}).Export().(map[string]any); result["success"] != false { t.Fatalf("ffmpegGetInfo missing file = %#v", result) } - if result := runtime.ffmpegConvert(goja.FunctionCall{}).Export().(map[string]interface{}); result["success"] != false { + if result := runtime.ffmpegConvert(goja.FunctionCall{}).Export().(map[string]any); result["success"] != false { t.Fatalf("ffmpegConvert missing args = %#v", result) } @@ -221,7 +221,7 @@ func TestExtensionHealthInitializeVMAndCustomSearchWrappers(t *testing.T) { t.Fatal("expected initialized VM") } provider := &extensionProviderWrapper{extension: ext} - if tracks, err := provider.CustomSearch("needle", map[string]interface{}{"type": "track"}); err != nil || len(tracks) == 0 { + if tracks, err := provider.CustomSearch("needle", map[string]any{"type": "track"}); err != nil || len(tracks) == 0 { t.Fatalf("CustomSearch = %#v/%v", tracks, err) } cancelMu.Lock() @@ -263,7 +263,7 @@ func TestManifestPerfMatchingAndTitleHelpers(t *testing.T) { t.Fatal("extensionDurationMs mismatch") } vm := goja.New() - value := vm.ToValue(map[string]interface{}{"tracks": []interface{}{1, 2, 3}}) + value := vm.ToValue(map[string]any{"tracks": []any{1, 2, 3}}) if countExtensionTopLevelItems(vm, value) != 3 { t.Fatal("countExtensionTopLevelItems mismatch") } @@ -298,7 +298,7 @@ func TestManifestPerfMatchingAndTitleHelpers(t *testing.T) { t.Fatal("expected mismatching track") } - var decoded map[string]interface{} + var decoded map[string]any if err := json.Unmarshal(data, &decoded); err != nil || decoded["name"] != "misc-ext" { t.Fatalf("manifest JSON decode = %#v/%v", decoded, err) } diff --git a/go_backend/output_fd_windows.go b/go_backend/output_fd_windows.go index a0cedd95..9b1290c4 100644 --- a/go_backend/output_fd_windows.go +++ b/go_backend/output_fd_windows.go @@ -8,11 +8,11 @@ func dupOutputFD(fd int) (int, error) { return fd, nil } -func truncateFD(fd int) error { +func truncateFD(_ int) error { return nil } -func seekFDStart(fd int) error { +func seekFDStart(_ int) error { return nil } diff --git a/go_backend/progress.go b/go_backend/progress.go index f527f1aa..4abcd5b4 100644 --- a/go_backend/progress.go +++ b/go_backend/progress.go @@ -369,7 +369,7 @@ func ClearAllItemProgress() { markMultiProgressDirtyLocked() } -func setDownloadDir(path string) error { +func setDownloadDir(_ string) error { return nil } diff --git a/go_backend/wav_aiff.go b/go_backend/wav_aiff.go index 93715d2f..ef825a36 100644 --- a/go_backend/wav_aiff.go +++ b/go_backend/wav_aiff.go @@ -33,11 +33,10 @@ type WAVQuality struct { } const ( - wavMaxMetaChunk = 16 * 1024 * 1024 // safety cap for buffering a metadata chunk - id3ChunkWAV = "id3 " - id3ChunkAIFF = "ID3 " - wavFormatPCM = 0x0001 - wavFormatFloat = 0x0003 + wavMaxMetaChunk = 16 * 1024 * 1024 // safety cap for buffering a metadata chunk + id3ChunkWAV = "id3 " + id3ChunkAIFF = "ID3 " + // Other format tags for reference: 0x0001 PCM, 0x0003 IEEE float. wavFormatExtensn = 0xFFFE )