gerdur-core 0.0.0-probe → 1.0.1

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE +0 -0
  3. package/README.md +186 -1
  4. package/dist/api/api.d.ts +78 -0
  5. package/dist/api/api.js +182 -0
  6. package/dist/api/cache.d.ts +3 -0
  7. package/dist/api/cache.js +12 -0
  8. package/dist/api/index.d.ts +2 -0
  9. package/dist/api/index.js +18 -0
  10. package/dist/api/request.d.ts +23 -0
  11. package/dist/api/request.js +88 -0
  12. package/dist/converter/deezer.d.ts +3 -0
  13. package/dist/converter/deezer.js +45 -0
  14. package/dist/converter/index.d.ts +5 -0
  15. package/dist/converter/index.js +34 -0
  16. package/dist/converter/parse.d.ts +18 -0
  17. package/dist/converter/parse.js +176 -0
  18. package/dist/converter/spotify.d.ts +40 -0
  19. package/dist/converter/spotify.js +154 -0
  20. package/dist/converter/tidal.d.ts +146 -0
  21. package/dist/converter/tidal.js +199 -0
  22. package/dist/converter/youtube.d.ts +6 -0
  23. package/dist/converter/youtube.js +102 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +24 -0
  26. package/dist/lib/decrypt.d.ts +9 -0
  27. package/dist/lib/decrypt.js +63 -0
  28. package/dist/lib/fast-lru.d.ts +63 -0
  29. package/dist/lib/fast-lru.js +121 -0
  30. package/dist/lib/get-url.d.ts +16 -0
  31. package/dist/lib/get-url.js +154 -0
  32. package/dist/lib/http.d.ts +66 -0
  33. package/dist/lib/http.js +235 -0
  34. package/dist/lib/metaflac-js.d.ts +124 -0
  35. package/dist/lib/metaflac-js.js +343 -0
  36. package/dist/lib/request.d.ts +18 -0
  37. package/dist/lib/request.js +86 -0
  38. package/dist/metadata-writer/abumCover.d.ts +10 -0
  39. package/dist/metadata-writer/abumCover.js +37 -0
  40. package/dist/metadata-writer/flacmetata.d.ts +3 -0
  41. package/dist/metadata-writer/flacmetata.js +80 -0
  42. package/dist/metadata-writer/getTrackLyrics.d.ts +2 -0
  43. package/dist/metadata-writer/getTrackLyrics.js +26 -0
  44. package/dist/metadata-writer/id3.d.ts +3 -0
  45. package/dist/metadata-writer/id3.js +119 -0
  46. package/dist/metadata-writer/index.d.ts +9 -0
  47. package/dist/metadata-writer/index.js +44 -0
  48. package/dist/metadata-writer/musixmatchLyrics.d.ts +1 -0
  49. package/dist/metadata-writer/musixmatchLyrics.js +39 -0
  50. package/dist/metadata-writer/useragents.d.ts +1 -0
  51. package/dist/metadata-writer/useragents.js +86 -0
  52. package/dist/types/album.d.ts +123 -0
  53. package/dist/types/album.js +2 -0
  54. package/dist/types/artist.d.ts +36 -0
  55. package/dist/types/artist.js +2 -0
  56. package/dist/types/channel.d.ts +33 -0
  57. package/dist/types/channel.js +2 -0
  58. package/dist/types/index.d.ts +10 -0
  59. package/dist/types/index.js +26 -0
  60. package/dist/types/playlist-channel.d.ts +81 -0
  61. package/dist/types/playlist-channel.js +2 -0
  62. package/dist/types/playlist.d.ts +49 -0
  63. package/dist/types/playlist.js +2 -0
  64. package/dist/types/profile.d.ts +29 -0
  65. package/dist/types/profile.js +2 -0
  66. package/dist/types/radio.d.ts +7 -0
  67. package/dist/types/radio.js +2 -0
  68. package/dist/types/search.d.ts +79 -0
  69. package/dist/types/search.js +2 -0
  70. package/dist/types/show.d.ts +61 -0
  71. package/dist/types/show.js +2 -0
  72. package/dist/types/tracks.d.ts +144 -0
  73. package/dist/types/tracks.js +2 -0
  74. package/dist/types/user.d.ts +16 -0
  75. package/dist/types/user.js +2 -0
  76. package/package.json +67 -5
  77. package/types/index.d.ts +1 -0
  78. package/types/index.js +3 -0
  79. package/types/package.json +4 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## 1.0.1 - 2026-08-30
4
+
5
+ Initial public release.
6
+
7
+ - Deezer gateway client with transparent token refresh and rate-limit backoff, on a dependency-light internal HTTP transport.
8
+ - Spotify / Tidal / YouTube URL resolution to Deezer tracks via ISRC and UPC matching.
9
+ - Blowfish stripe decryption (`decryptDownload`), download-URL resolution with licence and geo checks (`getTrackDownloadUrl`), ID3 / FLAC metadata writing (`addTrackTags`).
10
+ - Shared TypeScript types, also published as the `gerdur-core/types` subpath.
package/LICENSE ADDED
File without changes
package/README.md CHANGED
@@ -1,3 +1,188 @@
1
1
  # gerdur-core
2
2
 
3
- Name probe. Real release to follow.
3
+ The engine behind [`gerdur`](https://github.com/soulwax/gerdur): the streaming-service API clients, URL resolution, track decryption, and metadata tagging. Also used across the darkfloor / hexmusic services.
4
+
5
+ Source: <https://github.com/soulwax/gerdur-core> · npm: <https://www.npmjs.com/package/gerdur-core>
6
+
7
+ ## Why *gerdur*?
8
+
9
+ **Gerðr** is the jötunn Freyr sends his servant Skírnir riding through a wall of fire to fetch; her name, *garðr*, means "the enclosure, the walled garden" (cf. English *garden*). `gerdur-core` does the crossing — resolving identifiers, getting past the wall, decrypting the stream, and handing back a finished, tagged track. The [`gerdur`](https://github.com/soulwax/gerdur) CLI is a thin shell around it.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm i gerdur-core
15
+ ```
16
+
17
+ ```bash
18
+ yarn add gerdur-core
19
+ ```
20
+
21
+ ```bash
22
+ pnpm add gerdur-core
23
+ ```
24
+
25
+ Type declarations are also published under the `gerdur-core/types` subpath for consumers that want to import the shared library types directly.
26
+
27
+ ## Usage
28
+
29
+ Here's a simple example to download tracks.
30
+
31
+ ```ts
32
+ import fs from 'fs';
33
+ import {get} from 'https';
34
+ import * as api from 'gerdur-core';
35
+
36
+ const downloadBuffer = (url: string) =>
37
+ new Promise<Buffer>((resolve, reject) => {
38
+ get(url, (response) => {
39
+ const chunks: Buffer[] = [];
40
+ response.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
41
+ response.on('end', () => resolve(Buffer.concat(chunks)));
42
+ response.on('error', reject);
43
+ }).on('error', reject);
44
+ });
45
+
46
+ // Init api with arl from cookie
47
+ await api.initDeezerApi(arl_cookie);
48
+
49
+ // Verify user
50
+ try {
51
+ const user = await api.getUser();
52
+ // Successfully logged in
53
+ console.log('Logged in as ' + user.BLOG_NAME);
54
+ } catch (err) {
55
+ // Invalid arl cookie set
56
+ console.error(err.message);
57
+ }
58
+
59
+ // GET Track Object
60
+ const track = await api.getTrackInfo(song_id);
61
+
62
+ // Parse download URL for 128kbps
63
+ const trackData = await api.getTrackDownloadUrl(track, 1);
64
+
65
+ // Download track
66
+ const data = await downloadBuffer(trackData.trackUrl);
67
+
68
+ // Decrypt track if needed
69
+ const outFile = trackData.isEncrypted ? api.decryptDownload(data, track.SNG_ID) : data;
70
+
71
+ // Add id3 metadata
72
+ const trackWithMetadata = await api.addTrackTags(outFile, track, 500);
73
+
74
+ // Save file to disk
75
+ fs.writeFileSync(track.SNG_TITLE + '.mp3', trackWithMetadata);
76
+ ```
77
+
78
+ ### [Read FAQ](docs/faq.md)
79
+
80
+ ## Methods
81
+
82
+ All method returns `Object` or throws `Error`. Make sure to catch error on your side.
83
+
84
+ ### `.initDeezerApi(arl_cookie);`
85
+
86
+ > It is recommended that you first init the app with this method using your arl cookie.
87
+
88
+ | Parameters | Required | Type |
89
+ | ------------ | :------: | -------: |
90
+ | `arl_cookie` | Yes | `string` |
91
+
92
+ ### `.getTrackInfo(track_id);`
93
+
94
+ | Parameters | Required | Type |
95
+ | ---------- | :------: | -------: |
96
+ | `track_id` | Yes | `string` |
97
+
98
+ ### `.getLyrics(track_id);`
99
+
100
+ | Parameters | Required | Type |
101
+ | ---------- | :------: | -------: |
102
+ | `track_id` | Yes | `string` |
103
+
104
+ ### `.getAlbumInfo(album_id);`
105
+
106
+ | Parameters | Required | Type |
107
+ | ---------- | :------: | -------: |
108
+ | `album_id` | Yes | `string` |
109
+
110
+ ### `.getAlbumTracks(album_id);`
111
+
112
+ | Parameters | Required | Type |
113
+ | ---------- | :------: | -------: |
114
+ | `album_id` | Yes | `string` |
115
+
116
+ ### `.getPlaylistInfo(playlist_id);`
117
+
118
+ | Parameters | Required | Type |
119
+ | ------------- | :------: | -------: |
120
+ | `playlist_id` | Yes | `string` |
121
+
122
+ ### `.getPlaylistTracks(playlist_id);`
123
+
124
+ | Parameters | Required | Type |
125
+ | ------------- | :------: | -------: |
126
+ | `playlist_id` | Yes | `string` |
127
+
128
+ ### `.getArtistInfo(artist_id);`
129
+
130
+ | Parameters | Required | Type |
131
+ | ----------- | :------: | -------: |
132
+ | `artist_id` | Yes | `string` |
133
+
134
+ ### `.getDiscography(artist_id, limit);`
135
+
136
+ | Parameters | Required | Type | Default | Description |
137
+ | ----------- | :------: | -------: | ------: | ----------------------: |
138
+ | `artist_id` | Yes | `string` | - | artist id |
139
+ | `limit` | No | `number` | 500 | maximum tracks to fetch |
140
+
141
+ ### `.getProfile(user_id);`
142
+
143
+ | Parameters | Required | Type |
144
+ | ---------- | :------: | -------: |
145
+ | `user_id` | Yes | `string` |
146
+
147
+ ### `.searchAlternative(artist_name, song_name);`
148
+
149
+ | Parameters | Required | Type |
150
+ | ------------- | :------: | -------: |
151
+ | `artist_name` | Yes | `string` |
152
+ | `song_name` | Yes | `string` |
153
+
154
+ ### `.searchMusic(query, types, limit);`
155
+
156
+ | Parameters | Required | Type | Default | Description |
157
+ | ---------- | :------: | -------: | --------: | ------------------------------: |
158
+ | `query` | Yes | `string` | - | search query |
159
+ | `types` | No | `array` | ['TRACK'] | array of search types |
160
+ | `limit` | No | `number` | 15 | maximum item to fetch per types |
161
+
162
+ ### `.getTrackDownloadUrl(track, quality);`
163
+
164
+ | Parameters | Required | Type | Description |
165
+ | ---------- | :------: | ----------: | ---------------------------------: |
166
+ | `track` | Yes | `string` | track object |
167
+ | `quality` | Yes | `1, 3 or 9` | 1 = 128kbps, 3 = 320kbps, 9 = flac |
168
+
169
+ ### `.decryptDownload(data, song_id);`
170
+
171
+ | Parameters | Required | Type | Description |
172
+ | ---------- | :------: | -------: | ---------------------: |
173
+ | `data` | Yes | `buffer` | downloaded song buffer |
174
+ | `song_id` | Yes | `string` | track id |
175
+
176
+ ### `.addTrackTags(data, track,coverSize)`
177
+
178
+ | Parameters | Required | Type | Description |
179
+ | ----------- | :------: | --------: | ---------------------: |
180
+ | `data` | Yes | `buffer` | downloaded song buffer |
181
+ | `track` | Yes | `string` | track object |
182
+ | `coverSize` | No | `56-1800` | cover art size |
183
+
184
+ ###
185
+
186
+ > We are not responsible for any misuse of this library by any third party. Please make sure to respect the artists and the music industry when using this library.
187
+
188
+ > Made with :heart: by the Bluesix Team. If you want to contribute, please read the [contributing guidelines](.github/CONTRIBUTING.md) first.
@@ -0,0 +1,78 @@
1
+ import type { albumType, trackType, lyricsType, albumTracksType, showType, playlistInfo, playlistTracksType, playlistChannelType, channelSearchType, artistInfoType, discographyType, profileType, searchType, trackTypePublicApi, albumTypePublicApi, userType } from '../types';
2
+ /**
3
+ * @param {String} sng_id song id
4
+ */
5
+ export declare const getTrackInfoPublicApi: (sng_id: string) => Promise<trackTypePublicApi>;
6
+ /**
7
+ * @param {String} alb_id album id
8
+ */
9
+ export declare const getAlbumInfoPublicApi: (alb_id: string) => Promise<albumTypePublicApi>;
10
+ /**
11
+ * @param {String} sng_id song id
12
+ */
13
+ export declare const getTrackInfo: (sng_id: string) => Promise<trackType>;
14
+ /**
15
+ * @param {String} sng_id song id
16
+ */
17
+ export declare const getLyrics: (sng_id: string) => Promise<lyricsType>;
18
+ /**
19
+ * @param {String} alb_id album id
20
+ */
21
+ export declare const getAlbumInfo: (alb_id: string) => Promise<albumType>;
22
+ /**
23
+ * @param {String} alb_id user id
24
+ */
25
+ export declare const getAlbumTracks: (alb_id: string) => Promise<albumTracksType>;
26
+ /**
27
+ * @param {String} playlist_id playlist id
28
+ */
29
+ export declare const getPlaylistInfo: (playlist_id: string) => Promise<playlistInfo>;
30
+ /**
31
+ * @param {String} playlist_id playlist id
32
+ */
33
+ export declare const getPlaylistTracks: (playlist_id: string) => Promise<playlistTracksType>;
34
+ /**
35
+ * @param {String} art_id artist id
36
+ */
37
+ export declare const getArtistInfo: (art_id: string) => Promise<artistInfoType>;
38
+ /**
39
+ * @param {String} art_id artist id
40
+ * @param {String} nb number of total song to fetch
41
+ */
42
+ export declare const getDiscography: (art_id: string, nb?: number) => Promise<discographyType>;
43
+ /**
44
+ * @param {String} user_id user id
45
+ */
46
+ export declare const getProfile: (user_id: string) => Promise<profileType>;
47
+ /**
48
+ * @param {String} artist artist name
49
+ * @param {String} song song name
50
+ * @param {String} nb number of items to fetch
51
+ */
52
+ export declare const searchAlternative: (artist: string, song: string, nb?: number) => Promise<searchType>;
53
+ type searchTypesProp = 'ALBUM' | 'ARTIST' | 'TRACK' | 'PLAYLIST' | 'RADIO' | 'SHOW' | 'USER' | 'LIVESTREAM' | 'CHANNEL';
54
+ /**
55
+ * @param {String} query search query
56
+ * @param {Array} types search types
57
+ * @param {Number} nb number of items to fetch
58
+ */
59
+ export declare const searchMusic: (query: string, types?: searchTypesProp[], nb?: number) => Promise<searchType>;
60
+ /**
61
+ * Get details about current user
62
+ */
63
+ export declare const getUser: () => Promise<userType>;
64
+ /**
65
+ * Get list of channles
66
+ */
67
+ export declare const getChannelList: () => Promise<channelSearchType>;
68
+ /**
69
+ * @param {String} SHOW_ID show id
70
+ * @param {Number} NB number of items to fetch
71
+ * @param {Number} START start index
72
+ */
73
+ export declare const getShowInfo: (SHOW_ID: string, NB?: number, START?: number) => Promise<showType>;
74
+ /**
75
+ * Get details about a playlist channel
76
+ */
77
+ export declare const getPlaylistChannel: (page: string) => Promise<playlistChannelType>;
78
+ export {};
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPlaylistChannel = exports.getShowInfo = exports.getChannelList = exports.getUser = exports.searchMusic = exports.searchAlternative = exports.getProfile = exports.getDiscography = exports.getArtistInfo = exports.getPlaylistTracks = exports.getPlaylistInfo = exports.getAlbumTracks = exports.getAlbumInfo = exports.getLyrics = exports.getTrackInfo = exports.getAlbumInfoPublicApi = exports.getTrackInfoPublicApi = void 0;
4
+ const request_1 = require("./request");
5
+ /**
6
+ * @param {String} sng_id song id
7
+ */
8
+ const getTrackInfoPublicApi = (sng_id) => (0, request_1.requestPublicApi)('/track/' + sng_id);
9
+ exports.getTrackInfoPublicApi = getTrackInfoPublicApi;
10
+ /**
11
+ * @param {String} alb_id album id
12
+ */
13
+ const getAlbumInfoPublicApi = (alb_id) => (0, request_1.requestPublicApi)('/album/' + alb_id);
14
+ exports.getAlbumInfoPublicApi = getAlbumInfoPublicApi;
15
+ /**
16
+ * @param {String} sng_id song id
17
+ */
18
+ const getTrackInfo = (sng_id) => (0, request_1.request)({ sng_id }, 'song.getData');
19
+ exports.getTrackInfo = getTrackInfo;
20
+ /**
21
+ * @param {String} sng_id song id
22
+ */
23
+ const getLyrics = (sng_id) => (0, request_1.request)({ sng_id }, 'song.getLyrics');
24
+ exports.getLyrics = getLyrics;
25
+ /**
26
+ * @param {String} alb_id album id
27
+ */
28
+ const getAlbumInfo = (alb_id) => (0, request_1.request)({ alb_id }, 'album.getData');
29
+ exports.getAlbumInfo = getAlbumInfo;
30
+ /**
31
+ * @param {String} alb_id user id
32
+ */
33
+ const getAlbumTracks = async (alb_id) => (0, request_1.request)({ alb_id, lang: 'us', nb: -1 }, 'song.getListByAlbum');
34
+ exports.getAlbumTracks = getAlbumTracks;
35
+ /**
36
+ * @param {String} playlist_id playlist id
37
+ */
38
+ const getPlaylistInfo = (playlist_id) => (0, request_1.request)({ playlist_id, lang: 'en' }, 'playlist.getData');
39
+ exports.getPlaylistInfo = getPlaylistInfo;
40
+ /**
41
+ * @param {String} playlist_id playlist id
42
+ */
43
+ const getPlaylistTracks = async (playlist_id) => {
44
+ const playlistTracks = await (0, request_1.request)({ playlist_id, lang: 'en', nb: -1, start: 0, tab: 0, tags: true, header: true }, 'playlist.getSongs');
45
+ playlistTracks.data = playlistTracks.data.map((track, index) => {
46
+ track.TRACK_POSITION = index + 1;
47
+ return track;
48
+ });
49
+ return playlistTracks;
50
+ };
51
+ exports.getPlaylistTracks = getPlaylistTracks;
52
+ /**
53
+ * @param {String} art_id artist id
54
+ */
55
+ const getArtistInfo = (art_id) => (0, request_1.request)({ art_id, filter_role_id: [0], lang: 'en', tab: 0, nb: -1, start: 0 }, 'artist.getData');
56
+ exports.getArtistInfo = getArtistInfo;
57
+ /**
58
+ * @param {String} art_id artist id
59
+ * @param {String} nb number of total song to fetch
60
+ */
61
+ const getDiscography = (art_id, nb = 500) => (0, request_1.request)({ art_id, filter_role_id: [0], lang: 'en', nb, nb_songs: -1, start: 0 }, 'album.getDiscography');
62
+ exports.getDiscography = getDiscography;
63
+ /**
64
+ * @param {String} user_id user id
65
+ */
66
+ const getProfile = (user_id) => (0, request_1.request)({ user_id, tab: 'loved', nb: -1 }, 'mobile.pageUser');
67
+ exports.getProfile = getProfile;
68
+ /**
69
+ * @param {String} artist artist name
70
+ * @param {String} song song name
71
+ * @param {String} nb number of items to fetch
72
+ */
73
+ const searchAlternative = (artist, song, nb = 10) => (0, request_1.request)({
74
+ query: `artist:'${artist}' track:'${song}'`,
75
+ types: ['TRACK'],
76
+ nb,
77
+ }, 'mobile_suggest');
78
+ exports.searchAlternative = searchAlternative;
79
+ /**
80
+ * @param {String} query search query
81
+ * @param {Array} types search types
82
+ * @param {Number} nb number of items to fetch
83
+ */
84
+ const searchMusic = (query, types = ['TRACK'], nb = 15) => (0, request_1.requestLight)({ query, start: 0, nb, suggest: true, artist_suggest: true, top_tracks: true }, 'deezer.pageSearch');
85
+ exports.searchMusic = searchMusic;
86
+ /**
87
+ * Get details about current user
88
+ */
89
+ const getUser = async () => (0, request_1.requestGet)('user_getInfo');
90
+ exports.getUser = getUser;
91
+ /**
92
+ * Get list of channles
93
+ */
94
+ const getChannelList = async () => (0, request_1.request)({}, 'search_getChannels');
95
+ exports.getChannelList = getChannelList;
96
+ /**
97
+ * @param {String} SHOW_ID show id
98
+ * @param {Number} NB number of items to fetch
99
+ * @param {Number} START start index
100
+ */
101
+ const getShowInfo = (SHOW_ID, NB = 1000, START = 0) => (0, request_1.request)({
102
+ SHOW_ID,
103
+ NB,
104
+ START,
105
+ }, 'mobile.pageShow');
106
+ exports.getShowInfo = getShowInfo;
107
+ /**
108
+ * Get details about a playlist channel
109
+ */
110
+ const getPlaylistChannel = async (page) => {
111
+ const gateway_input = {
112
+ page,
113
+ version: '2.3',
114
+ support: {
115
+ 'long-card-horizontal-grid': ['album', 'playlist', 'radio', 'show'],
116
+ ads: [],
117
+ message: [],
118
+ highlight: ['generic', 'album', 'artist', 'playlist', 'radio', 'app'],
119
+ 'deeplink-list': ['generic', 'deeplink'],
120
+ grid: [
121
+ 'generic',
122
+ 'album',
123
+ 'artist',
124
+ 'playlist',
125
+ 'radio',
126
+ 'channel',
127
+ 'show',
128
+ 'page',
129
+ 'smarttracklist',
130
+ 'flow',
131
+ 'video-link',
132
+ ],
133
+ slideshow: ['album', 'artist', 'playlist', 'radio', 'show', 'channel', 'video-link', 'external-link'],
134
+ 'large-card': ['generic', 'album', 'artist', 'playlist', 'radio', 'show', 'external-link', 'video-link'],
135
+ 'item-highlight': ['radio', 'app'],
136
+ 'small-horizontal-grid': ['album', 'artist', 'playlist', 'radio', 'channel', 'show'],
137
+ 'grid-preview-two': [
138
+ 'generic',
139
+ 'album',
140
+ 'artist',
141
+ 'playlist',
142
+ 'radio',
143
+ 'channel',
144
+ 'show',
145
+ 'page',
146
+ 'smarttracklist',
147
+ 'flow',
148
+ 'video-link',
149
+ ],
150
+ list: ['generic', 'album', 'artist', 'playlist', 'radio', 'show', 'video-link', 'channel', 'episode'],
151
+ 'grid-preview-one': [
152
+ 'generic',
153
+ 'album',
154
+ 'artist',
155
+ 'playlist',
156
+ 'radio',
157
+ 'channel',
158
+ 'show',
159
+ 'page',
160
+ 'smarttracklist',
161
+ 'flow',
162
+ 'video-link',
163
+ ],
164
+ 'horizontal-grid': [
165
+ 'generic',
166
+ 'album',
167
+ 'artist',
168
+ 'playlist',
169
+ 'radio',
170
+ 'channel',
171
+ 'show',
172
+ 'video-link',
173
+ 'smarttracklist',
174
+ 'flow',
175
+ ],
176
+ },
177
+ lang: 'en',
178
+ timezone_offset: '6',
179
+ };
180
+ return await (0, request_1.requestGet)('app_page_get', { gateway_input }, page);
181
+ };
182
+ exports.getPlaylistChannel = getPlaylistChannel;
@@ -0,0 +1,3 @@
1
+ import FastLRU from '../lib/fast-lru';
2
+ declare const lru: FastLRU;
3
+ export default lru;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fast_lru_1 = __importDefault(require("../lib/fast-lru"));
7
+ // Expire cache in 60 minutes
8
+ const lru = new fast_lru_1.default({
9
+ maxSize: 1000,
10
+ ttl: 60 * 60000,
11
+ });
12
+ exports.default = lru;
@@ -0,0 +1,2 @@
1
+ export * from './api';
2
+ export * from './request';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./api"), exports);
18
+ __exportStar(require("./request"), exports);
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Make POST requests to deezer api
3
+ * @param {Object} body post body
4
+ * @param {String} method request method
5
+ */
6
+ export declare const request: (body: object, method: string) => Promise<any>;
7
+ /**
8
+ * Make POST requests to deezer api
9
+ * @param {Object} body post body
10
+ * @param {String} method request method
11
+ */
12
+ export declare const requestLight: (body: object, method: string) => Promise<any>;
13
+ /**
14
+ * Make GET requests to deezer public api
15
+ * @param {String} method request method
16
+ * @param {Object} params request parameters
17
+ */
18
+ export declare const requestGet: (method: string, params?: Record<string, any>, key?: string) => Promise<any>;
19
+ /**
20
+ * Make GET requests to deezer public api
21
+ * @param {String} slug endpoint
22
+ */
23
+ export declare const requestPublicApi: (slug: string) => Promise<any>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.requestPublicApi = exports.requestGet = exports.requestLight = exports.request = void 0;
7
+ const request_1 = __importDefault(require("../lib/request"));
8
+ const cache_1 = __importDefault(require("./cache"));
9
+ /**
10
+ * Make POST requests to deezer api
11
+ * @param {Object} body post body
12
+ * @param {String} method request method
13
+ */
14
+ const request = async (body, method) => {
15
+ const cacheKey = method + ':' + Object.entries(body).join(':');
16
+ const cache = cache_1.default.get(cacheKey);
17
+ if (cache) {
18
+ return cache;
19
+ }
20
+ const { data: { error, results }, } = await request_1.default.post('/gateway.php', body, { params: { method } });
21
+ if (Object.keys(results).length > 0) {
22
+ cache_1.default.set(cacheKey, results);
23
+ return results;
24
+ }
25
+ const errorMessage = Object.entries(error).join(', ');
26
+ throw new Error(errorMessage);
27
+ };
28
+ exports.request = request;
29
+ /**
30
+ * Make POST requests to deezer api
31
+ * @param {Object} body post body
32
+ * @param {String} method request method
33
+ */
34
+ const requestLight = async (body, method) => {
35
+ const cacheKey = method + ':' + Object.entries(body).join(':');
36
+ const cache = cache_1.default.get(cacheKey);
37
+ if (cache) {
38
+ return cache;
39
+ }
40
+ const { data: { error, results }, } = await request_1.default.post('https://www.deezer.com/ajax/gw-light.php', body, {
41
+ params: { method, api_version: '1.0' },
42
+ });
43
+ if (Object.keys(results).length > 0) {
44
+ cache_1.default.set(cacheKey, results);
45
+ return results;
46
+ }
47
+ const errorMessage = Object.entries(error).join(', ');
48
+ throw new Error(errorMessage);
49
+ };
50
+ exports.requestLight = requestLight;
51
+ /**
52
+ * Make GET requests to deezer public api
53
+ * @param {String} method request method
54
+ * @param {Object} params request parameters
55
+ */
56
+ const requestGet = async (method, params = {}, key = 'get_request') => {
57
+ const cacheKey = method + key;
58
+ const cache = cache_1.default.get(cacheKey);
59
+ if (cache) {
60
+ return cache;
61
+ }
62
+ const { data: { error, results }, } = await request_1.default.get('/gateway.php', { params: { method, ...params } });
63
+ if (Object.keys(results).length > 0) {
64
+ cache_1.default.set(cacheKey, results);
65
+ return results;
66
+ }
67
+ const errorMessage = Object.entries(error).join(', ');
68
+ throw new Error(errorMessage);
69
+ };
70
+ exports.requestGet = requestGet;
71
+ /**
72
+ * Make GET requests to deezer public api
73
+ * @param {String} slug endpoint
74
+ */
75
+ const requestPublicApi = async (slug) => {
76
+ const cache = cache_1.default.get(slug);
77
+ if (cache) {
78
+ return cache;
79
+ }
80
+ const { data } = await request_1.default.get('https://api.deezer.com' + slug);
81
+ if (data.error) {
82
+ const errorMessage = Object.entries(data.error).join(', ');
83
+ throw new Error(errorMessage);
84
+ }
85
+ cache_1.default.set(slug, data);
86
+ return data;
87
+ };
88
+ exports.requestPublicApi = requestPublicApi;
@@ -0,0 +1,3 @@
1
+ import type { albumType, trackType } from '../types';
2
+ export declare const isrc2deezer: (name: string, isrc?: string) => Promise<trackType>;
3
+ export declare const upc2deezer: (name: string, upc?: string) => Promise<[albumType, trackType[]]>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.upc2deezer = exports.isrc2deezer = void 0;
7
+ const delay_1 = __importDefault(require("delay"));
8
+ const api_1 = require("../api");
9
+ const http_1 = require("../lib/http");
10
+ const instance = new http_1.HttpClient({ baseURL: 'https://api.deezer.com/', timeout: 15000 });
11
+ const requestLookup = async (path) => {
12
+ const { data } = await instance.get(path);
13
+ if (data.error && data.error.code === 4) {
14
+ await delay_1.default.range(1000, 1500);
15
+ return await requestLookup(path);
16
+ }
17
+ return data;
18
+ };
19
+ const isrc2deezer = async (name, isrc) => {
20
+ if (!isrc) {
21
+ throw new Error('ISRC code not found for ' + name);
22
+ }
23
+ const data = await requestLookup('track/isrc:' + isrc);
24
+ if (data.error) {
25
+ throw new Error(`No match on deezer for ${name} (ISRC: ${isrc})`);
26
+ }
27
+ return await (0, api_1.getTrackInfo)(data.id);
28
+ };
29
+ exports.isrc2deezer = isrc2deezer;
30
+ const upc2deezer = async (name, upc) => {
31
+ if (!upc) {
32
+ throw new Error('UPC code not found for ' + name);
33
+ }
34
+ else if (upc.length > 12 && upc.startsWith('0')) {
35
+ upc = upc.slice(-12);
36
+ }
37
+ const data = await requestLookup('album/upc:' + upc);
38
+ if (data.error) {
39
+ throw new Error(`No match on deezer for ${name} (UPC: ${upc})`);
40
+ }
41
+ const albumInfo = await (0, api_1.getAlbumInfo)(data.id);
42
+ const albumTracks = await (0, api_1.getAlbumTracks)(data.id);
43
+ return [albumInfo, albumTracks.data];
44
+ };
45
+ exports.upc2deezer = upc2deezer;
@@ -0,0 +1,5 @@
1
+ export * from './parse';
2
+ export * from './deezer';
3
+ export * as tidal from './tidal';
4
+ export * as spotify from './spotify';
5
+ export * as youtube from './youtube';