gerdur 1.0.2 → 2.0.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,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.0 - 2026-08-31
4
+
5
+ ### Changed
6
+
7
+ - **Metadata is now much richer** (`gerdur-core@^2.0.0`). Every downloaded file
8
+ gets ReplayGain (`REPLAYGAIN_TRACK_GAIN`), BPM, real `©`/`℗` lines, the true
9
+ original release date (distinct from a reissue date), full studio credits
10
+ (featured artists, mastering / mixing / recording engineers, producers),
11
+ compilation/live flags, iTunes advisory, Deezer ids, and the artist photo as a
12
+ second embedded image. Album/playlist tracks are hydrated with one coalesced
13
+ `song.getData` so the credits are complete.
14
+ - **`.lrc` sidecar files** are written next to the audio for tracks with
15
+ time-synced lyrics. Toggle with `"lyrics": {"lrcFile": false}` in
16
+ `gerdur.config.json`.
17
+ - Cover-art requests are capped at Deezer's real ceiling of 1800 px.
18
+
19
+ ### Breaking (programmatic API)
20
+
21
+ - `gerdur-core.addTrackTags` changed signature/return — see its 2.0.0 changelog.
22
+ `getTrackBuffer` is unaffected (still resolves to `Buffer | null`); new
23
+ `getTaggedTrack(track, quality, options)` returns `{buffer, model}` with the
24
+ structured metadata and LRC. `downloadTrackToFile` now also returns `lrcPath`
25
+ when a sidecar was written.
26
+
3
27
  ## 1.0.1 - 2026-08-30
4
28
 
5
29
  ### Changed
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur",
3
- "version": "1.0.2",
3
+ "version": "2.0.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": "^1.0.4",
51
+ "gerdur-core": "^2.0.0",
52
52
  "dot-prop": "^6.0.1",
53
53
  "got": "^11.8.6",
54
54
  "gradient-string": "^2.0.2",
@@ -215,6 +215,7 @@ const startDownload = async (saveLayout, url, skipPrompt) => {
215
215
  const trackNumber = conf.get('trackNumber', true);
216
216
  const fallbackTrack = conf.get('fallbackTrack', true);
217
217
  const fallbackQuality = conf.get('fallbackQuality', true);
218
+ const lrc = conf.get('lyrics.lrcFile', true);
218
219
  const overwrite = options.overwrite ?? conf.get('overwrite', false);
219
220
  const resolveFullPath = options.resolveFullPath ?? conf.get('playlist.resolveFullPath');
220
221
  const savedFiles = [];
@@ -259,6 +260,7 @@ const startDownload = async (saveLayout, url, skipPrompt) => {
259
260
  fallbackQuality,
260
261
  overwrite,
261
262
  message: `(${index}/${data.tracks.length})`,
263
+ lrc,
262
264
  prefetched: prefetchedUrls.get(track.SNG_ID) ?? null,
263
265
  });
264
266
  // Add to saved list
@@ -56,7 +56,8 @@ export declare class LoginError extends Error {
56
56
  export declare const getArl: (email: string, password: string) => Promise<string>;
57
57
  export { createSession, Session } from './lib/session';
58
58
  export type { SessionOptions, DownloadTracksOptions, SearchType } from './lib/session';
59
- export { getTrackBuffer, downloadTrackToFile } from './lib/api-download';
59
+ export { getTrackBuffer, getTaggedTrack, downloadTrackToFile } from './lib/api-download';
60
60
  export type { Quality, GetTrackBufferOptions, DownloadTrackOptions, DownloadResult } from './lib/api-download';
61
61
  export { default as Config, globalConfigPath, resolveConfigFile } from './lib/config';
62
- export { initDeezerApi, parseInfo, searchMusic, getUser, getTrackInfo, getAlbumInfo, getAlbumTracks, getPlaylistInfo, getPlaylistTracks, getArtistInfo, getDiscography, getLyrics, getTrackDownloadUrl, GeoBlocked, } from 'gerdur-core';
62
+ export { initDeezerApi, parseInfo, searchMusic, getUser, getTrackInfo, getAlbumInfo, getAlbumTracks, getPlaylistInfo, getPlaylistTracks, getArtistInfo, getDiscography, getLyrics, getTrackDownloadUrl, resolveDownloadUrls, addTrackTags, getRichAlbum, normalizeContributors, toLrc, GeoBlocked, } from 'gerdur-core';
63
+ export type { AddTrackTagsOptions, TaggedTrack, TrackTagModel, RichAlbum, ResolvedUrl, NormalizedContributors, } from 'gerdur-core';
package/dist/src/index.js CHANGED
@@ -33,7 +33,7 @@ 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.GeoBlocked = exports.getTrackDownloadUrl = exports.getLyrics = exports.getDiscography = exports.getArtistInfo = exports.getPlaylistTracks = exports.getPlaylistInfo = exports.getAlbumTracks = exports.getAlbumInfo = exports.getTrackInfo = exports.getUser = exports.searchMusic = exports.parseInfo = exports.initDeezerApi = exports.resolveConfigFile = exports.globalConfigPath = exports.Config = exports.downloadTrackToFile = exports.getTrackBuffer = exports.Session = exports.createSession = exports.getArl = exports.LoginError = exports.loginWithEmail = void 0;
36
+ exports.GeoBlocked = exports.toLrc = exports.normalizeContributors = exports.getRichAlbum = exports.addTrackTags = exports.resolveDownloadUrls = exports.getTrackDownloadUrl = exports.getLyrics = exports.getDiscography = exports.getArtistInfo = exports.getPlaylistTracks = exports.getPlaylistInfo = exports.getAlbumTracks = exports.getAlbumInfo = exports.getTrackInfo = exports.getUser = exports.searchMusic = exports.parseInfo = exports.initDeezerApi = exports.resolveConfigFile = exports.globalConfigPath = exports.Config = exports.downloadTrackToFile = exports.getTaggedTrack = exports.getTrackBuffer = exports.Session = exports.createSession = exports.getArl = exports.LoginError = exports.loginWithEmail = void 0;
37
37
  // ─── Authentication ────────────────────────────────────────────────────────
38
38
  const email_login_1 = require("./lib/email-login");
39
39
  Object.defineProperty(exports, "loginWithEmail", { enumerable: true, get: function () { return email_login_1.loginWithEmail; } });
@@ -74,6 +74,7 @@ Object.defineProperty(exports, "Session", { enumerable: true, get: function () {
74
74
  // ─── Download primitives ─────────────────────────────────────────────────────
75
75
  var api_download_1 = require("./lib/api-download");
76
76
  Object.defineProperty(exports, "getTrackBuffer", { enumerable: true, get: function () { return api_download_1.getTrackBuffer; } });
77
+ Object.defineProperty(exports, "getTaggedTrack", { enumerable: true, get: function () { return api_download_1.getTaggedTrack; } });
77
78
  Object.defineProperty(exports, "downloadTrackToFile", { enumerable: true, get: function () { return api_download_1.downloadTrackToFile; } });
78
79
  // ─── Config ──────────────────────────────────────────────────────────────────
79
80
  // The same config the CLI uses (env var, global path resolution, arl storage).
@@ -98,4 +99,9 @@ Object.defineProperty(exports, "getArtistInfo", { enumerable: true, get: functio
98
99
  Object.defineProperty(exports, "getDiscography", { enumerable: true, get: function () { return gerdur_core_1.getDiscography; } });
99
100
  Object.defineProperty(exports, "getLyrics", { enumerable: true, get: function () { return gerdur_core_1.getLyrics; } });
100
101
  Object.defineProperty(exports, "getTrackDownloadUrl", { enumerable: true, get: function () { return gerdur_core_1.getTrackDownloadUrl; } });
102
+ Object.defineProperty(exports, "resolveDownloadUrls", { enumerable: true, get: function () { return gerdur_core_1.resolveDownloadUrls; } });
103
+ Object.defineProperty(exports, "addTrackTags", { enumerable: true, get: function () { return gerdur_core_1.addTrackTags; } });
104
+ Object.defineProperty(exports, "getRichAlbum", { enumerable: true, get: function () { return gerdur_core_1.getRichAlbum; } });
105
+ Object.defineProperty(exports, "normalizeContributors", { enumerable: true, get: function () { return gerdur_core_1.normalizeContributors; } });
106
+ Object.defineProperty(exports, "toLrc", { enumerable: true, get: function () { return gerdur_core_1.toLrc; } });
101
107
  Object.defineProperty(exports, "GeoBlocked", { enumerable: true, get: function () { return gerdur_core_1.GeoBlocked; } });
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ import type { AddTrackTagsOptions } from 'gerdur-core';
2
3
  import type { trackType } from 'gerdur-core/types';
3
4
  /** Music quality accepted by the API. */
4
5
  export type Quality = '128' | '320' | 'flac' | 1 | 3 | 9;
@@ -10,18 +11,30 @@ export interface GetTrackBufferOptions {
10
11
  * before giving up. Default true.
11
12
  */
12
13
  fallbackQuality?: boolean;
14
+ /**
15
+ * Extra metadata-writer options passed straight to `gerdur-core.addTrackTags`
16
+ * (e.g. `{embedArtistImage: false, richCredits: false}`). `coverSize` above
17
+ * wins over `metadata.coverSize`.
18
+ */
19
+ metadata?: AddTrackTagsOptions;
13
20
  }
14
21
  /**
15
22
  * Download, decrypt, and tag a single track entirely in memory.
16
23
  *
17
24
  * Returns the ready-to-write audio Buffer (MP3 or FLAC), or `null` if the track
18
25
  * is not available for download. Nothing is written to disk and nothing is
19
- * logged.
26
+ * logged. Use `getTaggedTrack` if you also want the structured metadata / LRC.
20
27
  *
21
28
  * @param track Track info (e.g. from `getTrackInfo` or `parseUrl`).
22
29
  * @param quality '128' | '320' | 'flac' (or numeric 1 | 3 | 9).
23
30
  */
24
- export declare const getTrackBuffer: (track: trackType, quality?: Quality, { coverSize, fallbackQuality }?: GetTrackBufferOptions) => Promise<Buffer | null>;
31
+ export declare const getTrackBuffer: (track: trackType, quality?: Quality, options?: GetTrackBufferOptions) => Promise<Buffer | null>;
32
+ /**
33
+ * Like `getTrackBuffer`, but returns `{buffer, model}` — `model` carries every
34
+ * field gerdur pulled from Deezer, including `model.lyricsSynced` (an LRC
35
+ * document) when the track has time-synced lyrics.
36
+ */
37
+ export declare const getTaggedTrack: (track: trackType, quality?: Quality, options?: GetTrackBufferOptions) => Promise<import("gerdur-core").TaggedTrack | null>;
25
38
  export interface DownloadTrackOptions extends GetTrackBufferOptions {
26
39
  /**
27
40
  * Output file path or a `saveLayout` template (e.g. `{ART_NAME} - {SNG_TITLE}`).
@@ -37,12 +50,16 @@ export interface DownloadTrackOptions extends GetTrackBufferOptions {
37
50
  trackNumber?: boolean;
38
51
  /** Re-download even if the destination file already exists. Default false. */
39
52
  overwrite?: boolean;
53
+ /** Write a `.lrc` sidecar next to the audio when the track has synced lyrics. Default true. */
54
+ lrc?: boolean;
40
55
  }
41
56
  export interface DownloadResult {
42
57
  /** The path the file was written to (or would have been, if skipped). */
43
58
  path: string;
44
59
  /** True if the file was written; false if skipped because it already existed. */
45
60
  written: boolean;
61
+ /** Path of the `.lrc` sidecar, if one was written. */
62
+ lrcPath?: string;
46
63
  }
47
64
  /**
48
65
  * Download a single track to disk (silent). Resolves the destination path from
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.downloadTrackToFile = exports.getTrackBuffer = void 0;
6
+ exports.downloadTrackToFile = exports.getTaggedTrack = exports.getTrackBuffer = void 0;
7
7
  const fs_1 = require("fs");
8
8
  const path_1 = require("path");
9
9
  const got_1 = __importDefault(require("got"));
@@ -22,18 +22,12 @@ const resolveQuality = (quality) => {
22
22
  const key = String(quality).toLowerCase();
23
23
  return QUALITY_MAP[key] ?? QUALITY_MAP['320'];
24
24
  };
25
- /**
26
- * Download, decrypt, and tag a single track entirely in memory.
27
- *
28
- * Returns the ready-to-write audio Buffer (MP3 or FLAC), or `null` if the track
29
- * is not available for download. Nothing is written to disk and nothing is
30
- * logged.
31
- *
32
- * @param track Track info (e.g. from `getTrackInfo` or `parseUrl`).
33
- * @param quality '128' | '320' | 'flac' (or numeric 1 | 3 | 9).
34
- */
35
- const getTrackBuffer = async (track, quality = '320', { coverSize = 500, fallbackQuality = true } = {}) => {
36
- const order = fallbackQuality ? [quality, '320', '128'] : [quality];
25
+ const tagOptions = (o) => ({
26
+ ...o.metadata,
27
+ coverSize: o.coverSize ?? o.metadata?.coverSize ?? 500,
28
+ });
29
+ const fetchDecryptTag = async (track, quality, options) => {
30
+ const order = options.fallbackQuality === false ? [quality] : [quality, '320', '128'];
37
31
  const tried = new Set();
38
32
  for (const q of order) {
39
33
  const { q: qNum } = resolveQuality(q);
@@ -54,13 +48,34 @@ const getTrackBuffer = async (track, quality = '320', { coverSize = 500, fallbac
54
48
  if (!trackData) {
55
49
  continue;
56
50
  }
57
- const { body } = await (0, got_1.default)(trackData.trackUrl, { responseType: 'buffer' });
51
+ const { body } = await (0, got_1.default)(trackData.trackUrl, { responseType: 'buffer', agent: { http: gerdur_core_1.httpAgent, https: gerdur_core_1.httpsAgent } });
58
52
  const decrypted = trackData.isEncrypted ? (0, decrypt_1.decryptDownload)(body, track.SNG_ID) : body;
59
- return (0, gerdur_core_1.addTrackTags)(decrypted, track, coverSize);
53
+ return (0, gerdur_core_1.addTrackTags)(decrypted, track, tagOptions(options));
60
54
  }
61
55
  return null;
62
56
  };
57
+ /**
58
+ * Download, decrypt, and tag a single track entirely in memory.
59
+ *
60
+ * Returns the ready-to-write audio Buffer (MP3 or FLAC), or `null` if the track
61
+ * is not available for download. Nothing is written to disk and nothing is
62
+ * logged. Use `getTaggedTrack` if you also want the structured metadata / LRC.
63
+ *
64
+ * @param track Track info (e.g. from `getTrackInfo` or `parseUrl`).
65
+ * @param quality '128' | '320' | 'flac' (or numeric 1 | 3 | 9).
66
+ */
67
+ const getTrackBuffer = async (track, quality = '320', options = {}) => {
68
+ const tagged = await fetchDecryptTag(track, quality, options);
69
+ return tagged ? tagged.buffer : null;
70
+ };
63
71
  exports.getTrackBuffer = getTrackBuffer;
72
+ /**
73
+ * Like `getTrackBuffer`, but returns `{buffer, model}` — `model` carries every
74
+ * field gerdur pulled from Deezer, including `model.lyricsSynced` (an LRC
75
+ * document) when the track has time-synced lyrics.
76
+ */
77
+ const getTaggedTrack = (track, quality = '320', options = {}) => fetchDecryptTag(track, quality, options);
78
+ exports.getTaggedTrack = getTaggedTrack;
64
79
  /**
65
80
  * Download a single track to disk (silent). Resolves the destination path from
66
81
  * the `output` template, skips existing files unless `overwrite` is set, and
@@ -75,15 +90,20 @@ const downloadTrackToFile = async (track, quality = '320', options = {}) => {
75
90
  if ((0, fs_1.existsSync)(savePath) && !overwrite) {
76
91
  return { path: savePath, written: false };
77
92
  }
78
- const buffer = await (0, exports.getTrackBuffer)(track, quality, options);
79
- if (!buffer) {
93
+ const tagged = await (0, exports.getTaggedTrack)(track, quality, options);
94
+ if (!tagged) {
80
95
  return null;
81
96
  }
82
97
  const dir = (0, path_1.dirname)(savePath);
83
98
  if (dir && !(0, fs_1.existsSync)(dir)) {
84
99
  (0, fs_1.mkdirSync)(dir, { recursive: true });
85
100
  }
86
- (0, fs_1.writeFileSync)(savePath, buffer);
87
- return { path: savePath, written: true };
101
+ (0, fs_1.writeFileSync)(savePath, tagged.buffer);
102
+ let lrcPath;
103
+ if (options.lrc !== false && tagged.model.lyricsSynced) {
104
+ lrcPath = savePath.replace(/\.(mp3|flac)$/i, '.lrc');
105
+ (0, fs_1.writeFileSync)(lrcPath, tagged.model.lyricsSynced);
106
+ }
107
+ return { path: savePath, written: true, lrcPath };
88
108
  };
89
109
  exports.downloadTrackToFile = downloadTrackToFile;
@@ -12,7 +12,7 @@ export declare const globalConfigPath: () => string;
12
12
  * 3. the global config path (created on first write)
13
13
  */
14
14
  export declare const resolveConfigFile: (configFile: string) => string;
15
- type keysType = 'concurrency' | 'saveLayout' | 'saveLayout.track' | 'saveLayout.album' | 'saveLayout.artist' | 'saveLayout.playlist' | 'playlist.resolveFullPath' | 'trackNumber' | 'fallbackTrack' | 'fallbackQuality' | 'overwrite' | 'coverSize' | 'coverSize.128' | 'coverSize.320' | 'coverSize.flac' | 'cookies.arl' | 'cookies.email' | 'cookies.password';
15
+ type keysType = 'concurrency' | 'saveLayout' | 'saveLayout.track' | 'saveLayout.album' | 'saveLayout.artist' | 'saveLayout.playlist' | 'playlist.resolveFullPath' | 'trackNumber' | 'fallbackTrack' | 'fallbackQuality' | 'overwrite' | 'coverSize' | 'coverSize.128' | 'coverSize.320' | 'coverSize.flac' | 'lyrics.lrcFile' | 'cookies.arl' | 'cookies.email' | 'cookies.password';
16
16
  declare class Config {
17
17
  userConfigLocation: string | null;
18
18
  private configFile;
@@ -62,6 +62,9 @@ const defaultConfig = {
62
62
  '320': 500,
63
63
  flac: 1000,
64
64
  },
65
+ lyrics: {
66
+ lrcFile: true,
67
+ },
65
68
  cookies: {
66
69
  arl: 'c973964816688562722418b5200c1515dffaad15a42643ebf87cc72824a54612ec51c2ad42d566743f9e424c774e98ccae7737770acff59251328e6cd598c7bcac38ca269adf78bfb88ec5bbad6cd800db3c0b88b2af645bb22b99e71de26416',
67
70
  },
@@ -94,6 +97,9 @@ class Config {
94
97
  if (userConfig.coverSize) {
95
98
  userConfig.coverSize = { ...defaultConfig.coverSize, ...userConfig.coverSize };
96
99
  }
100
+ if (userConfig.lyrics) {
101
+ userConfig.lyrics = { ...defaultConfig.lyrics, ...userConfig.lyrics };
102
+ }
97
103
  if (userConfig.cookies) {
98
104
  userConfig.cookies = { ...defaultConfig.cookies, ...userConfig.cookies };
99
105
  }
@@ -19,6 +19,8 @@ interface downloadTrackProps {
19
19
  isQualityFallback?: boolean;
20
20
  overwrite?: boolean;
21
21
  message?: string;
22
+ /** Write a `.lrc` sidecar for tracks with time-synced lyrics. Default true. */
23
+ lrc?: boolean;
22
24
  /**
23
25
  * A download URL already resolved for this track by a batch `resolveDownloadUrls`
24
26
  * pass. When set, the per-track `get_url` request and quality-fallback round-trips
@@ -32,5 +34,5 @@ interface downloadTrackProps {
32
34
  format: string;
33
35
  } | null;
34
36
  }
35
- declare const downloadTrack: ({ track, quality, info, coverSizes, path, totalTracks, trackNumber, fallbackTrack, fallbackQuality, isFallback, isQualityFallback, overwrite, message, prefetched, }: downloadTrackProps) => Promise<string | undefined>;
37
+ declare const downloadTrack: ({ track, quality, info, coverSizes, path, totalTracks, trackNumber, fallbackTrack, fallbackQuality, isFallback, isQualityFallback, overwrite, message, lrc, prefetched, }: downloadTrackProps) => Promise<string | undefined>;
36
38
  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 = '', 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, 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;
@@ -89,6 +89,7 @@ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTrac
89
89
  isFallback: true,
90
90
  overwrite,
91
91
  message,
92
+ lrc,
92
93
  });
93
94
  }
94
95
  else if (fallbackQuality && quality !== 1) {
@@ -105,6 +106,7 @@ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTrac
105
106
  isQualityFallback: true,
106
107
  overwrite,
107
108
  message,
109
+ lrc,
108
110
  });
109
111
  }
110
112
  (0, log_update_1.default)(signale_1.default.warn(`Skipped "${track.SNG_TITLE}", track not available.`));
@@ -149,7 +151,7 @@ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTrac
149
151
  outFile = (0, fs_1.readFileSync)(tmpfile);
150
152
  }
151
153
  (0, log_update_1.default)(signale_1.default.pending('Tagging ' + track.SNG_TITLE + ' by ' + track.ART_NAME));
152
- const trackWithMetadata = await (0, gerdur_core_1.addTrackTags)(outFile, track, coverSize);
154
+ const { buffer: trackWithMetadata, model } = await (0, gerdur_core_1.addTrackTags)(outFile, track, { coverSize });
153
155
  // Delete temporary file now
154
156
  (0, fs_1.unlinkSync)(tmpfile);
155
157
  (0, log_update_1.default)(signale_1.default.pending('Saving ' + track.SNG_TITLE + ' by ' + track.ART_NAME));
@@ -161,6 +163,9 @@ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTrac
161
163
  }
162
164
  // Save file to disk
163
165
  (0, fs_1.writeFileSync)(savePath, trackWithMetadata);
166
+ if (lrc !== false && model.lyricsSynced) {
167
+ (0, fs_1.writeFileSync)(savePath.replace(/\.(mp3|flac)$/i, '.lrc'), model.lyricsSynced);
168
+ }
164
169
  }
165
170
  // Print sucess info
166
171
  (0, log_update_1.default)(signale_1.default.success(`${isFallback ? chalk_1.default.yellow('[Fallback] ') : ''}${track.SNG_TITLE} by ${track.ART_NAME}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur",
3
- "version": "1.0.2",
3
+ "version": "2.0.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": "^1.0.4",
51
+ "gerdur-core": "^2.0.0",
52
52
  "dot-prop": "^6.0.1",
53
53
  "got": "^11.8.6",
54
54
  "gradient-string": "^2.0.2",