gerdur-core 2.1.0 → 2.2.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 +20 -0
- package/README.md +35 -0
- package/dist/api/browse.d.ts +49 -0
- package/dist/api/browse.js +82 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/types/browse.d.ts +85 -0
- package/dist/types/browse.js +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.0 - 2026-08-31
|
|
4
|
+
|
|
5
|
+
Phase 2.4 — browse & discovery. All additive, all on the public REST API (no
|
|
6
|
+
`arl` needed), all memoised.
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **Charts / editorial**: `getGenres`, `getChart(genreId, limit)` (the five
|
|
11
|
+
ranked lists), `getChartTracks`, `getGenreArtists`, `getEditorialList`,
|
|
12
|
+
`getEditorialReleases`, `getEditorialSelection`, `getEditorialCharts`.
|
|
13
|
+
- **Artist discovery**: `getArtistTopTracks`, `getRelatedArtists`,
|
|
14
|
+
`getArtistAlbums`, `getArtistPlaylists`, `getArtistRadioTracks`.
|
|
15
|
+
- **ISRC / UPC resolution**: `getTrackByISRC(isrc)` and `getAlbumByUPC(upc)` —
|
|
16
|
+
raw public-API track/album (with `bpm`, `gain`, `preview`, embedded `tracks`).
|
|
17
|
+
Complements the converter's `isrc2deezer` / `upc2deezer`, which hydrate a gw
|
|
18
|
+
track instead.
|
|
19
|
+
- New exported types: `chartType`, `chartTrack`/`chartAlbum`/`chartArtist`/
|
|
20
|
+
`chartPlaylist`/`chartPodcast`, `genreType`, `editorialType`,
|
|
21
|
+
`artistAlbumResult`, `publicApiList<T>`.
|
|
22
|
+
|
|
3
23
|
## 2.1.0 - 2026-08-31
|
|
4
24
|
|
|
5
25
|
Phase 2.5 — search, properly. All additive.
|
package/README.md
CHANGED
|
@@ -196,6 +196,41 @@ ignore the operators, so pass a plain string there.
|
|
|
196
196
|
"as you type" UIs. `nb` (default 5) caps items per type. Needs an initialised
|
|
197
197
|
session (`initDeezerApi`).
|
|
198
198
|
|
|
199
|
+
### Browse & discovery
|
|
200
|
+
|
|
201
|
+
Public REST endpoints — no `arl` needed, memoised like the rest. All return a
|
|
202
|
+
`{data, total?, next?}` list unless noted.
|
|
203
|
+
|
|
204
|
+
| Method | Returns |
|
|
205
|
+
| :--- | :--- |
|
|
206
|
+
| `getGenres()` | Deezer's genre list (`id` `0` = "All"). |
|
|
207
|
+
| `getChart(genreId = 0, limit = 10)` | `{tracks, albums, artists, playlists, podcasts}` — the ranked lists for a genre. |
|
|
208
|
+
| `getChartTracks(genreId = 0, limit = 100, index = 0)` | just the track chart, each with a `position`. |
|
|
209
|
+
| `getGenreArtists(genreId)` | artists filed under a genre. |
|
|
210
|
+
| `getEditorialList()` | Deezer's editorial sections. |
|
|
211
|
+
| `getEditorialReleases(editorialId = 0, limit = 25, index = 0)` | new releases for a section. |
|
|
212
|
+
| `getEditorialSelection(editorialId = 0)` | albums the editors are pushing. |
|
|
213
|
+
| `getEditorialCharts(editorialId = 0)` | a section's charts (same 5-list shape as `getChart`). |
|
|
214
|
+
| `getArtistTopTracks(artistId, limit = 50)` | an artist's most popular tracks. |
|
|
215
|
+
| `getRelatedArtists(artistId, limit = 20)` | similar / related artists. |
|
|
216
|
+
| `getArtistAlbums(artistId, limit = 50, index = 0)` | the artist's discography. |
|
|
217
|
+
| `getArtistPlaylists(artistId, limit = 25)` | playlists featuring the artist. |
|
|
218
|
+
| `getArtistRadioTracks(artistId)` | a ready-made radio seeded from the artist. |
|
|
219
|
+
| `getTrackByISRC(isrc)` | the public-API track for an ISRC (`bpm`, `gain`, `preview`, …). |
|
|
220
|
+
| `getAlbumByUPC(upc)` | the public-API album (with its `tracks`) for a UPC/EAN barcode. |
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
const {data: genres} = await getGenres();
|
|
224
|
+
const rock = genres.find((g) => g.name === 'Rock');
|
|
225
|
+
const {tracks} = await getChart(rock.id, 20); // this week's rock chart
|
|
226
|
+
const similar = await getRelatedArtists(27); // artists like Daft Punk
|
|
227
|
+
const track = await getTrackByISRC('USUM71311296'); // "Get Lucky"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`getTrackByISRC` / `getAlbumByUPC` return raw public-API objects. To download,
|
|
231
|
+
pass the `id` to `getTrackInfo` / `getAlbumTracks` (or use the converter's
|
|
232
|
+
`isrc2deezer` / `upc2deezer`, which hydrate a gw track for you).
|
|
233
|
+
|
|
199
234
|
### `.getTrackDownloadUrl(track, quality);`
|
|
200
235
|
|
|
201
236
|
| Parameters | Required | Type | Description |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { albumTypePublicApi, artistAlbumResult, chartType, editorialType, genreType, publicApiList, searchResultArtist, searchResultPlaylist, searchResultTrack, trackTypePublicApi } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* The five ranked lists Deezer publishes for a genre: `tracks`, `albums`,
|
|
4
|
+
* `artists`, `playlists`, `podcasts`. `genreId` `0` (the default) is "all
|
|
5
|
+
* genres"; other ids come from {@link getGenres}.
|
|
6
|
+
*/
|
|
7
|
+
export declare const getChart: (genreId?: number | string, limit?: number) => Promise<chartType>;
|
|
8
|
+
/** Just the track chart for a genre (`0` = all). Handy as a ready-to-play list. */
|
|
9
|
+
export declare const getChartTracks: (genreId?: number | string, limit?: number, index?: number) => Promise<publicApiList<searchResultTrack & {
|
|
10
|
+
position: number;
|
|
11
|
+
}>>;
|
|
12
|
+
/** Deezer's genre list — the `id`s feed {@link getChart}, {@link getGenreArtists}, advanced search. */
|
|
13
|
+
export declare const getGenres: () => Promise<publicApiList<genreType>>;
|
|
14
|
+
/** Artists Deezer files under a genre. */
|
|
15
|
+
export declare const getGenreArtists: (genreId: number | string) => Promise<publicApiList<searchResultArtist>>;
|
|
16
|
+
/** Deezer's editorial sections (the `id`s feed {@link getEditorialReleases} / {@link getEditorialSelection}). */
|
|
17
|
+
export declare const getEditorialList: () => Promise<publicApiList<editorialType>>;
|
|
18
|
+
/** New releases for an editorial section (`0` = the default section). */
|
|
19
|
+
export declare const getEditorialReleases: (editorialId?: number | string, limit?: number, index?: number) => Promise<publicApiList<artistAlbumResult>>;
|
|
20
|
+
/** The albums Deezer's editors are currently pushing for a section. */
|
|
21
|
+
export declare const getEditorialSelection: (editorialId?: number | string) => Promise<publicApiList<artistAlbumResult>>;
|
|
22
|
+
/** The editorial charts for a section — same five-list shape as {@link getChart}. */
|
|
23
|
+
export declare const getEditorialCharts: (editorialId?: number | string) => Promise<chartType>;
|
|
24
|
+
/** An artist's most popular tracks. */
|
|
25
|
+
export declare const getArtistTopTracks: (artistId: number | string, limit?: number) => Promise<publicApiList<searchResultTrack>>;
|
|
26
|
+
/** Artists Deezer considers related / similar. */
|
|
27
|
+
export declare const getRelatedArtists: (artistId: number | string, limit?: number) => Promise<publicApiList<searchResultArtist>>;
|
|
28
|
+
/** An artist's discography (public-API album shape). */
|
|
29
|
+
export declare const getArtistAlbums: (artistId: number | string, limit?: number, index?: number) => Promise<publicApiList<artistAlbumResult>>;
|
|
30
|
+
/** Playlists featuring an artist. */
|
|
31
|
+
export declare const getArtistPlaylists: (artistId: number | string, limit?: number) => Promise<publicApiList<searchResultPlaylist>>;
|
|
32
|
+
/** A ready-made radio (track list) seeded from an artist. */
|
|
33
|
+
export declare const getArtistRadioTracks: (artistId: number | string) => Promise<publicApiList<searchResultTrack>>;
|
|
34
|
+
/**
|
|
35
|
+
* Resolve an ISRC to the Deezer **public-API** track (with `bpm`, `gain`,
|
|
36
|
+
* `isrc`, `preview`, `contributors`). Unlike the converter's `isrc2deezer`, this
|
|
37
|
+
* does not hydrate a gw track — pass `result.id` to `getTrackInfo` for that.
|
|
38
|
+
*
|
|
39
|
+
* @throws when Deezer has no track for the code
|
|
40
|
+
*/
|
|
41
|
+
export declare const getTrackByISRC: (isrc: string) => Promise<trackTypePublicApi>;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a UPC / EAN barcode to the Deezer **public-API** album (with its
|
|
44
|
+
* `tracks`). A 13-digit barcode with a leading `0` is trimmed to 12, matching
|
|
45
|
+
* Deezer's own lookup.
|
|
46
|
+
*
|
|
47
|
+
* @throws when Deezer has no album for the code
|
|
48
|
+
*/
|
|
49
|
+
export declare const getAlbumByUPC: (upc: string) => Promise<albumTypePublicApi>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAlbumByUPC = exports.getTrackByISRC = exports.getArtistRadioTracks = exports.getArtistPlaylists = exports.getArtistAlbums = exports.getRelatedArtists = exports.getArtistTopTracks = exports.getEditorialCharts = exports.getEditorialSelection = exports.getEditorialReleases = exports.getEditorialList = exports.getGenreArtists = exports.getGenres = exports.getChartTracks = exports.getChart = 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
|
+
// ─── Charts ──────────────────────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* The five ranked lists Deezer publishes for a genre: `tracks`, `albums`,
|
|
18
|
+
* `artists`, `playlists`, `podcasts`. `genreId` `0` (the default) is "all
|
|
19
|
+
* genres"; other ids come from {@link getGenres}.
|
|
20
|
+
*/
|
|
21
|
+
const getChart = (genreId = 0, limit = 10) => (0, request_1.requestPublicApi)(withParams(`/chart/${genreId}`, { limit }));
|
|
22
|
+
exports.getChart = getChart;
|
|
23
|
+
/** Just the track chart for a genre (`0` = all). Handy as a ready-to-play list. */
|
|
24
|
+
const getChartTracks = (genreId = 0, limit = 100, index = 0) => (0, request_1.requestPublicApi)(withParams(`/chart/${genreId}/tracks`, { limit, index }));
|
|
25
|
+
exports.getChartTracks = getChartTracks;
|
|
26
|
+
// ─── Genres & editorial ──────────────────────────────────────────────────────
|
|
27
|
+
/** Deezer's genre list — the `id`s feed {@link getChart}, {@link getGenreArtists}, advanced search. */
|
|
28
|
+
const getGenres = () => (0, request_1.requestPublicApi)('/genre');
|
|
29
|
+
exports.getGenres = getGenres;
|
|
30
|
+
/** Artists Deezer files under a genre. */
|
|
31
|
+
const getGenreArtists = (genreId) => (0, request_1.requestPublicApi)(`/genre/${genreId}/artists`);
|
|
32
|
+
exports.getGenreArtists = getGenreArtists;
|
|
33
|
+
/** Deezer's editorial sections (the `id`s feed {@link getEditorialReleases} / {@link getEditorialSelection}). */
|
|
34
|
+
const getEditorialList = () => (0, request_1.requestPublicApi)('/editorial');
|
|
35
|
+
exports.getEditorialList = getEditorialList;
|
|
36
|
+
/** New releases for an editorial section (`0` = the default section). */
|
|
37
|
+
const getEditorialReleases = (editorialId = 0, limit = 25, index = 0) => (0, request_1.requestPublicApi)(withParams(`/editorial/${editorialId}/releases`, { limit, index }));
|
|
38
|
+
exports.getEditorialReleases = getEditorialReleases;
|
|
39
|
+
/** The albums Deezer's editors are currently pushing for a section. */
|
|
40
|
+
const getEditorialSelection = (editorialId = 0) => (0, request_1.requestPublicApi)(`/editorial/${editorialId}/selection`);
|
|
41
|
+
exports.getEditorialSelection = getEditorialSelection;
|
|
42
|
+
/** The editorial charts for a section — same five-list shape as {@link getChart}. */
|
|
43
|
+
const getEditorialCharts = (editorialId = 0) => (0, request_1.requestPublicApi)(`/editorial/${editorialId}/charts`);
|
|
44
|
+
exports.getEditorialCharts = getEditorialCharts;
|
|
45
|
+
// ─── Artist discovery ────────────────────────────────────────────────────────
|
|
46
|
+
/** An artist's most popular tracks. */
|
|
47
|
+
const getArtistTopTracks = (artistId, limit = 50) => (0, request_1.requestPublicApi)(withParams(`/artist/${artistId}/top`, { limit }));
|
|
48
|
+
exports.getArtistTopTracks = getArtistTopTracks;
|
|
49
|
+
/** Artists Deezer considers related / similar. */
|
|
50
|
+
const getRelatedArtists = (artistId, limit = 20) => (0, request_1.requestPublicApi)(withParams(`/artist/${artistId}/related`, { limit }));
|
|
51
|
+
exports.getRelatedArtists = getRelatedArtists;
|
|
52
|
+
/** An artist's discography (public-API album shape). */
|
|
53
|
+
const getArtistAlbums = (artistId, limit = 50, index = 0) => (0, request_1.requestPublicApi)(withParams(`/artist/${artistId}/albums`, { limit, index }));
|
|
54
|
+
exports.getArtistAlbums = getArtistAlbums;
|
|
55
|
+
/** Playlists featuring an artist. */
|
|
56
|
+
const getArtistPlaylists = (artistId, limit = 25) => (0, request_1.requestPublicApi)(withParams(`/artist/${artistId}/playlists`, { limit }));
|
|
57
|
+
exports.getArtistPlaylists = getArtistPlaylists;
|
|
58
|
+
/** A ready-made radio (track list) seeded from an artist. */
|
|
59
|
+
const getArtistRadioTracks = (artistId) => (0, request_1.requestPublicApi)(`/artist/${artistId}/radio`);
|
|
60
|
+
exports.getArtistRadioTracks = getArtistRadioTracks;
|
|
61
|
+
// ─── ISRC / UPC resolution ───────────────────────────────────────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Resolve an ISRC to the Deezer **public-API** track (with `bpm`, `gain`,
|
|
64
|
+
* `isrc`, `preview`, `contributors`). Unlike the converter's `isrc2deezer`, this
|
|
65
|
+
* does not hydrate a gw track — pass `result.id` to `getTrackInfo` for that.
|
|
66
|
+
*
|
|
67
|
+
* @throws when Deezer has no track for the code
|
|
68
|
+
*/
|
|
69
|
+
const getTrackByISRC = (isrc) => (0, request_1.requestPublicApi)(`/track/isrc:${encodeURIComponent(isrc)}`);
|
|
70
|
+
exports.getTrackByISRC = getTrackByISRC;
|
|
71
|
+
/**
|
|
72
|
+
* Resolve a UPC / EAN barcode to the Deezer **public-API** album (with its
|
|
73
|
+
* `tracks`). A 13-digit barcode with a leading `0` is trimmed to 12, matching
|
|
74
|
+
* Deezer's own lookup.
|
|
75
|
+
*
|
|
76
|
+
* @throws when Deezer has no album for the code
|
|
77
|
+
*/
|
|
78
|
+
const getAlbumByUPC = (upc) => {
|
|
79
|
+
const code = upc.length > 12 && upc.startsWith('0') ? upc.slice(-12) : upc;
|
|
80
|
+
return (0, request_1.requestPublicApi)(`/album/upc:${encodeURIComponent(code)}`);
|
|
81
|
+
};
|
|
82
|
+
exports.getAlbumByUPC = getAlbumByUPC;
|
package/dist/api/index.d.ts
CHANGED
package/dist/api/index.js
CHANGED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { searchResultAlbum, searchResultArtist, searchResultPlaylist, searchResultTrack } from './search';
|
|
2
|
+
/** The `{data, total, next?, prev?}` envelope every paginated public-API list uses. */
|
|
3
|
+
export interface publicApiList<T> {
|
|
4
|
+
data: T[];
|
|
5
|
+
total?: number;
|
|
6
|
+
/** absolute URL of the next page, when there is one */
|
|
7
|
+
next?: string;
|
|
8
|
+
prev?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface chartTrack extends searchResultTrack {
|
|
11
|
+
/** 1-based position in the chart */
|
|
12
|
+
position: number;
|
|
13
|
+
}
|
|
14
|
+
export interface chartArtist extends searchResultArtist {
|
|
15
|
+
position: number;
|
|
16
|
+
}
|
|
17
|
+
export interface chartAlbum extends searchResultAlbum {
|
|
18
|
+
position: number;
|
|
19
|
+
}
|
|
20
|
+
export interface chartPlaylist extends searchResultPlaylist {
|
|
21
|
+
position: number;
|
|
22
|
+
}
|
|
23
|
+
export interface chartPodcast {
|
|
24
|
+
id: number;
|
|
25
|
+
title: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
available?: boolean;
|
|
28
|
+
fans?: number;
|
|
29
|
+
link?: string;
|
|
30
|
+
share?: string;
|
|
31
|
+
picture: string;
|
|
32
|
+
picture_small?: string;
|
|
33
|
+
picture_medium?: string;
|
|
34
|
+
picture_big?: string;
|
|
35
|
+
picture_xl?: string;
|
|
36
|
+
position: number;
|
|
37
|
+
type: 'podcast';
|
|
38
|
+
}
|
|
39
|
+
/** `/chart/{genreId}` — the five ranked lists Deezer publishes per genre (`0` = all genres). */
|
|
40
|
+
export interface chartType {
|
|
41
|
+
tracks: publicApiList<chartTrack>;
|
|
42
|
+
albums: publicApiList<chartAlbum>;
|
|
43
|
+
artists: publicApiList<chartArtist>;
|
|
44
|
+
playlists: publicApiList<chartPlaylist>;
|
|
45
|
+
podcasts: publicApiList<chartPodcast>;
|
|
46
|
+
}
|
|
47
|
+
export interface genreType {
|
|
48
|
+
id: number;
|
|
49
|
+
name: string;
|
|
50
|
+
picture: string;
|
|
51
|
+
picture_small?: string;
|
|
52
|
+
picture_medium?: string;
|
|
53
|
+
picture_big?: string;
|
|
54
|
+
picture_xl?: string;
|
|
55
|
+
type: 'genre';
|
|
56
|
+
}
|
|
57
|
+
export interface editorialType {
|
|
58
|
+
id: number;
|
|
59
|
+
name: string;
|
|
60
|
+
picture: string;
|
|
61
|
+
picture_small?: string;
|
|
62
|
+
picture_medium?: string;
|
|
63
|
+
picture_big?: string;
|
|
64
|
+
picture_xl?: string;
|
|
65
|
+
type: 'editorial';
|
|
66
|
+
}
|
|
67
|
+
/** An album from `/artist/{id}/albums` — the artist's own discography, public-API shape. */
|
|
68
|
+
export interface artistAlbumResult {
|
|
69
|
+
id: number;
|
|
70
|
+
title: string;
|
|
71
|
+
link: string;
|
|
72
|
+
cover: string;
|
|
73
|
+
cover_small?: string;
|
|
74
|
+
cover_medium?: string;
|
|
75
|
+
cover_big?: string;
|
|
76
|
+
cover_xl?: string;
|
|
77
|
+
md5_image: string;
|
|
78
|
+
genre_id: number;
|
|
79
|
+
fans?: number;
|
|
80
|
+
release_date: string;
|
|
81
|
+
record_type: string;
|
|
82
|
+
tracklist: string;
|
|
83
|
+
explicit_lyrics: boolean;
|
|
84
|
+
type: 'album';
|
|
85
|
+
}
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./album"), exports);
|
|
18
18
|
__exportStar(require("./artist"), exports);
|
|
19
|
+
__exportStar(require("./browse"), exports);
|
|
19
20
|
__exportStar(require("./show"), exports);
|
|
20
21
|
__exportStar(require("./playlist"), exports);
|
|
21
22
|
__exportStar(require("./playlist-channel"), exports);
|