gerdur-core 2.5.0 → 2.6.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,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.6.0 - 2026-08-31
4
+
5
+ Phase 2.4 round 2 — Flow, radios, and a user's library. All public REST, all
6
+ memoised, all additive.
7
+
8
+ ### Added
9
+
10
+ - **Flow / library** (take a `userId`): `getUserFlow`, `getUserFavoriteTracks`
11
+ (with `time_add`), `getUserFavoriteAlbums`, `getUserFavoriteArtists`,
12
+ `getUserPlaylists`, `getUserRadios`, `getUserChartTracks`.
13
+ - **Radios**: `getRadios`, `getRadioTracks(radioId)`, `getRadioGenres`.
14
+ - New types: `userFavoriteTrack`, `userFavoriteAlbum`, `userFavoriteArtist`,
15
+ `userPlaylistResult`, `radioResult`, `radioGenre`.
16
+
17
+ ### Internal
18
+
19
+ - Tests run under `ts-node/register/transpile-only` (build still type-checks) —
20
+ the growing live-API suite was hitting the ts-node worker heap limit.
21
+ - Live-API tests skip cleanly on Deezer's `code: 4` "Quota limit exceeded"
22
+ instead of failing when the suite bursts the public API.
23
+
3
24
  ## 2.5.0 - 2026-08-31
4
25
 
5
26
  Phase 3.1 — streaming download primitives. Additive.
package/README.md CHANGED
@@ -244,6 +244,31 @@ const track = await getTrackByISRC('USUM71311296'); // "Get Lucky"
244
244
  pass the `id` to `getTrackInfo` / `getAlbumTracks` (or use the converter's
245
245
  `isrc2deezer` / `upc2deezer`, which hydrate a gw track for you).
246
246
 
247
+ ### Flow, radios & a user's library
248
+
249
+ Public-profile data — pass a `userId` (`getUser().USER_ID`, a profile URL, or
250
+ `parseInfo`). A private library is only visible to that user's own session.
251
+
252
+ | Method | Returns |
253
+ | :--- | :--- |
254
+ | `getUserFlow(userId, limit = 40)` | **Flow** — the endless personalised mix, as tracks. |
255
+ | `getUserFavoriteTracks(userId, limit?, index?)` | loved tracks, newest first (each with `time_add`). |
256
+ | `getUserFavoriteAlbums(userId, limit?, index?)` | favourite albums. |
257
+ | `getUserFavoriteArtists(userId, limit?, index?)` | favourite artists. |
258
+ | `getUserPlaylists(userId, limit?, index?)` | the user's own + followed playlists. |
259
+ | `getUserRadios(userId)` | radios the user favourited. |
260
+ | `getUserChartTracks(userId, limit?)` | the user's personal top tracks. |
261
+ | `getRadios()` | Deezer's curated radio list. |
262
+ | `getRadioTracks(radioId)` | a radio's current tracklist — a ready-to-play source. |
263
+ | `getRadioGenres()` | radios grouped by genre. |
264
+
265
+ ```js
266
+ const me = await getUser();
267
+ const {data: flow} = await getUserFlow(me.USER_ID); // your Flow
268
+ const {data: loved} = await getUserFavoriteTracks(me.USER_ID);
269
+ const {data: eighties} = await getRadioTracks(38305); // "The '80s"
270
+ ```
271
+
247
272
  ### `.getTrackDownloadUrl(track, quality);`
248
273
 
249
274
  | Parameters | Required | Type | Description |
@@ -3,3 +3,4 @@ export * from './request';
3
3
  export * from './search';
4
4
  export * from './browse';
5
5
  export * from './preview';
6
+ export * from './user';
package/dist/api/index.js CHANGED
@@ -19,3 +19,4 @@ __exportStar(require("./request"), exports);
19
19
  __exportStar(require("./search"), exports);
20
20
  __exportStar(require("./browse"), exports);
21
21
  __exportStar(require("./preview"), exports);
22
+ __exportStar(require("./user"), exports);
@@ -0,0 +1,24 @@
1
+ import type { publicApiList, radioGenre, radioResult, searchResultTrack, userFavoriteAlbum, userFavoriteArtist, userFavoriteTrack, userPlaylistResult } from '../types';
2
+ /**
3
+ * Deezer **Flow** — the endless personalised mix — for a user. Returns
4
+ * public-API track objects; `getTrackInfo(id)` to make one downloadable.
5
+ */
6
+ export declare const getUserFlow: (userId: number | string, limit?: number) => Promise<publicApiList<searchResultTrack>>;
7
+ /** A user's favourite (loved) tracks, newest first; each carries `time_add`. */
8
+ export declare const getUserFavoriteTracks: (userId: number | string, limit?: number, index?: number) => Promise<publicApiList<userFavoriteTrack>>;
9
+ /** A user's favourite albums. */
10
+ export declare const getUserFavoriteAlbums: (userId: number | string, limit?: number, index?: number) => Promise<publicApiList<userFavoriteAlbum>>;
11
+ /** A user's favourite artists. */
12
+ export declare const getUserFavoriteArtists: (userId: number | string, limit?: number, index?: number) => Promise<publicApiList<userFavoriteArtist>>;
13
+ /** A user's own + followed playlists. */
14
+ export declare const getUserPlaylists: (userId: number | string, limit?: number, index?: number) => Promise<publicApiList<userPlaylistResult>>;
15
+ /** The radios a user has favourited. */
16
+ export declare const getUserRadios: (userId: number | string) => Promise<publicApiList<radioResult>>;
17
+ /** A user's personal track chart (their most-played). */
18
+ export declare const getUserChartTracks: (userId: number | string, limit?: number) => Promise<publicApiList<searchResultTrack>>;
19
+ /** Deezer's curated radio list. */
20
+ export declare const getRadios: () => Promise<publicApiList<radioResult>>;
21
+ /** A radio's current track list — a ready-to-play (public-API) source. */
22
+ export declare const getRadioTracks: (radioId: number | string) => Promise<publicApiList<searchResultTrack>>;
23
+ /** Radios grouped by genre. */
24
+ export declare const getRadioGenres: () => Promise<publicApiList<radioGenre>>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRadioGenres = exports.getRadioTracks = exports.getRadios = exports.getUserChartTracks = exports.getUserRadios = exports.getUserPlaylists = exports.getUserFavoriteArtists = exports.getUserFavoriteAlbums = exports.getUserFavoriteTracks = exports.getUserFlow = void 0;
4
+ const request_1 = require("./request");
5
+ const withParams = (slug, params) => {
6
+ const search = new URLSearchParams();
7
+ for (const [key, value] of Object.entries(params)) {
8
+ if (value !== undefined && value !== '') {
9
+ search.set(key, String(value));
10
+ }
11
+ }
12
+ const qs = search.toString();
13
+ return qs ? `${slug}?${qs}` : slug;
14
+ };
15
+ // ─── Flow & a user's library (public REST) ───────────────────────────────────
16
+ //
17
+ // These take an explicit `userId` (from `getUser().USER_ID`, a profile URL, or
18
+ // `parseInfo`). They read **public** profile data — a user whose library is
19
+ // private only exposes it to their own authenticated session. All memoised.
20
+ /**
21
+ * Deezer **Flow** — the endless personalised mix — for a user. Returns
22
+ * public-API track objects; `getTrackInfo(id)` to make one downloadable.
23
+ */
24
+ const getUserFlow = (userId, limit = 40) => (0, request_1.requestPublicApi)(withParams(`/user/${userId}/flow`, { limit }));
25
+ exports.getUserFlow = getUserFlow;
26
+ /** A user's favourite (loved) tracks, newest first; each carries `time_add`. */
27
+ const getUserFavoriteTracks = (userId, limit = 100, index = 0) => (0, request_1.requestPublicApi)(withParams(`/user/${userId}/tracks`, { limit, index }));
28
+ exports.getUserFavoriteTracks = getUserFavoriteTracks;
29
+ /** A user's favourite albums. */
30
+ const getUserFavoriteAlbums = (userId, limit = 50, index = 0) => (0, request_1.requestPublicApi)(withParams(`/user/${userId}/albums`, { limit, index }));
31
+ exports.getUserFavoriteAlbums = getUserFavoriteAlbums;
32
+ /** A user's favourite artists. */
33
+ const getUserFavoriteArtists = (userId, limit = 50, index = 0) => (0, request_1.requestPublicApi)(withParams(`/user/${userId}/artists`, { limit, index }));
34
+ exports.getUserFavoriteArtists = getUserFavoriteArtists;
35
+ /** A user's own + followed playlists. */
36
+ const getUserPlaylists = (userId, limit = 50, index = 0) => (0, request_1.requestPublicApi)(withParams(`/user/${userId}/playlists`, { limit, index }));
37
+ exports.getUserPlaylists = getUserPlaylists;
38
+ /** The radios a user has favourited. */
39
+ const getUserRadios = (userId) => (0, request_1.requestPublicApi)(`/user/${userId}/radios`);
40
+ exports.getUserRadios = getUserRadios;
41
+ /** A user's personal track chart (their most-played). */
42
+ const getUserChartTracks = (userId, limit = 50) => (0, request_1.requestPublicApi)(withParams(`/user/${userId}/charts/tracks`, { limit }));
43
+ exports.getUserChartTracks = getUserChartTracks;
44
+ // ─── Radios (public REST) ────────────────────────────────────────────────────
45
+ /** Deezer's curated radio list. */
46
+ const getRadios = () => (0, request_1.requestPublicApi)('/radio');
47
+ exports.getRadios = getRadios;
48
+ /** A radio's current track list — a ready-to-play (public-API) source. */
49
+ const getRadioTracks = (radioId) => (0, request_1.requestPublicApi)(`/radio/${radioId}/tracks`);
50
+ exports.getRadioTracks = getRadioTracks;
51
+ /** Radios grouped by genre. */
52
+ const getRadioGenres = () => (0, request_1.requestPublicApi)('/radio/genres');
53
+ exports.getRadioGenres = getRadioGenres;
@@ -1,3 +1,4 @@
1
+ import type { searchResultTrack, searchResultArtist } from './search';
1
2
  export interface userType {
2
3
  USER_ID: string;
3
4
  EMAIL: string;
@@ -14,3 +15,82 @@ export interface userType {
14
15
  PHONE?: string;
15
16
  __TYPE__: 'user';
16
17
  }
18
+ /** A favourite track from `/user/{id}/tracks` — public-API shape, plus `time_add`. */
19
+ export interface userFavoriteTrack extends searchResultTrack {
20
+ /** unix timestamp the track was added to favourites */
21
+ time_add?: number;
22
+ }
23
+ export interface userFavoriteAlbum {
24
+ id: number;
25
+ title: string;
26
+ link: string;
27
+ cover: string;
28
+ cover_small?: string;
29
+ cover_medium?: string;
30
+ cover_big?: string;
31
+ cover_xl?: string;
32
+ md5_image: string;
33
+ nb_tracks: number;
34
+ release_date: string;
35
+ record_type: string;
36
+ available: boolean;
37
+ tracklist: string;
38
+ explicit_lyrics: boolean;
39
+ time_add?: number;
40
+ artist: searchResultArtist | {
41
+ id: number;
42
+ name: string;
43
+ tracklist?: string;
44
+ type: 'artist';
45
+ };
46
+ type: 'album';
47
+ }
48
+ export interface userFavoriteArtist extends searchResultArtist {
49
+ time_add?: number;
50
+ }
51
+ export interface userPlaylistResult {
52
+ id: number;
53
+ title: string;
54
+ duration: number;
55
+ public: boolean;
56
+ is_loved_track: boolean;
57
+ collaborative: boolean;
58
+ nb_tracks: number;
59
+ fans: number;
60
+ link: string;
61
+ picture: string;
62
+ picture_small?: string;
63
+ picture_medium?: string;
64
+ picture_big?: string;
65
+ picture_xl?: string;
66
+ checksum: string;
67
+ tracklist: string;
68
+ creation_date?: string;
69
+ time_add?: number;
70
+ time_mod?: number;
71
+ creator?: {
72
+ id: number;
73
+ name: string;
74
+ tracklist?: string;
75
+ type: 'user';
76
+ };
77
+ type: 'playlist';
78
+ }
79
+ export interface radioResult {
80
+ id: number;
81
+ title: string;
82
+ description?: string;
83
+ picture: string;
84
+ picture_small?: string;
85
+ picture_medium?: string;
86
+ picture_big?: string;
87
+ picture_xl?: string;
88
+ md5_image?: string;
89
+ tracklist: string;
90
+ type: 'radio';
91
+ }
92
+ export interface radioGenre {
93
+ id: number;
94
+ title: string;
95
+ radios: radioResult[];
96
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur-core",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Core module for gerdur.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -61,7 +61,7 @@
61
61
  "!__tests__/helpers.ts"
62
62
  ],
63
63
  "require": [
64
- "ts-node/register"
64
+ "ts-node/register/transpile-only"
65
65
  ],
66
66
  "timeout": "2m",
67
67
  "verbose": true