gerdur-core 2.16.0 → 2.17.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 +26 -0
- package/README.md +32 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/library.d.ts +72 -0
- package/dist/api/library.js +65 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.17.0 - 2026-08-31
|
|
4
|
+
|
|
5
|
+
The account's own library, over the authenticated gateway.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`src/api/library.ts`** — the logged-in account's *private* library. Distinct
|
|
10
|
+
from the public-REST surface in `api/user.ts`, which needs a public profile and
|
|
11
|
+
only shows what that profile exposes. Found by probing the gateway: seven
|
|
12
|
+
methods answer here that the public API cannot reach.
|
|
13
|
+
- `getMyPlaylists(userId?, nb?, start?)` — **including private playlists**
|
|
14
|
+
- `getMyFavoriteTracks` / `getMyFavoriteAlbums` / `getMyFavoriteArtists`
|
|
15
|
+
- `getMyFavoritePlaylists` / `getMyFavoriteRadios` / `getMyFavoriteShows`
|
|
16
|
+
- `getMyFavoriteTrackIds()` — every loved track id in one small request, for
|
|
17
|
+
diffing a local library against the account
|
|
18
|
+
- `userId` defaults to the logged-in account. Responses are gateway shapes, so
|
|
19
|
+
tracks arrive with a `TRACK_TOKEN` and are directly downloadable; being
|
|
20
|
+
account-scoped they stay in the per-session cache and are never shared.
|
|
21
|
+
- **`getTrackMix(sngId, nb?, start?)`** (`song.getSearchTrackMix`) — a "more like
|
|
22
|
+
this" mix seeded from one track. Unlike the public radio endpoints it returns
|
|
23
|
+
full gateway tracks **with tokens already attached**: verified that
|
|
24
|
+
`resolveDownloadUrls` resolves them 3/3 with no `getTrackInfo` round trip.
|
|
25
|
+
|
|
26
|
+
Verified against a live account: `getMyPlaylists` 1/1, `getMyFavoriteArtists`
|
|
27
|
+
7/7 with real names, `getTrackMix` 5/5 all carrying tokens.
|
|
28
|
+
|
|
3
29
|
## 2.16.0 - 2026-08-31
|
|
4
30
|
|
|
5
31
|
### Added
|
package/README.md
CHANGED
|
@@ -46,6 +46,7 @@ the CLI and the file-writing layer on top.
|
|
|
46
46
|
- [Search](#search)
|
|
47
47
|
- [Browse and discover](#browse-and-discover)
|
|
48
48
|
- [Flow, radios and a user's library](#flow-radios-and-a-users-library)
|
|
49
|
+
- [Your own library](#your-own-library)
|
|
49
50
|
- [Podcasts](#podcasts)
|
|
50
51
|
- [Preview clips](#preview-clips)
|
|
51
52
|
- [Resolve a download URL](#resolve-a-download-url)
|
|
@@ -381,6 +382,33 @@ const {data: loved} = await getUserFavoriteTracks(me.USER_ID);
|
|
|
381
382
|
const {data: eighties} = await getRadioTracks(38305); // "The '80s"
|
|
382
383
|
```
|
|
383
384
|
|
|
385
|
+
### Your own library
|
|
386
|
+
|
|
387
|
+
`api/user.ts` above reads a **public** profile. These read what the *account*
|
|
388
|
+
can see — private playlists included — over the authenticated gateway, and
|
|
389
|
+
return gateway shapes, so tracks come with a `TRACK_TOKEN` and are immediately
|
|
390
|
+
downloadable.
|
|
391
|
+
|
|
392
|
+
| Function | Returns |
|
|
393
|
+
| :--- | :--- |
|
|
394
|
+
| `getMyPlaylists(userId?, nb?, start?)` | the account's own playlists, **including private ones** |
|
|
395
|
+
| `getMyFavoriteTracks(userId?, nb?, start?)` | loved tracks, as downloadable gw tracks |
|
|
396
|
+
| `getMyFavoriteTrackIds()` | every loved track id in one request — for diffing a local library |
|
|
397
|
+
| `getMyFavoriteAlbums` / `getMyFavoriteArtists` | favourited albums / artists |
|
|
398
|
+
| `getMyFavoritePlaylists` / `getMyFavoriteRadios` / `getMyFavoriteShows` | followed playlists / radios / shows |
|
|
399
|
+
| `getTrackMix(sngId, nb?, start?)` | a "more like this" mix seeded from a track — **tokens already attached** |
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
import {getMyPlaylists, getTrackMix, resolveDownloadUrls} from 'gerdur-core';
|
|
403
|
+
|
|
404
|
+
const {data: playlists} = await getMyPlaylists(); // yours, private included
|
|
405
|
+
const {data: mix} = await getTrackMix('3135556', 20); // 20 tracks like this one
|
|
406
|
+
const urls = await resolveDownloadUrls(mix, [9, 3, 1]); // straight to download — no per-track lookup
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
`userId` defaults to the logged-in account. These are account-scoped, so they
|
|
410
|
+
never enter the shared cross-session cache.
|
|
411
|
+
|
|
384
412
|
### Podcasts
|
|
385
413
|
|
|
386
414
|
```ts
|
|
@@ -787,7 +815,10 @@ import type {
|
|
|
787
815
|
|
|
788
816
|
`getUserFlow` · `getUserFavoriteTracks` · `getUserFavoriteAlbums` ·
|
|
789
817
|
`getUserFavoriteArtists` · `getUserPlaylists` · `getUserRadios` ·
|
|
790
|
-
`getUserChartTracks` · `getRadios` · `getRadioTracks` · `getRadioGenres`
|
|
818
|
+
`getUserChartTracks` · `getRadios` · `getRadioTracks` · `getRadioGenres` ·
|
|
819
|
+
`getMyPlaylists` · `getMyFavoriteTracks` · `getMyFavoriteTrackIds` ·
|
|
820
|
+
`getMyFavoriteAlbums` · `getMyFavoriteArtists` · `getMyFavoritePlaylists` ·
|
|
821
|
+
`getMyFavoriteRadios` · `getMyFavoriteShows` · `getTrackMix`
|
|
791
822
|
</details>
|
|
792
823
|
|
|
793
824
|
<details>
|
package/dist/api/index.d.ts
CHANGED
package/dist/api/index.js
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { playlistInfoMinimal, trackType } from '../types';
|
|
2
|
+
/** Envelope the gateway wraps these listings in. */
|
|
3
|
+
export interface GwList<T> {
|
|
4
|
+
data: T[];
|
|
5
|
+
count: number;
|
|
6
|
+
total: number;
|
|
7
|
+
filtered_count?: number;
|
|
8
|
+
checksum?: string;
|
|
9
|
+
}
|
|
10
|
+
/** A favourited artist, as the library returns it. */
|
|
11
|
+
export interface FavoriteArtist {
|
|
12
|
+
ART_ID: string;
|
|
13
|
+
ART_NAME: string;
|
|
14
|
+
ART_PICTURE: string;
|
|
15
|
+
/** when it was favourited — `YYYY-MM-DD HH:MM:SS` */
|
|
16
|
+
DATE_ADD?: string;
|
|
17
|
+
NB_ALBUM?: number;
|
|
18
|
+
NB_FAN?: number;
|
|
19
|
+
ARTIST_IS_DUMMY?: boolean;
|
|
20
|
+
__TYPE__?: string;
|
|
21
|
+
}
|
|
22
|
+
/** A favourited album, as the library returns it. */
|
|
23
|
+
export interface FavoriteAlbum {
|
|
24
|
+
ALB_ID: string;
|
|
25
|
+
ALB_TITLE: string;
|
|
26
|
+
ALB_PICTURE: string;
|
|
27
|
+
ART_ID?: string;
|
|
28
|
+
ART_NAME?: string;
|
|
29
|
+
DATE_ADD?: string;
|
|
30
|
+
NUMBER_TRACK?: number;
|
|
31
|
+
PHYSICAL_RELEASE_DATE?: string;
|
|
32
|
+
__TYPE__?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The account's own playlists (`playlist.getList`) — **including private ones**,
|
|
36
|
+
* which the public `/user/{id}/playlists` endpoint will not show you.
|
|
37
|
+
*
|
|
38
|
+
* @param userId defaults to the logged-in account
|
|
39
|
+
*/
|
|
40
|
+
export declare const getMyPlaylists: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<playlistInfoMinimal>>;
|
|
41
|
+
/**
|
|
42
|
+
* Loved tracks (`song.getFavorites`). Gateway track objects, so each carries a
|
|
43
|
+
* `TRACK_TOKEN` and can go straight to `resolveDownloadUrls`.
|
|
44
|
+
*/
|
|
45
|
+
export declare const getMyFavoriteTracks: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<trackType>>;
|
|
46
|
+
/**
|
|
47
|
+
* Just the ids of every loved track (`song.getFavoriteIds`) — one small request
|
|
48
|
+
* for the whole set, for diffing a local library against the account.
|
|
49
|
+
*/
|
|
50
|
+
export declare const getMyFavoriteTrackIds: () => Promise<GwList<{
|
|
51
|
+
SNG_ID: string;
|
|
52
|
+
}>>;
|
|
53
|
+
/** Favourited albums (`album.getFavorites`). */
|
|
54
|
+
export declare const getMyFavoriteAlbums: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<FavoriteAlbum>>;
|
|
55
|
+
/** Favourited artists (`artist.getFavorites`). */
|
|
56
|
+
export declare const getMyFavoriteArtists: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<FavoriteArtist>>;
|
|
57
|
+
/** Playlists the account follows (`playlist.getFavorites`). */
|
|
58
|
+
export declare const getMyFavoritePlaylists: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<playlistInfoMinimal>>;
|
|
59
|
+
/** Favourited radios (`radio.getFavorites`). */
|
|
60
|
+
export declare const getMyFavoriteRadios: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<Record<string, any>>>;
|
|
61
|
+
/** Favourited podcast shows (`show.getFavorites`). */
|
|
62
|
+
export declare const getMyFavoriteShows: (userId?: string | number, nb?: number, start?: number) => Promise<GwList<Record<string, any>>>;
|
|
63
|
+
/**
|
|
64
|
+
* A "more like this" mix seeded from one track (`song.getSearchTrackMix`).
|
|
65
|
+
*
|
|
66
|
+
* Returns full gateway tracks **with `TRACK_TOKEN`s**, so unlike the public
|
|
67
|
+
* radio endpoints the results are immediately downloadable — no `getTrackInfo`
|
|
68
|
+
* round trip per hit.
|
|
69
|
+
*
|
|
70
|
+
* @param sngId the seed track's `SNG_ID`
|
|
71
|
+
*/
|
|
72
|
+
export declare const getTrackMix: (sngId: string, nb?: number, start?: number) => Promise<GwList<trackType>>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTrackMix = exports.getMyFavoriteShows = exports.getMyFavoriteRadios = exports.getMyFavoritePlaylists = exports.getMyFavoriteArtists = exports.getMyFavoriteAlbums = exports.getMyFavoriteTrackIds = exports.getMyFavoriteTracks = exports.getMyPlaylists = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The **logged-in account's own library**, over the authenticated gateway.
|
|
6
|
+
*
|
|
7
|
+
* This is not the same surface as `src/api/user.ts`. Those functions read the
|
|
8
|
+
* *public* REST profile (`/user/{id}/tracks` …), which needs the profile to be
|
|
9
|
+
* public and shows only what that profile exposes. These read what the account
|
|
10
|
+
* itself can see — including a private library — and return gateway shapes, so
|
|
11
|
+
* tracks arrive with a `TRACK_TOKEN` and are directly downloadable.
|
|
12
|
+
*
|
|
13
|
+
* Every response here is account-scoped, so it lives in the per-session cache
|
|
14
|
+
* and is never shared between sessions.
|
|
15
|
+
*/
|
|
16
|
+
const request_1 = require("./request");
|
|
17
|
+
const api_1 = require("./api");
|
|
18
|
+
/** Resolve the caller's own user id when one wasn't supplied. */
|
|
19
|
+
const ownUserId = async (userId) => userId !== undefined ? String(userId) : String((await (0, api_1.getUser)()).USER_ID);
|
|
20
|
+
/**
|
|
21
|
+
* The account's own playlists (`playlist.getList`) — **including private ones**,
|
|
22
|
+
* which the public `/user/{id}/playlists` endpoint will not show you.
|
|
23
|
+
*
|
|
24
|
+
* @param userId defaults to the logged-in account
|
|
25
|
+
*/
|
|
26
|
+
const getMyPlaylists = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start, tab: 'all' }, 'playlist.getList');
|
|
27
|
+
exports.getMyPlaylists = getMyPlaylists;
|
|
28
|
+
/**
|
|
29
|
+
* Loved tracks (`song.getFavorites`). Gateway track objects, so each carries a
|
|
30
|
+
* `TRACK_TOKEN` and can go straight to `resolveDownloadUrls`.
|
|
31
|
+
*/
|
|
32
|
+
const getMyFavoriteTracks = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start }, 'song.getFavorites');
|
|
33
|
+
exports.getMyFavoriteTracks = getMyFavoriteTracks;
|
|
34
|
+
/**
|
|
35
|
+
* Just the ids of every loved track (`song.getFavoriteIds`) — one small request
|
|
36
|
+
* for the whole set, for diffing a local library against the account.
|
|
37
|
+
*/
|
|
38
|
+
const getMyFavoriteTrackIds = () => (0, request_1.request)({}, 'song.getFavoriteIds');
|
|
39
|
+
exports.getMyFavoriteTrackIds = getMyFavoriteTrackIds;
|
|
40
|
+
/** Favourited albums (`album.getFavorites`). */
|
|
41
|
+
const getMyFavoriteAlbums = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start }, 'album.getFavorites');
|
|
42
|
+
exports.getMyFavoriteAlbums = getMyFavoriteAlbums;
|
|
43
|
+
/** Favourited artists (`artist.getFavorites`). */
|
|
44
|
+
const getMyFavoriteArtists = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start }, 'artist.getFavorites');
|
|
45
|
+
exports.getMyFavoriteArtists = getMyFavoriteArtists;
|
|
46
|
+
/** Playlists the account follows (`playlist.getFavorites`). */
|
|
47
|
+
const getMyFavoritePlaylists = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start }, 'playlist.getFavorites');
|
|
48
|
+
exports.getMyFavoritePlaylists = getMyFavoritePlaylists;
|
|
49
|
+
/** Favourited radios (`radio.getFavorites`). */
|
|
50
|
+
const getMyFavoriteRadios = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start }, 'radio.getFavorites');
|
|
51
|
+
exports.getMyFavoriteRadios = getMyFavoriteRadios;
|
|
52
|
+
/** Favourited podcast shows (`show.getFavorites`). */
|
|
53
|
+
const getMyFavoriteShows = async (userId, nb = 50, start = 0) => (0, request_1.request)({ user_id: await ownUserId(userId), nb, start }, 'show.getFavorites');
|
|
54
|
+
exports.getMyFavoriteShows = getMyFavoriteShows;
|
|
55
|
+
/**
|
|
56
|
+
* A "more like this" mix seeded from one track (`song.getSearchTrackMix`).
|
|
57
|
+
*
|
|
58
|
+
* Returns full gateway tracks **with `TRACK_TOKEN`s**, so unlike the public
|
|
59
|
+
* radio endpoints the results are immediately downloadable — no `getTrackInfo`
|
|
60
|
+
* round trip per hit.
|
|
61
|
+
*
|
|
62
|
+
* @param sngId the seed track's `SNG_ID`
|
|
63
|
+
*/
|
|
64
|
+
const getTrackMix = (sngId, nb = 40, start = 0) => (0, request_1.request)({ sng_id: sngId, start, nb }, 'song.getSearchTrackMix');
|
|
65
|
+
exports.getTrackMix = getTrackMix;
|
package/package.json
CHANGED