Update dependencies and refactor validation logic#426
Update dependencies and refactor validation logic#426
Conversation
- Updated `zod` from version 3.25.76 to 4.1.13 in `package.json`. - Updated `material-symbols` from version 0.39.1 to 0.40.0 in `package.json`. - Refactored validation logic in various routes to directly use `zod` schemas instead of `zodValidator` from `@tanstack/zod-adapter`. - Updated routes in `albums`, `artists`, `folders`, `genres`, `lyrics`, `playlists`, `queue`, and `search` to reflect the new validation approach.
…audio metadata handling
…tadata and update related imports - Renamed `sendSongId3Tags` to `sendSongMetadata` across multiple files for clarity. - Updated the function signature in `songs.ts` to reflect the new naming convention. - Removed the old `sendSongId3Tags` implementation and replaced it with the new `sendSongMetadata` logic. - Adjusted all relevant imports and usages to ensure consistency throughout the codebase.
- Introduced a new script `colorize-logs.ts` for colorizing and tailing NDJSON log files. - The script supports various features including log level filtering, file selection, and pretty-printing of log data. - Added a new npm command `logs` to execute the log viewer script with an optional environment log path.
- Implemented `testUtils.ts` to provide mock data and utility functions for testing song metadata, file stats, and database transactions. - Created comprehensive tests in `tryToParseSong.test.ts` to cover various scenarios including duplicate prevention, success cases, retry logic, renderer messages, and edge cases. - Mocked dependencies such as file system operations, database queries, and external libraries to isolate tests and ensure reliability. - Enhanced test coverage for song parsing logic, ensuring robust handling of different paths and error scenarios.
…nres, and artists; enhance song metadata update process
- Updated function signatures and variable types in various modules to use number for songId instead of string. - Adjusted related database queries and IPC handlers to accommodate the new type. - Modified local storage migration to convert songId from string to number. - Updated type definitions in app.d.ts to reflect changes in songId type. - Ensured consistency in handling songId throughout the application, including in event data and song-related operations.
Updated the README to enhance clarity and structure, including a new introduction and improved feature descriptions.
…and queries - Updated toggleSongIsFavorite to accept songId as a number. - Modified updateQueueOnSongPlay to handle songId as a number and adjusted queue structure accordingly. - Changed album, artist, genre, listen, playlist, and song queries to use number for songId and related identifiers. - Adjusted route parameters in main-player routes to convert string params to numbers for songId, albumId, artistId, genreId, and playlistId. - Updated local storage utility functions to handle number arrays instead of string arrays for ignored artists and songs. - Refined metadata management functions to ensure consistent handling of artist and genre data. - Adjusted types in app.d.ts to reflect changes in songId and related identifiers. - Fixed various instances in the UI where songId was treated as a string instead of a number.
…s to use enums - Changed import paths for conversion functions in multiple files to use '../utils/convert' instead of '../../common/convert'. - Updated playlist IDs in the filesystem and related components to use the SpecialPlaylists enum for better maintainability. - Adjusted types for song and album data structures to use numbers instead of strings where applicable. - Modified API calls to handle data responses correctly in various components. - Cleaned up unused parameters and improved code readability across several files.
…rseSong and related tests
… in recursive calls
- Implement tests for hasDataChanged to verify data comparison logic across various object structures, including basic and complex cases. - Introduce tests for isLatestVersion to validate version comparison, covering scenarios with different release phases and build metadata.
…nd library management
…type safety and state handling - Introduced type definitions for queue and store subscription states to improve type safety. - Refactored queue singleton initialization and synchronization logic for clarity and maintainability. - Updated store subscription logic to ensure proper state retrieval and local storage synchronization. - Improved logging for state changes during development.
…nd hydration logic
…for better stability and performance
…st database debug level for consistency
There was a problem hiding this comment.
Pull request overview
This PR modernizes the codebase by updating tooling/configuration, shifting many IDs from string to number across renderer + main, introducing DB-backed user-preferences storage (with migration + export), and refactoring some metadata/audio handling (including adoption of node-taglib-sharp and new file-handle utilities).
Changes:
- Refactored many song/artist/album/playlist/genre IDs from
string→numberand updated route param handling (stringifying where needed). - Added new user-preferences persistence (Drizzle migration + seed + queries) and included export/import support.
- Tooling/config updates: Oxfmt config, removal of Prettier/ESLint configs, and electron-vite config updates.
Reviewed changes
Copilot reviewed 294 out of 419 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/renderer/src/components/SongsPage/DeleteSongsFromSystemConfrimPrompt.tsx | Switch songIds prop type to number[]; import ordering |
| src/renderer/src/components/SongsPage/BlacklistSongConfirmPrompt.tsx | Switch songIds prop type to number[]; import ordering |
| src/renderer/src/components/SongsControlsContainer/UpNextSongPopup.tsx | Route param stringification; songId type number |
| src/renderer/src/components/SongsControlsContainer/SongControlsContainer.tsx | Import ordering |
| src/renderer/src/components/SongsControlsContainer/SongControlsAndSeekbarContainer.tsx | Formatting only |
| src/renderer/src/components/SongsControlsContainer/SeekBarContainer.tsx | Import ordering |
| src/renderer/src/components/SongsControlsContainer/OtherSongControlsContainer.tsx | Import ordering |
| src/renderer/src/components/SongsControlsContainer/CurrentlyPlayingSongInfoContainer.tsx | Route param stringification; album/songId types |
| src/renderer/src/components/SongUnplayableErrorPrompt.tsx | Import ordering |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongLyricsEditorInput.tsx | songId/artistId types; TODO stubbed navigation |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongGenresInput.tsx | genreId types; Tailwind class tweaks |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongArtistsInput.tsx | artistId types; Tailwind class tweaks |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongArtistInputResult.tsx | artistId type; import ordering |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongAlbumInputResult.tsx | Typed album data; Tailwind class tweak |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongAlbumInput.tsx | Typed album data arrays; Tailwind class tweak |
| src/renderer/src/components/SongTagsEditingPage/input_containers/SongAlbumArtistInput.tsx | albumId/artistId types |
| src/renderer/src/components/SongTagsEditingPage/SongMetadataResult.tsx | API response .data handling; migrate album→albums |
| src/renderer/src/components/SongTagsEditingPage/SongArtwork.tsx | Migrate album→albums (first item) when artwork changes |
| src/renderer/src/components/SongTagsEditingPage/ResetTagsToDefaultPrompt.tsx | Formatting only |
| src/renderer/src/components/SongTagsEditingPage/CustomizeSelectedMetadataPrompt.tsx | API response .data; migrate album→albums |
| src/renderer/src/components/SongInfoPage/UnAvailableTrack.tsx | Import ordering |
| src/renderer/src/components/SongInfoPage/SongsWithFeaturingArtistSuggestion.tsx | Move ignore handling to user preferences hook; songId type |
| src/renderer/src/components/SongInfoPage/SongAdditionalInfoContainer.tsx | Import ordering |
| src/renderer/src/components/SongInfoPage/SimilarTracksContainer.tsx | songId type; queue fields rename usage (songIds/position) |
| src/renderer/src/components/SongInfoPage/ListeningActivityBarGraph.tsx | Formatting only |
| src/renderer/src/components/Sidebar/Sidebar.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/SettingsPage.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/StorageSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/StartupSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/PreferencesSettings.tsx | Remove userData gating for preference checkbox |
| src/renderer/src/components/SettingsPage/Settings/PerformanceSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/LyricsSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/LanguageSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/DefaultPageSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AudioPlaybackSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AppearanceSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AppStats.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AdvancedSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AccountsSettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AccessibilitySettings.tsx | Import ordering |
| src/renderer/src/components/SettingsPage/Settings/AboutSettings.tsx | Use settingsQuery suspense instead of store for dark mode |
| src/renderer/src/components/SettingsPage/ResetAppConfirmationPrompt.tsx | Formatting only |
| src/renderer/src/components/SettingsPage/ClearLocalStoragePrompt.tsx | Formatting only |
| src/renderer/src/components/SettingsPage/BlacklistedSong.tsx | songId type number |
| src/renderer/src/components/SettingsPage/AppShortcutsPrompt.tsx | Import ordering |
| src/renderer/src/components/SensitiveActionConfirmPrompt.tsx | Import ordering |
| src/renderer/src/components/SeekBarSlider.tsx | Import ordering |
| src/renderer/src/components/SecondaryContainer.tsx | Formatting only |
| src/renderer/src/components/SearchPage/SearchStartPlaceholder.tsx | Import ordering |
| src/renderer/src/components/SearchPage/SearchResultsFilter.tsx | Formatting only |
| src/renderer/src/components/SearchPage/SearchOptions.tsx | Formatting only |
| src/renderer/src/components/SearchPage/Result_Containers/SongSearchResultsContainer.tsx | songId type number |
| src/renderer/src/components/SearchPage/Result_Containers/PlaylistSearchResultsContainer.tsx | Import ordering |
| src/renderer/src/components/SearchPage/Result_Containers/MostRelevantSearchResultsContainer.tsx | Queue field rename usage; route param stringification |
| src/renderer/src/components/SearchPage/Result_Containers/GenreSearchResultsContainer.tsx | Import ordering |
| src/renderer/src/components/SearchPage/Result_Containers/ArtistsSearchResultsContainer.tsx | Import ordering |
| src/renderer/src/components/SearchPage/Result_Containers/AlbumSearchResultsContainer.tsx | Import ordering |
| src/renderer/src/components/SearchPage/RecentSearchResult.tsx | Formatting only |
| src/renderer/src/components/SearchPage/NoSearchResultsContainer.tsx | Import ordering |
| src/renderer/src/components/SearchPage/MostRelevantResult.tsx | id type number; route param stringification |
| src/renderer/src/components/SearchPage/All_Search_Result_Containers/AllSongResults.tsx | songId type number |
| src/renderer/src/components/SearchPage/All_Search_Result_Containers/AllPlaylistResults.tsx | Import ordering |
| src/renderer/src/components/SearchPage/All_Search_Result_Containers/AllGenreResults.tsx | Import ordering |
| src/renderer/src/components/SearchPage/All_Search_Result_Containers/AllArtistResults.tsx | Import ordering |
| src/renderer/src/components/SearchPage/All_Search_Result_Containers/AllAlbumResults.tsx | Import ordering |
| src/renderer/src/components/ReleaseNotesPrompt/VersionNote.tsx | Formatting only |
| src/renderer/src/components/ReleaseNotesPrompt/Version.tsx | Import ordering |
| src/renderer/src/components/ReleaseNotesPrompt/ReleaseNotesPrompt.tsx | Import ordering |
| src/renderer/src/components/ReleaseNotesPrompt/ReleaseNotesAppUpdateInfo.tsx | Formatting only |
| src/renderer/src/components/PromptMenu/PromptMenuNavigationControlsContainer.tsx | Import ordering |
| src/renderer/src/components/PromptMenu/PromptMenu.tsx | Formatting + Tailwind class changes |
| src/renderer/src/components/Preloader/Preloader.tsx | Import ordering |
| src/renderer/src/components/PlaylistsPage/RenamePlaylistPrompt.tsx | Tailwind class changes |
| src/renderer/src/components/PlaylistsPage/PlaylistOptions.tsx | Import ordering |
| src/renderer/src/components/PlaylistsPage/NewPlaylistPrompt.tsx | Import ordering |
| src/renderer/src/components/PlaylistsPage/MultipleArtworksCover.tsx | songIds type number[]; query import ordering |
| src/renderer/src/components/PlaylistsPage/ConfirmDeletePlaylistsPrompt.tsx | playlistIds type number[]; SpecialPlaylists usage |
| src/renderer/src/components/PlaylistsInfoPage/PlaylistInfoAndImgContainer.tsx | Import ordering |
| src/renderer/src/components/OpenLinkConfirmPrompt.tsx | Import ordering |
| src/renderer/src/components/NotificationPanel/NotificationPanel.tsx | Import ordering |
| src/renderer/src/components/NotificationPanel/NotificationClearAllButton.tsx | Formatting only |
| src/renderer/src/components/NotificationPanel/Notification.tsx | Import ordering |
| src/renderer/src/components/NavLink.tsx | Doc comment formatting |
| src/renderer/src/components/MusicFoldersPage/folderOptions.tsx | Formatting only |
| src/renderer/src/components/MusicFoldersPage/SelectableFolder.tsx | Import ordering |
| src/renderer/src/components/MusicFoldersPage/RemoveFolderConfirmationPrompt.tsx | Formatting only |
| src/renderer/src/components/MusicFoldersPage/BlacklistFolderConfirmPrompt.tsx | Formatting only |
| src/renderer/src/components/MusicFoldersPage/AddMusicFoldersPrompt.tsx | Import ordering |
| src/renderer/src/components/MultipleSelectionCheckbox.tsx | id type number; stringified for Checkbox id |
| src/renderer/src/components/MiniPlayer/containers/TitleBarContainer.tsx | Import ordering |
| src/renderer/src/components/MiniPlayer/containers/LyricsContainer.tsx | Import ordering |
| src/renderer/src/components/MiniPlayer/MiniPlayer.tsx | Import ordering |
| src/renderer/src/components/MainContainer.tsx | Formatting only |
| src/renderer/src/components/LyricsPage/NoLyrics.tsx | Formatting only |
| src/renderer/src/components/LyricsPage/LyricsMetadata.tsx | Formatting only |
| src/renderer/src/components/LyricsPage/LyricLine.tsx | Formatting only |
| src/renderer/src/components/LyricsEditingPage/LyricsEditorSettingsPrompt.tsx | Import ordering |
| src/renderer/src/components/LyricsEditingPage/LyricsEditorSavePrompt.tsx | Import ordering |
| src/renderer/src/components/LyricsEditingPage/LyricsEditorHelpPrompt.tsx | Import ordering |
| src/renderer/src/components/LyricsEditingPage/LyricsEditingPageDurationCounter.tsx | Formatting only |
| src/renderer/src/components/LyricsEditingPage/EnhancedSyncedLyricWord.tsx | Formatting only |
| src/renderer/src/components/LyricsEditingPage/EditingLyricsLine.tsx | Import ordering |
| src/renderer/src/components/Img.tsx | Import ordering |
| src/renderer/src/components/Hyperlink.tsx | Import ordering |
| src/renderer/src/components/HomePage/RecentlyPlayedSongs.tsx | Import ordering |
| src/renderer/src/components/HomePage/RecentlyPlayedArtists.tsx | Import ordering |
| src/renderer/src/components/HomePage/RecentlyAddedSongs.tsx | Import ordering |
| src/renderer/src/components/HomePage/MostLovedSongs.tsx | Import ordering |
| src/renderer/src/components/HomePage/MostLovedArtists.tsx | Import ordering |
| src/renderer/src/components/GenresPage/genreOptions.tsx | Formatting only |
| src/renderer/src/components/GenreInfoPage/GenreImgAndInfoContainer.tsx | Import ordering |
| src/renderer/src/components/FullScreenPlayer/containers/SongInfoContainer.tsx | Import ordering |
| src/renderer/src/components/FullScreenPlayer/containers/LyricsContainer.tsx | Import ordering |
| src/renderer/src/components/FullScreenPlayer/FullScreenPlayer.tsx | Formatting + import ordering |
| src/renderer/src/components/ErrorPrompt.tsx | Import ordering |
| src/renderer/src/components/ErrorBoundary.tsx | Import ordering |
| src/renderer/src/components/ContextMenu/ContextMenuItem.tsx | Formatting only |
| src/renderer/src/components/ContextMenu/ContextMenu.tsx | Import ordering |
| src/renderer/src/components/Checkbox.tsx | Tailwind class tweaks |
| src/renderer/src/components/BodyAndSidebarContainer.tsx | Import ordering |
| src/renderer/src/components/Biography/HashTag.tsx | Formatting only |
| src/renderer/src/components/Biography/Biography.tsx | Import ordering |
| src/renderer/src/components/ArtistPage/ArtistOptions.tsx | Formatting only |
| src/renderer/src/components/ArtistPage/Artist.tsx | artistId/songIds types; route param stringification; queue field rename |
| src/renderer/src/components/ArtistInfoPage/SimilarArtistsContainer.tsx | Import ordering |
| src/renderer/src/components/ArtistInfoPage/SeparateArtistsSuggestion.tsx | Switch ignore handling to user preferences hook |
| src/renderer/src/components/AlbumsPage/AlbumOptions.tsx | Formatting only |
| src/renderer/src/components/AlbumsPage/Album.tsx | selectAllHandler type; route param stringification; queue field rename |
| src/renderer/src/components/AlbumInfoPage/OnlineAlbumInfoContainer.tsx | Import ordering |
| src/renderer/src/components/AlbumInfoPage/AlbumImgAndInfoContainer.tsx | Formatting only |
| src/renderer/src/assets/locales/en/en.json | Fix English strings |
| src/main/utils/withFileHandle.ts | New utility for safe node-taglib-sharp file disposal |
| src/main/utils/safeStorage.ts | Formatting only |
| src/main/utils/romanizeLyrics.ts | Import ordering |
| src/main/utils/parseSongMetadataFromMusixmatchApiData.ts | Import ordering |
| src/main/utils/makeDir.ts | Formatting only |
| src/main/utils/isPathADir.ts | Import ordering |
| src/main/utils/isBlacklisted.ts | songId type number |
| src/main/utils/getTranslatedLyrics.ts | Formatting only |
| src/main/utils/getRootSize.ts | Regex tweak + import ordering |
| src/main/utils/getFileSize.ts | Formatting only |
| src/main/utils/getDirSize.ts | Change catch to catch {}; import ordering |
| src/main/utils/filterSongs.ts | Use song.isBlacklisted instead of song.blacklist |
| src/main/utils/fetchSongMetadataFromInternet.ts | Import ordering |
| src/main/utils/fetchSongArtworksFromSpotify.ts | Import ordering |
| src/main/utils/fetchLyricsFromMusixmatch.ts | Import ordering |
| src/main/utils/dirExists.ts | Formatting only |
| src/main/utils/copyDir.ts | Import ordering |
| src/main/utils/convertToRomaja.ts | Import ordering |
| src/main/utils/convertToPinyin.ts | Import ordering |
| src/main/update.ts | Import ordering / formatting |
| src/main/search.ts | Convert import path switch to main utils/convert |
| src/main/saveLyricsToSong.ts | Import ordering |
| src/main/resetAppData.ts | Import ordering |
| src/main/removeSongsFromLibrary.ts | Convert import path; const flags |
| src/main/parseSong/manageAlbumsOfParsedSong.ts | Import ordering |
| src/main/parseSong/manageAlbumArtistOfParsedSong.ts | Import ordering |
| src/main/parseSong/generateCoverBuffer.ts | Modify API to accept a string path only |
| src/main/other/lastFm/sendNowPlayingSongDataToLastFM.ts | songId type number; convert import path |
| src/main/other/lastFm/sendFavoritesDataToLastFM.ts | Import ordering |
| src/main/other/lastFm/scrobbleSong.ts | songId type number; convert import path |
| src/main/other/lastFm/getSimilarTracks.ts | songId type number; convert import path |
| src/main/other/lastFm/getLastFMAuthData.ts | Import ordering |
| src/main/other/lastFm/getAlbumInfoFromLastFM.ts | albumId type number; id comparisons updated |
| src/main/other/lastFm/generateApiRequestBodyForLastFMPostRequests.ts | Import ordering |
| src/main/other/generatePalette.ts | Import ordering; updated generateCoverBuffer call |
| src/main/other/discordRPC.ts | Formatting only |
| src/main/other/discord.ts | Formatting only |
| src/main/other/artworks.ts | Import ordering; change catch to catch {}; doc formatting |
| src/main/migrations.ts | Formatting only |
| src/main/logger.ts | Formatting only |
| src/main/handleFileProtocol.ts | Import ordering; change catch to catch {} |
| src/main/fs/resolveFilePaths.ts | playlist/song id types; import ordering |
| src/main/fs/parseFolderStructuresForSongPaths.ts | Import ordering |
| src/main/fs/checkForFolderModifications.ts | Import ordering |
| src/main/fs/checkFolderForUnknownContentModifications.ts | Import ordering |
| src/main/fs/checkFolderForContentModifications.ts | Import ordering |
| src/main/fs/addWatchersToParentFolders.ts | Import ordering |
| src/main/fs/addWatchersToFolders.ts | Import ordering |
| src/main/filesystem.ts | SpecialPlaylists numeric IDs; playlistIds type number[] |
| src/main/db/seed.ts | Seed keyboard shortcuts + equalizer preset tables |
| src/main/db/queries/userPreferences.ts | New queries for keyboard shortcuts + equalizer preset |
| src/main/db/queries/songs.ts | Add updateSongBasicFields; rename metadata getter |
| src/main/db/queries/playlists.ts | Import ordering |
| src/main/db/queries/palettes.ts | Import ordering |
| src/main/db/queries/listens.ts | Formatting only |
| src/main/db/queries/history.ts | Import ordering |
| src/main/db/queries/genres.ts | Add helpers + delete function + docs |
| src/main/db/queries/folders.ts | songIds now numeric |
| src/main/db/queries/artworks.ts | Formatting only |
| src/main/db/queries/artists.ts | Add deleteArtist + docs; keep unlink docs |
| src/main/db/queries/albums.ts | Add deleteAlbum + docs; add getAlbumSongIds |
| src/main/db/db.ts | Reorder imports; lower PGlite debug; formatting |
| src/main/core/userPreferencesExportImport.ts | New export/import for DB-backed user preferences |
| src/main/core/updateSongListeningData.ts | songId type number |
| src/main/core/toggleLikeSongs.ts | songIds type number[]; remove Number conversions |
| src/main/core/toggleLikeArtists.ts | artistIds type number[]; remove Number conversions |
| src/main/core/toggleBlacklistFolders.ts | dataUpdateEvent payload removed |
| src/main/core/sendPlaylistData.ts | convert import path; signature tweak |
| src/main/core/sendAudioDataFromPath.ts | Switch to node-taglib-sharp; id/duration handling changes |
| src/main/core/sendAudioData.ts | songId type number; artist/album id types |
| src/main/core/saveLyricsToLrcFile.ts | Import ordering |
| src/main/core/saveArtworkToSystem.ts | Update import paths for updateSong/updateSongId3Tags |
| src/main/core/restoreBlacklistedSongs.ts | blacklistedSongIds type number[] |
| src/main/core/restoreBlacklistedFolder.ts | Import ordering |
| src/main/core/resolveSeparateArtists.ts | separateArtistId type number; updateSong import path |
| src/main/core/resolveFeaturingArtists.ts | songId type number; updateSong import path |
| src/main/core/resolveDuplicates.ts | selectedArtistId/duplicateIds types number[] |
| src/main/core/renameAPlaylist.ts | playlistId type number |
| src/main/core/removeSongFromPlaylist.ts | playlistId/songId types number |
| src/main/core/removePlaylists.ts | playlistIds type number[] |
| src/main/core/removeMusicFolder.ts | Import ordering |
| src/main/core/removeFromFavorites.ts | songId type number |
| src/main/core/manageTaskbarPlaybackButtonControls.ts | Import ordering |
| src/main/core/importPlaylist.ts | Import ordering |
| src/main/core/getStorageUsage.ts | Import ordering |
| src/main/core/getSongLyrics.ts | Import ordering; change catch to catch {} |
| src/main/core/getSongInfo.ts | songIds type number[]; convert import path |
| src/main/core/getMusicFolderData.ts | Import ordering |
| src/main/core/getListeningData.ts | songIds type number[] |
| src/main/core/getGenresInfo.ts | convert import path |
| src/main/core/getFolderStructures.ts | Import ordering |
| src/main/core/getDuplicates.ts | Import ordering |
| src/main/core/getArtworksForMultipleArtworksCover.ts | songIds type number[] |
| src/main/core/getArtistInfoFromNet.ts | artistId type number; convert import path |
| src/main/core/getAllSongs.ts | convert import path |
| src/main/core/getAllHistorySongs.ts | convert import path |
| src/main/core/getAllFavoriteSongs.ts | convert import path |
| src/main/core/fetchSongInfoFromLastFM.ts | Import ordering |
| src/main/core/fetchArtistData.ts | convert import path |
| src/main/core/fetchAlbumData.ts | convert import path |
| src/main/core/exportPlaylist.ts | playlistId type number |
| src/main/core/exportAppData.ts | Include user_preferences.json export |
| src/main/core/deleteSongsFromSystem.ts | Import ordering |
| src/main/core/convertParsedLyricsToNodeID3Format.ts | Formatting only |
| src/main/core/clearSongHistory.ts | Formatting only |
| src/main/core/clearSeachHistoryResults.ts | Formatting only |
| src/main/core/checkForStartUpSongs.ts | Import ordering |
| src/main/core/checkForNewSongs.ts | Import ordering |
| src/main/core/changeAppTheme.ts | dataUpdateEvent payload removed |
| src/main/core/blacklistSongs.ts | songIds type number[] |
| src/main/core/blacklistFolders.ts | Import ordering |
| src/main/core/addSongsToPlaylist.ts | playlistId/songIds types number; remove Number conversions |
| src/main/core/addNewPlaylist.ts | Update import paths; convert import path |
| src/main/core/addMusicFolder.ts | Import ordering |
| src/main/core/addArtworkToAPlaylist.ts | playlistId type number |
| src/main/auth/manageLastFmAuth.ts | Import ordering |
| src/common/playlists.enum.ts | New SpecialPlaylists constants + helper |
| src/common/parseLyrics.ts | Regex tweak + catch to catch {} |
| src/common/isLyricsSynced.ts | Regex tweak for extended synced lyrics |
| skills-lock.json | New skills lockfile |
| scripts/dropDatabase.ts | Import ordering |
| resources/drizzle/meta/_journal.json | Add migration journal entry |
| resources/drizzle/0001_add_user_preferences.sql | New schema for user preferences tables |
| prettier.config.cjs | Removed Prettier config |
| flatpak/app.netlify.noramusic.Nora.json | Formatting only |
| eslint.config.mjs | Removed ESLint flat config |
| electron.vite.config.ts | Remove externalizeDepsPlugin; update TanStack Router plugin paths |
| .vscode/launch.json | JSON formatting fix |
| .prettierignore | Removed (replaced by .oxfmtrc ignorePatterns) |
| .oxfmtrc.json | New Oxfmt config (format, import sort, ignore patterns) |
| .env.example | Add env var template for local development |
| const ignoreSuggestion = useCallback(() => { | ||
| storage.ignoredSongsWithFeatArtists.setIgnoredSongsWithFeatArtists([songId]); | ||
| if (!songId) return; | ||
| addIgnoredFeaturingArtistMutation.mutate({ songIds: [songId] }); | ||
|
|
||
| setIsIgnored(true); |
There was a problem hiding this comment.
ignoredFeaturingArtists (as implied by the hook name and the DB migration/table naming) appears to store artist IDs, but this UI is passing songIds. This will either fail at runtime (type mismatch) or silently persist incorrect data. Consider either (mandatory) changing the mutation payload to persist an artist ID (and rename any UI variables that call these "ignoredSongs"), or (alternative) introduce a separate preference/table specifically for “ignored songs with featuring-artist suggestions” and wire this component to that store.
| ignoredArtists: ignored.map((item) => item.artistId), | ||
| ignoredFeaturingArtists: ignoredFeating.map((item) => item.artistId), | ||
| ignoredDuplicateMetadata: ignoredDuplicate.map((item) => ({ |
There was a problem hiding this comment.
The export/import model treats ignoredFeaturingArtists as an array of artistIds, but the renderer uses that preference list as “ignored songs” (see SongsWithFeaturingArtistsSuggestion). The preference semantics need to be made consistent (mandatory): either rename and use it as artist IDs everywhere, or create a separate persisted preference keyed by song ID and export/import that instead.
| const file = File.createFromPath(songPath); | ||
| const metadata = file.tag; | ||
| if (metadata) { | ||
| const artworkData = metadata.common?.picture?.at(0)?.data; | ||
| const artworkData = metadata.pictures?.at(0)?.data?.toByteArray(); |
There was a problem hiding this comment.
File.createFromPath() allocates a native handle in node-taglib-sharp, but the handle is never disposed here (risking leaked file handles / memory, especially when scanning or previewing many files). Additionally, generating songId with Math.random() can collide with real DB IDs or other temp IDs, leading to incorrect lookups and UI behavior. Use the new withFileHandle() wrapper (or an explicit try/finally calling file.dispose()) and generate a collision-resistant temp ID (e.g., a negative range based on -Date.now() or a UUID mapped to a safe numeric namespace if you must keep number).
| artworkPath: tempArtworkPath, | ||
| path: path.join(DEFAULT_FILE_URL, songPath), | ||
| songId: generateRandomId(), | ||
| songId: Math.floor(Math.random() * 1000000), |
There was a problem hiding this comment.
File.createFromPath() allocates a native handle in node-taglib-sharp, but the handle is never disposed here (risking leaked file handles / memory, especially when scanning or previewing many files). Additionally, generating songId with Math.random() can collide with real DB IDs or other temp IDs, leading to incorrect lookups and UI behavior. Use the new withFileHandle() wrapper (or an explicit try/finally calling file.dispose()) and generate a collision-resistant temp ID (e.g., a negative range based on -Date.now() or a UUID mapped to a safe numeric namespace if you must keep number).
| <DialogPanel | ||
| ref={promptMenuRef} | ||
| transition | ||
| className="bg-background-color-1 dark:bg-dark-background-color-1 relative h-fit max-h-[80%] min-h-75 w-[80%] max-w-[90%] min-w-[800px] transform overflow-hidden overflow-y-auto rounded-2xl text-left shadow-xl transition-all data-closed:scale-95 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in sm:my-8 sm:w-full sm:max-w-lg"> |
There was a problem hiding this comment.
min-h-75 is not part of Tailwind’s default spacing scale (unless this project has custom spacing values configured). If it’s not configured, this class will be dropped and the dialog may become too short/tall unexpectedly. Prefer bracket notation for non-standard values (e.g., min-h-[300px]) or ensure the spacing scale explicitly includes 75.
| className="bg-background-color-1 dark:bg-dark-background-color-1 relative h-fit max-h-[80%] min-h-75 w-[80%] max-w-[90%] min-w-[800px] transform overflow-hidden overflow-y-auto rounded-2xl text-left shadow-xl transition-all data-closed:scale-95 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in sm:my-8 sm:w-full sm:max-w-lg"> | |
| className="bg-background-color-1 dark:bg-dark-background-color-1 relative h-fit max-h-[80%] min-h-[300px] w-[80%] max-w-[90%] min-w-[800px] transform overflow-hidden overflow-y-auto rounded-2xl text-left shadow-xl transition-all data-closed:scale-95 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in sm:my-8 sm:w-full sm:max-w-lg"> |
| type="text" | ||
| name="playlistName" | ||
| className="playlist-name-input bg-background-color-2! text-font-color-black dark:bg-dark-background-color-2! dark:text-font-color-white w-fit max-w-[75%] min-w-[400px] rounded-2xl border-[transparent] px-6 py-3 text-lg outline-hidden" | ||
| className="playlist-name-input bg-background-color-2! text-font-color-black dark:bg-dark-background-color-2! dark:text-font-color-white w-fit max-w-[75%] min-w-100 rounded-2xl border-transparent px-6 py-3 text-lg outline-hidden" |
There was a problem hiding this comment.
min-w-100 is also not part of Tailwind’s default spacing scale (unless customized). If not configured, this will be ignored and layout may regress. Prefer min-w-[400px] (as before) or another known Tailwind token (e.g., min-w-96) / project-defined spacing token.
| className="playlist-name-input bg-background-color-2! text-font-color-black dark:bg-dark-background-color-2! dark:text-font-color-white w-fit max-w-[75%] min-w-100 rounded-2xl border-transparent px-6 py-3 text-lg outline-hidden" | |
| className="playlist-name-input bg-background-color-2! text-font-color-black dark:bg-dark-background-color-2! dark:text-font-color-white w-fit max-w-[75%] min-w-[400px] rounded-2xl border-transparent px-6 py-3 text-lg outline-hidden" |
| year: data.year || null, | ||
| trackNumber: data.trackNumber || null |
There was a problem hiding this comment.
Using || null will coerce valid falsy values to null (e.g., year: 0 becomes null). For numeric fields, prefer nullish coalescing (?? null) so that only undefined/null become null. This is particularly important if 0 is a meaningful value in any of these fields now or in future migrations.
| year: data.year || null, | |
| trackNumber: data.trackNumber || null | |
| year: data.year ?? null, | |
| trackNumber: data.trackNumber ?? null |
| } | ||
| } catch (error) { | ||
| } catch { | ||
| logger.error('Failed to calculate dir size of a directory.'); | ||
| } |
There was a problem hiding this comment.
catch {} drops the underlying error details, which makes diagnosing filesystem issues (permissions, broken symlinks, transient IO failures) much harder in production logs. Consider capturing the error and logging it (e.g., include { error, filepath }), while still returning 0 to keep behavior stable.
| import storage from '../../utils/localStorage'; | ||
|
|
||
| const BlacklistSongConfrimPrompt = (props: { songIds: string[]; title?: string }) => { | ||
| const BlacklistSongConfrimPrompt = (props: { songIds: number[]; title?: string }) => { |
There was a problem hiding this comment.
Confrim appears to be a typo in the component name (and there are similar occurrences elsewhere). Since this component is being edited anyway, consider renaming to BlacklistSongConfirmPrompt for clarity and to reduce future import/name churn.
…tCard component - Updated FavoritesPlaylistInfoPage to include an importSongsToFavorites feature, allowing users to import songs directly into the favorites playlist. - Improved the layout and functionality of the favorites playlist, including better handling of song actions and notifications. - Introduced a new SpecialPlaylistCard component for displaying special playlists with context menu options for exporting playlists.
This pull request introduces two new migration guides for modern JavaScript/TypeScript projects and adds an example environment variable file. The guides provide step-by-step instructions for migrating from ESLint to Oxlint and from Prettier/Biome to Oxfmt, including manual steps, option mappings, and troubleshooting tips. Additionally, a template
.env.examplefile is included to help developers configure environment variables for local development. Minor formatting improvements are also made to the main process documentation.New Migration Documentation:
.agents/skills/migrate-oxlint/SKILL.md, a comprehensive guide for migrating a project from ESLint to Oxlint, covering automated migration, plugin and rule mapping, handling unsupported features, CI/script updates, and best practices..agents/skills/migrate-oxfmt/SKILL.md, a detailed guide for migrating from Prettier or Biome to Oxfmt, including option mapping, config review, handling unsupported features, and updating CI/scripts.Development Environment Setup:
.env.examplefile providing a template for required environment variables, including Musixmatch, Last.fm, Genius, Sentry, Discord, database, and log path configuration.Documentation Improvements:
.github/copilot-instructions.mdfor the main process description, window management, system integration, database structure, and code patterns. [1] [2] [3] [4] [5] [6] [7] [8] [9]This pull request introduces a variety of improvements and updates across the codebase, focusing on dependency upgrades, environment configuration, playlist management, and documentation. The most significant changes are grouped below by theme.Dependency and Build System Updates:
package.json, includingdrizzle-orm,electron-vite,material-symbols, andzod, and added new dependencies such asnode-taglib-sharpandyoctocolors. [1] [2] [3] [4] [5]electron.vite.config.tsto remove the use ofexternalizeDepsPluginand ensure compatibility with the newelectron-viteversion. [1] [2]Environment and Configuration:
.env.examplefile with placeholders for all required environment variables, improving developer onboarding and configuration clarity.Playlist Management Improvements:
numbertypes forplaylistIdandsongIdsinstead ofstring, enhancing type safety and reliability in functions likeaddSongsToPlaylist,addArtworkToAPlaylist, andblacklistSongs. [1] [2] [3] [4]SpecialPlaylistsenum insrc/common/playlists.enum.tsto better handle special playlist IDs such as History and Favorites.Documentation and Developer Experience:
README.mdfor improved clarity, structure, and user engagement, including new feature lists, gallery, feedback/contribution sections, and clearer build instructions. [1] [2]logsscript inpackage.jsonfor easier log colorization and access.Path and Import Fixes:
These changes collectively improve the robustness, maintainability, and usability of the project.Upgrade
zodandmaterial-symbolsdependencies. Refactor validation logic to directly utilizezodschemas across various routes, removing reliance onzod-adapter. This change streamlines validation processes and enhances code maintainability.