gerdur 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.11.0 - 2026-08-31
4
+
5
+ ### Fixed
6
+
7
+ - **`--enrich`** now picks the right release. It was calling the Cover Art
8
+ Archive on a recording's *first* MusicBrainz release, which for many tracks is
9
+ a promo comp / bootleg with no art — so it silently fell back to Deezer's
10
+ cover. `gerdur-core@2.13.0`'s `getCoverArtByISRC` walks the release-groups
11
+ canonical-first (Official → Album → earliest) and returns the first real
12
+ cover (verified: 216 KB CAA cover vs Deezer's ~35 KB).
13
+
14
+ ### Added
15
+
16
+ - Re-export `getCoverArtByISRC` / `getRecordingCoverArt`.
17
+
18
+ ## 2.10.0 - 2026-08-31
19
+
20
+ ### Added
21
+
22
+ - **`gerdur-core@^2.12.0`** — re-exports the optional read-only enrichment layer:
23
+ `lookupRecordingByISRC`, `getMusicBrainzRecording` / `getMusicBrainzRelease`,
24
+ `getCoverArt` / `getBestCoverArtUrl`, `configureMusicBrainz`, `PoliteJsonClient`.
25
+ - **`--enrich`** — during a download, look the track's ISRC up on MusicBrainz and
26
+ embed a higher-resolution front cover from the Cover Art Archive instead of
27
+ Deezer's (which caps at 1800 px). Falls back silently to Deezer's cover when
28
+ there's no match or the services are unavailable.
29
+
3
30
  ## 2.9.0 - 2026-08-31
4
31
 
5
32
  ### Added
package/README.md CHANGED
@@ -143,6 +143,7 @@ All options are optional. You can suppress prompts via providing `quality` and `
143
143
  | `--dur-min` / `--dur-max` | *None* | number (seconds) | Search filter — track duration range |
144
144
  | `--search-limit` | *None* | number (default 50) | How many search results to fetch |
145
145
  | `--preview` | *None* | *Nothing* | Download the 30-second preview clips (`.preview.mp3`) instead of full tracks — no `--quality` needed |
146
+ | `--enrich` | *None* | *Nothing* | Embed a higher-res front cover from the Cover Art Archive (looked up by ISRC via MusicBrainz); falls back to Deezer's cover |
146
147
 
147
148
  ## Search
148
149
 
@@ -217,6 +218,21 @@ gerdur --preview -u https://deezer.com/album/302127 # 14 clips
217
218
  gerdur -d --preview --artist "Justice" --search-limit 10 # audition a search
218
219
  ```
219
220
 
221
+ ## Better cover art (`--enrich`)
222
+
223
+ `--enrich` looks each track's ISRC up on MusicBrainz, finds its release-group,
224
+ and embeds the front cover from the [Cover Art Archive](https://coverartarchive.org)
225
+ instead of Deezer's (which is capped at 1800 px). No match, or the services are
226
+ down? It silently keeps Deezer's cover.
227
+
228
+ ```bash
229
+ gerdur --enrich -q flac -u https://deezer.com/album/302127
230
+ ```
231
+
232
+ The enrichment functions (`lookupRecordingByISRC`, `getBestCoverArtUrl`, …) are
233
+ also re-exported for programmatic use. Read-only, off by default, and
234
+ `gerdur-core` never wires them into tagging on its own.
235
+
220
236
  ## Programmatic API
221
237
 
222
238
  When installed as a dependency, `gerdur` exposes a side-effect-free API
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur",
3
- "version": "2.9.0",
3
+ "version": "2.11.0",
4
4
  "description": "The crucial streaming module for dabox systems.",
5
5
  "author": "Christian",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -48,7 +48,7 @@
48
48
  "adm-zip": "^0.5.16",
49
49
  "chalk": "^4.1.2",
50
50
  "commander": "^9.5.0",
51
- "gerdur-core": "^2.11.0",
51
+ "gerdur-core": "^2.13.0",
52
52
  "dot-prop": "^6.0.1",
53
53
  "got": "^11.8.6",
54
54
  "gradient-string": "^2.0.2",
@@ -59,7 +59,8 @@ const cmd = new commander_1.Command()
59
59
  .option('--dur-min <seconds>', 'Search filter: minimum duration')
60
60
  .option('--dur-max <seconds>', 'Search filter: maximum duration')
61
61
  .option('--search-limit <n>', 'Max search results to fetch', '50')
62
- .option('--preview', 'Download the 30-second preview clips instead of full tracks', false);
62
+ .option('--preview', 'Download the 30-second preview clips instead of full tracks', false)
63
+ .option('--enrich', 'Embed a higher-res cover from the Cover Art Archive (looked up by ISRC)', false);
63
64
  if (process.pkg) {
64
65
  cmd.option('-U, --update', 'Update this program to latest version');
65
66
  }
@@ -484,6 +485,7 @@ const startDownload = async (saveLayout, url, skipPrompt) => {
484
485
  overwrite,
485
486
  message: `(${index}/${data.tracks.length})`,
486
487
  lrc,
488
+ enrich: Boolean(options.enrich),
487
489
  prefetched: prefetchedUrls.get(track.SNG_ID) ?? null,
488
490
  });
489
491
  // Add to saved list
@@ -58,6 +58,8 @@ export { createSession, Session } from './lib/session';
58
58
  export type { SessionOptions, DownloadTracksOptions, SearchType } from './lib/session';
59
59
  export { createSession as createCoreSession, Session as CoreSession, defaultSession } from 'gerdur-core';
60
60
  export type { SessionUserData, SearchFacets } from 'gerdur-core';
61
+ export { configureMusicBrainz, lookupRecordingByISRC, getMusicBrainzRecording, getMusicBrainzRelease, getCoverArt, getBestCoverArtUrl, getRecordingCoverArt, getCoverArtByISRC, PoliteJsonClient, } from 'gerdur-core';
62
+ export type { MBRecording, MBRelease, MBArtistCredit, CoverArt, CoverArtImage } from 'gerdur-core';
61
63
  export { getTrackBuffer, getTaggedTrack, downloadTrackToFile } from './lib/api-download';
62
64
  export type { Quality, GetTrackBufferOptions, DownloadTrackOptions, DownloadResult } from './lib/api-download';
63
65
  export { default as Config, globalConfigPath, resolveConfigFile } from './lib/config';
package/dist/src/index.js CHANGED
@@ -33,8 +33,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
33
  return (mod && mod.__esModule) ? mod : { "default": mod };
34
34
  };
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.getShowEpisodes = exports.getEpisode = exports.getRadioGenres = exports.getRadioTracks = exports.getRadios = exports.getUserChartTracks = exports.getUserRadios = exports.getUserPlaylists = exports.getUserFavoriteArtists = exports.getUserFavoriteAlbums = exports.getUserFavoriteTracks = exports.getUserFlow = exports.getArtistRadioTracks = exports.getArtistPlaylists = exports.getArtistAlbums = exports.getRelatedArtists = exports.getArtistTopTracks = exports.getEditorialCharts = exports.getEditorialSelection = exports.getEditorialReleases = exports.getEditorialList = exports.getGenreArtists = exports.getChartTracks = exports.getChart = exports.getGenres = exports.suggest = exports.buildAdvancedQuery = exports.searchPlaylists = exports.searchArtists = exports.searchAlbums = exports.searchTracks = exports.searchPublicApi = exports.searchFacets = exports.searchMusic = exports.parseInfo = exports.initDeezerApi = exports.resolveConfigFile = exports.globalConfigPath = exports.Config = exports.downloadTrackToFile = exports.getTaggedTrack = exports.getTrackBuffer = exports.defaultSession = exports.CoreSession = exports.createCoreSession = exports.Session = exports.createSession = exports.getArl = exports.LoginError = exports.loginWithEmail = void 0;
37
- exports.DeezerError = exports.GeoBlocked = exports.toLrc = exports.normalizeContributors = exports.getRichAlbum = exports.addTrackTags = exports.getStream = exports.createDecryptStream = exports.downloadTrackBuffer = exports.streamTrackDownload = exports.resolveDownloadUrls = exports.getTrackDownloadUrl = exports.getLyrics = exports.getDiscography = exports.getArtistInfo = exports.getPlaylistTracks = exports.getPlaylistInfo = exports.getAlbumTracks = exports.getAlbumInfo = exports.getTrackInfo = exports.getUser = exports.DEEZER_FORMATS = exports.toFormat = exports.formatName = exports.downloadPreview = exports.getTrackPreview = exports.getAlbumByUPC = exports.getTrackByISRC = exports.refreshTrackTokens = void 0;
36
+ exports.getUserFavoriteAlbums = exports.getUserFavoriteTracks = exports.getUserFlow = exports.getArtistRadioTracks = exports.getArtistPlaylists = exports.getArtistAlbums = exports.getRelatedArtists = exports.getArtistTopTracks = exports.getEditorialCharts = exports.getEditorialSelection = exports.getEditorialReleases = exports.getEditorialList = exports.getGenreArtists = exports.getChartTracks = exports.getChart = exports.getGenres = exports.suggest = exports.buildAdvancedQuery = exports.searchPlaylists = exports.searchArtists = exports.searchAlbums = exports.searchTracks = exports.searchPublicApi = exports.searchFacets = exports.searchMusic = exports.parseInfo = exports.initDeezerApi = exports.resolveConfigFile = exports.globalConfigPath = exports.Config = exports.downloadTrackToFile = exports.getTaggedTrack = exports.getTrackBuffer = exports.PoliteJsonClient = exports.getCoverArtByISRC = exports.getRecordingCoverArt = exports.getBestCoverArtUrl = exports.getCoverArt = exports.getMusicBrainzRelease = exports.getMusicBrainzRecording = exports.lookupRecordingByISRC = exports.configureMusicBrainz = exports.defaultSession = exports.CoreSession = exports.createCoreSession = exports.Session = exports.createSession = exports.getArl = exports.LoginError = exports.loginWithEmail = void 0;
37
+ exports.DeezerError = exports.GeoBlocked = exports.toLrc = exports.normalizeContributors = exports.getRichAlbum = exports.addTrackTags = exports.getStream = exports.createDecryptStream = exports.downloadTrackBuffer = exports.streamTrackDownload = exports.resolveDownloadUrls = exports.getTrackDownloadUrl = exports.getLyrics = exports.getDiscography = exports.getArtistInfo = exports.getPlaylistTracks = exports.getPlaylistInfo = exports.getAlbumTracks = exports.getAlbumInfo = exports.getTrackInfo = exports.getUser = exports.DEEZER_FORMATS = exports.toFormat = exports.formatName = exports.downloadPreview = exports.getTrackPreview = exports.getAlbumByUPC = exports.getTrackByISRC = exports.refreshTrackTokens = exports.getShowEpisodes = exports.getEpisode = exports.getRadioGenres = exports.getRadioTracks = exports.getRadios = exports.getUserChartTracks = exports.getUserRadios = exports.getUserPlaylists = exports.getUserFavoriteArtists = void 0;
38
38
  // ─── Authentication ────────────────────────────────────────────────────────
39
39
  const email_login_1 = require("./lib/email-login");
40
40
  Object.defineProperty(exports, "loginWithEmail", { enumerable: true, get: function () { return email_login_1.loginWithEmail; } });
@@ -79,6 +79,18 @@ var gerdur_core_1 = require("gerdur-core");
79
79
  Object.defineProperty(exports, "createCoreSession", { enumerable: true, get: function () { return gerdur_core_1.createSession; } });
80
80
  Object.defineProperty(exports, "CoreSession", { enumerable: true, get: function () { return gerdur_core_1.Session; } });
81
81
  Object.defineProperty(exports, "defaultSession", { enumerable: true, get: function () { return gerdur_core_1.defaultSession; } });
82
+ // Optional, read-only enrichment against open databases (MusicBrainz, Cover Art
83
+ // Archive). Off by default; `--enrich` on the CLI uses it for hi-res covers.
84
+ var gerdur_core_2 = require("gerdur-core");
85
+ Object.defineProperty(exports, "configureMusicBrainz", { enumerable: true, get: function () { return gerdur_core_2.configureMusicBrainz; } });
86
+ Object.defineProperty(exports, "lookupRecordingByISRC", { enumerable: true, get: function () { return gerdur_core_2.lookupRecordingByISRC; } });
87
+ Object.defineProperty(exports, "getMusicBrainzRecording", { enumerable: true, get: function () { return gerdur_core_2.getMusicBrainzRecording; } });
88
+ Object.defineProperty(exports, "getMusicBrainzRelease", { enumerable: true, get: function () { return gerdur_core_2.getMusicBrainzRelease; } });
89
+ Object.defineProperty(exports, "getCoverArt", { enumerable: true, get: function () { return gerdur_core_2.getCoverArt; } });
90
+ Object.defineProperty(exports, "getBestCoverArtUrl", { enumerable: true, get: function () { return gerdur_core_2.getBestCoverArtUrl; } });
91
+ Object.defineProperty(exports, "getRecordingCoverArt", { enumerable: true, get: function () { return gerdur_core_2.getRecordingCoverArt; } });
92
+ Object.defineProperty(exports, "getCoverArtByISRC", { enumerable: true, get: function () { return gerdur_core_2.getCoverArtByISRC; } });
93
+ Object.defineProperty(exports, "PoliteJsonClient", { enumerable: true, get: function () { return gerdur_core_2.PoliteJsonClient; } });
82
94
  // ─── Download primitives ─────────────────────────────────────────────────────
83
95
  var api_download_1 = require("./lib/api-download");
84
96
  Object.defineProperty(exports, "getTrackBuffer", { enumerable: true, get: function () { return api_download_1.getTrackBuffer; } });
@@ -93,69 +105,69 @@ Object.defineProperty(exports, "resolveConfigFile", { enumerable: true, get: fun
93
105
  // ─── Re-exported core query functions ────────────────────────────────────────
94
106
  // Convenience re-exports so consumers don't need `gerdur-core` directly.
95
107
  // After `initDeezerApi(arl)` (or `createSession`) these are ready to use.
96
- var gerdur_core_2 = require("gerdur-core");
97
- Object.defineProperty(exports, "initDeezerApi", { enumerable: true, get: function () { return gerdur_core_2.initDeezerApi; } });
98
- Object.defineProperty(exports, "parseInfo", { enumerable: true, get: function () { return gerdur_core_2.parseInfo; } });
99
- Object.defineProperty(exports, "searchMusic", { enumerable: true, get: function () { return gerdur_core_2.searchMusic; } });
100
- Object.defineProperty(exports, "searchFacets", { enumerable: true, get: function () { return gerdur_core_2.searchFacets; } });
101
- Object.defineProperty(exports, "searchPublicApi", { enumerable: true, get: function () { return gerdur_core_2.searchPublicApi; } });
102
- Object.defineProperty(exports, "searchTracks", { enumerable: true, get: function () { return gerdur_core_2.searchTracks; } });
103
- Object.defineProperty(exports, "searchAlbums", { enumerable: true, get: function () { return gerdur_core_2.searchAlbums; } });
104
- Object.defineProperty(exports, "searchArtists", { enumerable: true, get: function () { return gerdur_core_2.searchArtists; } });
105
- Object.defineProperty(exports, "searchPlaylists", { enumerable: true, get: function () { return gerdur_core_2.searchPlaylists; } });
106
- Object.defineProperty(exports, "buildAdvancedQuery", { enumerable: true, get: function () { return gerdur_core_2.buildAdvancedQuery; } });
107
- Object.defineProperty(exports, "suggest", { enumerable: true, get: function () { return gerdur_core_2.suggest; } });
108
- Object.defineProperty(exports, "getGenres", { enumerable: true, get: function () { return gerdur_core_2.getGenres; } });
109
- Object.defineProperty(exports, "getChart", { enumerable: true, get: function () { return gerdur_core_2.getChart; } });
110
- Object.defineProperty(exports, "getChartTracks", { enumerable: true, get: function () { return gerdur_core_2.getChartTracks; } });
111
- Object.defineProperty(exports, "getGenreArtists", { enumerable: true, get: function () { return gerdur_core_2.getGenreArtists; } });
112
- Object.defineProperty(exports, "getEditorialList", { enumerable: true, get: function () { return gerdur_core_2.getEditorialList; } });
113
- Object.defineProperty(exports, "getEditorialReleases", { enumerable: true, get: function () { return gerdur_core_2.getEditorialReleases; } });
114
- Object.defineProperty(exports, "getEditorialSelection", { enumerable: true, get: function () { return gerdur_core_2.getEditorialSelection; } });
115
- Object.defineProperty(exports, "getEditorialCharts", { enumerable: true, get: function () { return gerdur_core_2.getEditorialCharts; } });
116
- Object.defineProperty(exports, "getArtistTopTracks", { enumerable: true, get: function () { return gerdur_core_2.getArtistTopTracks; } });
117
- Object.defineProperty(exports, "getRelatedArtists", { enumerable: true, get: function () { return gerdur_core_2.getRelatedArtists; } });
118
- Object.defineProperty(exports, "getArtistAlbums", { enumerable: true, get: function () { return gerdur_core_2.getArtistAlbums; } });
119
- Object.defineProperty(exports, "getArtistPlaylists", { enumerable: true, get: function () { return gerdur_core_2.getArtistPlaylists; } });
120
- Object.defineProperty(exports, "getArtistRadioTracks", { enumerable: true, get: function () { return gerdur_core_2.getArtistRadioTracks; } });
121
- Object.defineProperty(exports, "getUserFlow", { enumerable: true, get: function () { return gerdur_core_2.getUserFlow; } });
122
- Object.defineProperty(exports, "getUserFavoriteTracks", { enumerable: true, get: function () { return gerdur_core_2.getUserFavoriteTracks; } });
123
- Object.defineProperty(exports, "getUserFavoriteAlbums", { enumerable: true, get: function () { return gerdur_core_2.getUserFavoriteAlbums; } });
124
- Object.defineProperty(exports, "getUserFavoriteArtists", { enumerable: true, get: function () { return gerdur_core_2.getUserFavoriteArtists; } });
125
- Object.defineProperty(exports, "getUserPlaylists", { enumerable: true, get: function () { return gerdur_core_2.getUserPlaylists; } });
126
- Object.defineProperty(exports, "getUserRadios", { enumerable: true, get: function () { return gerdur_core_2.getUserRadios; } });
127
- Object.defineProperty(exports, "getUserChartTracks", { enumerable: true, get: function () { return gerdur_core_2.getUserChartTracks; } });
128
- Object.defineProperty(exports, "getRadios", { enumerable: true, get: function () { return gerdur_core_2.getRadios; } });
129
- Object.defineProperty(exports, "getRadioTracks", { enumerable: true, get: function () { return gerdur_core_2.getRadioTracks; } });
130
- Object.defineProperty(exports, "getRadioGenres", { enumerable: true, get: function () { return gerdur_core_2.getRadioGenres; } });
131
- Object.defineProperty(exports, "getEpisode", { enumerable: true, get: function () { return gerdur_core_2.getEpisode; } });
132
- Object.defineProperty(exports, "getShowEpisodes", { enumerable: true, get: function () { return gerdur_core_2.getShowEpisodes; } });
133
- Object.defineProperty(exports, "refreshTrackTokens", { enumerable: true, get: function () { return gerdur_core_2.refreshTrackTokens; } });
134
- Object.defineProperty(exports, "getTrackByISRC", { enumerable: true, get: function () { return gerdur_core_2.getTrackByISRC; } });
135
- Object.defineProperty(exports, "getAlbumByUPC", { enumerable: true, get: function () { return gerdur_core_2.getAlbumByUPC; } });
136
- Object.defineProperty(exports, "getTrackPreview", { enumerable: true, get: function () { return gerdur_core_2.getTrackPreview; } });
137
- Object.defineProperty(exports, "downloadPreview", { enumerable: true, get: function () { return gerdur_core_2.downloadPreview; } });
138
- Object.defineProperty(exports, "formatName", { enumerable: true, get: function () { return gerdur_core_2.formatName; } });
139
- Object.defineProperty(exports, "toFormat", { enumerable: true, get: function () { return gerdur_core_2.toFormat; } });
140
- Object.defineProperty(exports, "DEEZER_FORMATS", { enumerable: true, get: function () { return gerdur_core_2.DEEZER_FORMATS; } });
141
- Object.defineProperty(exports, "getUser", { enumerable: true, get: function () { return gerdur_core_2.getUser; } });
142
- Object.defineProperty(exports, "getTrackInfo", { enumerable: true, get: function () { return gerdur_core_2.getTrackInfo; } });
143
- Object.defineProperty(exports, "getAlbumInfo", { enumerable: true, get: function () { return gerdur_core_2.getAlbumInfo; } });
144
- Object.defineProperty(exports, "getAlbumTracks", { enumerable: true, get: function () { return gerdur_core_2.getAlbumTracks; } });
145
- Object.defineProperty(exports, "getPlaylistInfo", { enumerable: true, get: function () { return gerdur_core_2.getPlaylistInfo; } });
146
- Object.defineProperty(exports, "getPlaylistTracks", { enumerable: true, get: function () { return gerdur_core_2.getPlaylistTracks; } });
147
- Object.defineProperty(exports, "getArtistInfo", { enumerable: true, get: function () { return gerdur_core_2.getArtistInfo; } });
148
- Object.defineProperty(exports, "getDiscography", { enumerable: true, get: function () { return gerdur_core_2.getDiscography; } });
149
- Object.defineProperty(exports, "getLyrics", { enumerable: true, get: function () { return gerdur_core_2.getLyrics; } });
150
- Object.defineProperty(exports, "getTrackDownloadUrl", { enumerable: true, get: function () { return gerdur_core_2.getTrackDownloadUrl; } });
151
- Object.defineProperty(exports, "resolveDownloadUrls", { enumerable: true, get: function () { return gerdur_core_2.resolveDownloadUrls; } });
152
- Object.defineProperty(exports, "streamTrackDownload", { enumerable: true, get: function () { return gerdur_core_2.streamTrackDownload; } });
153
- Object.defineProperty(exports, "downloadTrackBuffer", { enumerable: true, get: function () { return gerdur_core_2.downloadTrackBuffer; } });
154
- Object.defineProperty(exports, "createDecryptStream", { enumerable: true, get: function () { return gerdur_core_2.createDecryptStream; } });
155
- Object.defineProperty(exports, "getStream", { enumerable: true, get: function () { return gerdur_core_2.getStream; } });
156
- Object.defineProperty(exports, "addTrackTags", { enumerable: true, get: function () { return gerdur_core_2.addTrackTags; } });
157
- Object.defineProperty(exports, "getRichAlbum", { enumerable: true, get: function () { return gerdur_core_2.getRichAlbum; } });
158
- Object.defineProperty(exports, "normalizeContributors", { enumerable: true, get: function () { return gerdur_core_2.normalizeContributors; } });
159
- Object.defineProperty(exports, "toLrc", { enumerable: true, get: function () { return gerdur_core_2.toLrc; } });
160
- Object.defineProperty(exports, "GeoBlocked", { enumerable: true, get: function () { return gerdur_core_2.GeoBlocked; } });
161
- Object.defineProperty(exports, "DeezerError", { enumerable: true, get: function () { return gerdur_core_2.DeezerError; } });
108
+ var gerdur_core_3 = require("gerdur-core");
109
+ Object.defineProperty(exports, "initDeezerApi", { enumerable: true, get: function () { return gerdur_core_3.initDeezerApi; } });
110
+ Object.defineProperty(exports, "parseInfo", { enumerable: true, get: function () { return gerdur_core_3.parseInfo; } });
111
+ Object.defineProperty(exports, "searchMusic", { enumerable: true, get: function () { return gerdur_core_3.searchMusic; } });
112
+ Object.defineProperty(exports, "searchFacets", { enumerable: true, get: function () { return gerdur_core_3.searchFacets; } });
113
+ Object.defineProperty(exports, "searchPublicApi", { enumerable: true, get: function () { return gerdur_core_3.searchPublicApi; } });
114
+ Object.defineProperty(exports, "searchTracks", { enumerable: true, get: function () { return gerdur_core_3.searchTracks; } });
115
+ Object.defineProperty(exports, "searchAlbums", { enumerable: true, get: function () { return gerdur_core_3.searchAlbums; } });
116
+ Object.defineProperty(exports, "searchArtists", { enumerable: true, get: function () { return gerdur_core_3.searchArtists; } });
117
+ Object.defineProperty(exports, "searchPlaylists", { enumerable: true, get: function () { return gerdur_core_3.searchPlaylists; } });
118
+ Object.defineProperty(exports, "buildAdvancedQuery", { enumerable: true, get: function () { return gerdur_core_3.buildAdvancedQuery; } });
119
+ Object.defineProperty(exports, "suggest", { enumerable: true, get: function () { return gerdur_core_3.suggest; } });
120
+ Object.defineProperty(exports, "getGenres", { enumerable: true, get: function () { return gerdur_core_3.getGenres; } });
121
+ Object.defineProperty(exports, "getChart", { enumerable: true, get: function () { return gerdur_core_3.getChart; } });
122
+ Object.defineProperty(exports, "getChartTracks", { enumerable: true, get: function () { return gerdur_core_3.getChartTracks; } });
123
+ Object.defineProperty(exports, "getGenreArtists", { enumerable: true, get: function () { return gerdur_core_3.getGenreArtists; } });
124
+ Object.defineProperty(exports, "getEditorialList", { enumerable: true, get: function () { return gerdur_core_3.getEditorialList; } });
125
+ Object.defineProperty(exports, "getEditorialReleases", { enumerable: true, get: function () { return gerdur_core_3.getEditorialReleases; } });
126
+ Object.defineProperty(exports, "getEditorialSelection", { enumerable: true, get: function () { return gerdur_core_3.getEditorialSelection; } });
127
+ Object.defineProperty(exports, "getEditorialCharts", { enumerable: true, get: function () { return gerdur_core_3.getEditorialCharts; } });
128
+ Object.defineProperty(exports, "getArtistTopTracks", { enumerable: true, get: function () { return gerdur_core_3.getArtistTopTracks; } });
129
+ Object.defineProperty(exports, "getRelatedArtists", { enumerable: true, get: function () { return gerdur_core_3.getRelatedArtists; } });
130
+ Object.defineProperty(exports, "getArtistAlbums", { enumerable: true, get: function () { return gerdur_core_3.getArtistAlbums; } });
131
+ Object.defineProperty(exports, "getArtistPlaylists", { enumerable: true, get: function () { return gerdur_core_3.getArtistPlaylists; } });
132
+ Object.defineProperty(exports, "getArtistRadioTracks", { enumerable: true, get: function () { return gerdur_core_3.getArtistRadioTracks; } });
133
+ Object.defineProperty(exports, "getUserFlow", { enumerable: true, get: function () { return gerdur_core_3.getUserFlow; } });
134
+ Object.defineProperty(exports, "getUserFavoriteTracks", { enumerable: true, get: function () { return gerdur_core_3.getUserFavoriteTracks; } });
135
+ Object.defineProperty(exports, "getUserFavoriteAlbums", { enumerable: true, get: function () { return gerdur_core_3.getUserFavoriteAlbums; } });
136
+ Object.defineProperty(exports, "getUserFavoriteArtists", { enumerable: true, get: function () { return gerdur_core_3.getUserFavoriteArtists; } });
137
+ Object.defineProperty(exports, "getUserPlaylists", { enumerable: true, get: function () { return gerdur_core_3.getUserPlaylists; } });
138
+ Object.defineProperty(exports, "getUserRadios", { enumerable: true, get: function () { return gerdur_core_3.getUserRadios; } });
139
+ Object.defineProperty(exports, "getUserChartTracks", { enumerable: true, get: function () { return gerdur_core_3.getUserChartTracks; } });
140
+ Object.defineProperty(exports, "getRadios", { enumerable: true, get: function () { return gerdur_core_3.getRadios; } });
141
+ Object.defineProperty(exports, "getRadioTracks", { enumerable: true, get: function () { return gerdur_core_3.getRadioTracks; } });
142
+ Object.defineProperty(exports, "getRadioGenres", { enumerable: true, get: function () { return gerdur_core_3.getRadioGenres; } });
143
+ Object.defineProperty(exports, "getEpisode", { enumerable: true, get: function () { return gerdur_core_3.getEpisode; } });
144
+ Object.defineProperty(exports, "getShowEpisodes", { enumerable: true, get: function () { return gerdur_core_3.getShowEpisodes; } });
145
+ Object.defineProperty(exports, "refreshTrackTokens", { enumerable: true, get: function () { return gerdur_core_3.refreshTrackTokens; } });
146
+ Object.defineProperty(exports, "getTrackByISRC", { enumerable: true, get: function () { return gerdur_core_3.getTrackByISRC; } });
147
+ Object.defineProperty(exports, "getAlbumByUPC", { enumerable: true, get: function () { return gerdur_core_3.getAlbumByUPC; } });
148
+ Object.defineProperty(exports, "getTrackPreview", { enumerable: true, get: function () { return gerdur_core_3.getTrackPreview; } });
149
+ Object.defineProperty(exports, "downloadPreview", { enumerable: true, get: function () { return gerdur_core_3.downloadPreview; } });
150
+ Object.defineProperty(exports, "formatName", { enumerable: true, get: function () { return gerdur_core_3.formatName; } });
151
+ Object.defineProperty(exports, "toFormat", { enumerable: true, get: function () { return gerdur_core_3.toFormat; } });
152
+ Object.defineProperty(exports, "DEEZER_FORMATS", { enumerable: true, get: function () { return gerdur_core_3.DEEZER_FORMATS; } });
153
+ Object.defineProperty(exports, "getUser", { enumerable: true, get: function () { return gerdur_core_3.getUser; } });
154
+ Object.defineProperty(exports, "getTrackInfo", { enumerable: true, get: function () { return gerdur_core_3.getTrackInfo; } });
155
+ Object.defineProperty(exports, "getAlbumInfo", { enumerable: true, get: function () { return gerdur_core_3.getAlbumInfo; } });
156
+ Object.defineProperty(exports, "getAlbumTracks", { enumerable: true, get: function () { return gerdur_core_3.getAlbumTracks; } });
157
+ Object.defineProperty(exports, "getPlaylistInfo", { enumerable: true, get: function () { return gerdur_core_3.getPlaylistInfo; } });
158
+ Object.defineProperty(exports, "getPlaylistTracks", { enumerable: true, get: function () { return gerdur_core_3.getPlaylistTracks; } });
159
+ Object.defineProperty(exports, "getArtistInfo", { enumerable: true, get: function () { return gerdur_core_3.getArtistInfo; } });
160
+ Object.defineProperty(exports, "getDiscography", { enumerable: true, get: function () { return gerdur_core_3.getDiscography; } });
161
+ Object.defineProperty(exports, "getLyrics", { enumerable: true, get: function () { return gerdur_core_3.getLyrics; } });
162
+ Object.defineProperty(exports, "getTrackDownloadUrl", { enumerable: true, get: function () { return gerdur_core_3.getTrackDownloadUrl; } });
163
+ Object.defineProperty(exports, "resolveDownloadUrls", { enumerable: true, get: function () { return gerdur_core_3.resolveDownloadUrls; } });
164
+ Object.defineProperty(exports, "streamTrackDownload", { enumerable: true, get: function () { return gerdur_core_3.streamTrackDownload; } });
165
+ Object.defineProperty(exports, "downloadTrackBuffer", { enumerable: true, get: function () { return gerdur_core_3.downloadTrackBuffer; } });
166
+ Object.defineProperty(exports, "createDecryptStream", { enumerable: true, get: function () { return gerdur_core_3.createDecryptStream; } });
167
+ Object.defineProperty(exports, "getStream", { enumerable: true, get: function () { return gerdur_core_3.getStream; } });
168
+ Object.defineProperty(exports, "addTrackTags", { enumerable: true, get: function () { return gerdur_core_3.addTrackTags; } });
169
+ Object.defineProperty(exports, "getRichAlbum", { enumerable: true, get: function () { return gerdur_core_3.getRichAlbum; } });
170
+ Object.defineProperty(exports, "normalizeContributors", { enumerable: true, get: function () { return gerdur_core_3.normalizeContributors; } });
171
+ Object.defineProperty(exports, "toLrc", { enumerable: true, get: function () { return gerdur_core_3.toLrc; } });
172
+ Object.defineProperty(exports, "GeoBlocked", { enumerable: true, get: function () { return gerdur_core_3.GeoBlocked; } });
173
+ Object.defineProperty(exports, "DeezerError", { enumerable: true, get: function () { return gerdur_core_3.DeezerError; } });
@@ -21,6 +21,12 @@ interface downloadTrackProps {
21
21
  message?: string;
22
22
  /** Write a `.lrc` sidecar for tracks with time-synced lyrics. Default true. */
23
23
  lrc?: boolean;
24
+ /**
25
+ * Replace Deezer's cover art with a higher-resolution one from the Cover Art
26
+ * Archive (looked up via the track's ISRC on MusicBrainz). Falls back silently
27
+ * to Deezer's cover if there's no match. Off by default.
28
+ */
29
+ enrich?: boolean;
24
30
  /**
25
31
  * A download URL already resolved for this track by a batch `resolveDownloadUrls`
26
32
  * pass. When set, the per-track `get_url` request and quality-fallback round-trips
@@ -34,5 +40,5 @@ interface downloadTrackProps {
34
40
  format: string;
35
41
  } | null;
36
42
  }
37
- declare const downloadTrack: ({ track, quality, info, coverSizes, path, totalTracks, trackNumber, fallbackTrack, fallbackQuality, isFallback, isQualityFallback, overwrite, message, lrc, prefetched, }: downloadTrackProps) => Promise<string | undefined>;
43
+ declare const downloadTrack: ({ track, quality, info, coverSizes, path, totalTracks, trackNumber, fallbackTrack, fallbackQuality, isFallback, isQualityFallback, overwrite, message, lrc, enrich, prefetched, }: downloadTrackProps) => Promise<string | undefined>;
38
44
  export default downloadTrack;
@@ -18,7 +18,7 @@ const pipeline = (0, util_1.promisify)(stream_1.default.pipeline);
18
18
  const simulate = process.env.SIMULATE;
19
19
  /** media-API format string -> gerdur's numeric quality */
20
20
  const FORMAT_TO_QUALITY = { FLAC: 9, MP3_320: 3, MP3_256: 3, MP3_128: 1, MP3_64: 1 };
21
- const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTracks, trackNumber = true, fallbackTrack = true, fallbackQuality = true, isFallback = false, isQualityFallback = false, overwrite = false, message = '', lrc = true, prefetched = null, }) => {
21
+ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTracks, trackNumber = true, fallbackTrack = true, fallbackQuality = true, isFallback = false, isQualityFallback = false, overwrite = false, message = '', lrc = true, enrich = false, prefetched = null, }) => {
22
22
  (0, log_update_1.default)(signale_1.default.pending(track.SNG_TITLE + ' by ' + track.ART_NAME + ' from ' + track.ALB_TITLE));
23
23
  try {
24
24
  let ext = '.mp3', fileSize = 0, downloaded = 0, coverSize = 500;
@@ -153,8 +153,24 @@ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTrac
153
153
  else {
154
154
  outFile = (0, fs_1.readFileSync)(tmpfile);
155
155
  }
156
+ let enrichedCover;
157
+ if (enrich && track.ISRC && !simulate) {
158
+ try {
159
+ const coverUrl = await (0, gerdur_core_1.getCoverArtByISRC)(track.ISRC, { minSize: 1200 });
160
+ if (coverUrl) {
161
+ enrichedCover = await (0, gerdur_core_1.getBuffer)(coverUrl);
162
+ (0, log_update_1.default)(signale_1.default.note(`Using a higher-res cover from the Cover Art Archive for ${track.SNG_TITLE}`));
163
+ }
164
+ }
165
+ catch {
166
+ // MusicBrainz / CAA unavailable or no match — keep Deezer's cover
167
+ }
168
+ }
156
169
  (0, log_update_1.default)(signale_1.default.pending('Tagging ' + track.SNG_TITLE + ' by ' + track.ART_NAME));
157
- const { buffer: trackWithMetadata, model } = await (0, gerdur_core_1.addTrackTags)(outFile, track, { coverSize });
170
+ const { buffer: trackWithMetadata, model } = await (0, gerdur_core_1.addTrackTags)(outFile, track, {
171
+ coverSize,
172
+ ...(enrichedCover ? { cover: enrichedCover } : {}),
173
+ });
158
174
  // Delete temporary file now
159
175
  (0, fs_1.unlinkSync)(tmpfile);
160
176
  (0, log_update_1.default)(signale_1.default.pending('Saving ' + track.SNG_TITLE + ' by ' + track.ART_NAME));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur",
3
- "version": "2.9.0",
3
+ "version": "2.11.0",
4
4
  "description": "The crucial streaming module for dabox systems.",
5
5
  "author": "Christian",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -48,7 +48,7 @@
48
48
  "adm-zip": "^0.5.16",
49
49
  "chalk": "^4.1.2",
50
50
  "commander": "^9.5.0",
51
- "gerdur-core": "^2.11.0",
51
+ "gerdur-core": "^2.13.0",
52
52
  "dot-prop": "^6.0.1",
53
53
  "got": "^11.8.6",
54
54
  "gradient-string": "^2.0.2",