@lucaperret/tidal-cli 1.1.0 → 1.2.2

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.
@@ -1,9 +1,52 @@
1
+ import type { PlaylistInfo } from './types';
2
+ export type { PlaylistInfo };
3
+ export declare function listPlaylistsData(client: any, countryCode: string): Promise<PlaylistInfo[]>;
1
4
  export declare function listPlaylists(json: boolean): Promise<void>;
5
+ export declare function createPlaylistData(name: string, description: string, client: any): Promise<{
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ }>;
2
10
  export declare function createPlaylist(name: string, description: string, json: boolean): Promise<void>;
11
+ export declare function renamePlaylistData(playlistId: string, name: string, client: any): Promise<{
12
+ id: string;
13
+ name: string;
14
+ success: boolean;
15
+ }>;
3
16
  export declare function renamePlaylist(playlistId: string, name: string, json: boolean): Promise<void>;
17
+ export declare function deletePlaylistData(playlistId: string, client: any): Promise<{
18
+ id: string;
19
+ deleted: boolean;
20
+ }>;
4
21
  export declare function deletePlaylist(playlistId: string, json: boolean): Promise<void>;
22
+ export declare function addTrackToPlaylistData(playlistId: string, trackId: string, client: any): Promise<{
23
+ playlistId: string;
24
+ trackId: string;
25
+ added: boolean;
26
+ }>;
5
27
  export declare function addTrackToPlaylist(playlistId: string, trackId: string, json: boolean): Promise<void>;
28
+ export declare function removeTrackFromPlaylistData(playlistId: string, trackId: string, client: any): Promise<{
29
+ playlistId: string;
30
+ trackId: string;
31
+ removed: boolean;
32
+ }>;
6
33
  export declare function removeTrackFromPlaylist(playlistId: string, trackId: string, json: boolean): Promise<void>;
34
+ export declare function addAlbumToPlaylistData(playlistId: string, albumId: string, client: any, countryCode: string): Promise<{
35
+ playlistId: string;
36
+ albumId: string;
37
+ tracksAdded: number;
38
+ }>;
7
39
  export declare function addAlbumToPlaylist(playlistId: string, albumId: string, json: boolean): Promise<void>;
40
+ export declare function moveTrackInPlaylistData(playlistId: string, trackId: string, positionBefore: string, client: any): Promise<{
41
+ playlistId: string;
42
+ trackId: string;
43
+ positionBefore: string;
44
+ moved: boolean;
45
+ }>;
8
46
  export declare function moveTrackInPlaylist(playlistId: string, trackId: string, positionBefore: string, json: boolean): Promise<void>;
47
+ export declare function updatePlaylistDescriptionData(playlistId: string, description: string, client: any): Promise<{
48
+ id: string;
49
+ description: string;
50
+ success: boolean;
51
+ }>;
9
52
  export declare function updatePlaylistDescription(playlistId: string, description: string, json: boolean): Promise<void>;
package/dist/playlist.js CHANGED
@@ -1,30 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listPlaylistsData = listPlaylistsData;
3
4
  exports.listPlaylists = listPlaylists;
5
+ exports.createPlaylistData = createPlaylistData;
4
6
  exports.createPlaylist = createPlaylist;
7
+ exports.renamePlaylistData = renamePlaylistData;
5
8
  exports.renamePlaylist = renamePlaylist;
9
+ exports.deletePlaylistData = deletePlaylistData;
6
10
  exports.deletePlaylist = deletePlaylist;
11
+ exports.addTrackToPlaylistData = addTrackToPlaylistData;
7
12
  exports.addTrackToPlaylist = addTrackToPlaylist;
13
+ exports.removeTrackFromPlaylistData = removeTrackFromPlaylistData;
8
14
  exports.removeTrackFromPlaylist = removeTrackFromPlaylist;
15
+ exports.addAlbumToPlaylistData = addAlbumToPlaylistData;
9
16
  exports.addAlbumToPlaylist = addAlbumToPlaylist;
17
+ exports.moveTrackInPlaylistData = moveTrackInPlaylistData;
10
18
  exports.moveTrackInPlaylist = moveTrackInPlaylist;
19
+ exports.updatePlaylistDescriptionData = updatePlaylistDescriptionData;
11
20
  exports.updatePlaylistDescription = updatePlaylistDescription;
12
21
  const auth_1 = require("./auth");
13
- async function listPlaylists(json) {
14
- const client = await (0, auth_1.getApiClient)();
22
+ async function listPlaylistsData(client, countryCode) {
15
23
  const { data, error } = await client.GET('/playlists', {
16
24
  params: {
17
25
  query: {
18
26
  'filter[owners.id]': ['me'],
19
- countryCode: await (0, auth_1.getCountryCode)(),
27
+ countryCode,
20
28
  },
21
29
  },
22
30
  });
23
31
  if (error || !data) {
24
- console.error(`Error: Failed to list playlists — ${JSON.stringify(error)}`);
25
- process.exit(1);
32
+ throw new Error(`Failed to list playlists — ${JSON.stringify(error)}`);
26
33
  }
27
- const playlists = (data.data ?? []).map((p) => ({
34
+ return (data.data ?? []).map((p) => ({
28
35
  id: p.id,
29
36
  name: p.attributes?.name ?? 'Untitled',
30
37
  description: p.attributes?.description,
@@ -32,24 +39,34 @@ async function listPlaylists(json) {
32
39
  createdAt: p.attributes?.createdAt,
33
40
  lastModifiedAt: p.attributes?.lastModifiedAt,
34
41
  }));
35
- if (json) {
36
- console.log(JSON.stringify(playlists, null, 2));
37
- return;
38
- }
39
- if (playlists.length === 0) {
40
- console.log('No playlists found.');
41
- return;
42
+ }
43
+ async function listPlaylists(json) {
44
+ const client = await (0, auth_1.getApiClient)();
45
+ const countryCode = await (0, auth_1.getCountryCode)();
46
+ try {
47
+ const playlists = await listPlaylistsData(client, countryCode);
48
+ if (json) {
49
+ console.log(JSON.stringify(playlists, null, 2));
50
+ return;
51
+ }
52
+ if (playlists.length === 0) {
53
+ console.log('No playlists found.');
54
+ return;
55
+ }
56
+ console.log('\nYour playlists:\n');
57
+ for (const p of playlists) {
58
+ console.log(` [${p.id}] ${p.name} (${p.numberOfItems ?? 0} tracks)`);
59
+ if (p.description)
60
+ console.log(` ${p.description}`);
61
+ }
62
+ console.log();
42
63
  }
43
- console.log('\nYour playlists:\n');
44
- for (const p of playlists) {
45
- console.log(` [${p.id}] ${p.name} (${p.numberOfItems ?? 0} tracks)`);
46
- if (p.description)
47
- console.log(` ${p.description}`);
64
+ catch (err) {
65
+ console.error(`Error: ${err.message}`);
66
+ process.exit(1);
48
67
  }
49
- console.log();
50
68
  }
51
- async function createPlaylist(name, description, json) {
52
- const client = await (0, auth_1.getApiClient)();
69
+ async function createPlaylistData(name, description, client) {
53
70
  const { data, error } = await client.POST('/playlists', {
54
71
  body: {
55
72
  data: {
@@ -63,23 +80,31 @@ async function createPlaylist(name, description, json) {
63
80
  },
64
81
  });
65
82
  if (error || !data) {
66
- console.error(`Error: Failed to create playlist — ${JSON.stringify(error)}`);
67
- process.exit(1);
83
+ throw new Error(`Failed to create playlist — ${JSON.stringify(error)}`);
68
84
  }
69
85
  const created = data.data;
70
- const result = {
86
+ return {
71
87
  id: created.id,
72
88
  name: created.attributes?.name ?? name,
73
89
  description: created.attributes?.description ?? description,
74
90
  };
75
- if (json) {
76
- console.log(JSON.stringify(result, null, 2));
77
- return;
78
- }
79
- console.log(`\nPlaylist created: [${result.id}] ${result.name}`);
80
91
  }
81
- async function renamePlaylist(playlistId, name, json) {
92
+ async function createPlaylist(name, description, json) {
82
93
  const client = await (0, auth_1.getApiClient)();
94
+ try {
95
+ const result = await createPlaylistData(name, description, client);
96
+ if (json) {
97
+ console.log(JSON.stringify(result, null, 2));
98
+ return;
99
+ }
100
+ console.log(`\nPlaylist created: [${result.id}] ${result.name}`);
101
+ }
102
+ catch (err) {
103
+ console.error(`Error: ${err.message}`);
104
+ process.exit(1);
105
+ }
106
+ }
107
+ async function renamePlaylistData(playlistId, name, client) {
83
108
  const { error } = await client.PATCH('/playlists/{id}', {
84
109
  params: { path: { id: playlistId } },
85
110
  body: {
@@ -91,32 +116,50 @@ async function renamePlaylist(playlistId, name, json) {
91
116
  },
92
117
  });
93
118
  if (error) {
94
- console.error(`Error: Failed to rename playlist — ${JSON.stringify(error)}`);
95
- process.exit(1);
96
- }
97
- if (json) {
98
- console.log(JSON.stringify({ id: playlistId, name, success: true }, null, 2));
99
- return;
119
+ throw new Error(`Failed to rename playlist — ${JSON.stringify(error)}`);
100
120
  }
101
- console.log(`\nPlaylist ${playlistId} renamed to "${name}".`);
121
+ return { id: playlistId, name, success: true };
102
122
  }
103
- async function deletePlaylist(playlistId, json) {
123
+ async function renamePlaylist(playlistId, name, json) {
104
124
  const client = await (0, auth_1.getApiClient)();
125
+ try {
126
+ const result = await renamePlaylistData(playlistId, name, client);
127
+ if (json) {
128
+ console.log(JSON.stringify(result, null, 2));
129
+ return;
130
+ }
131
+ console.log(`\nPlaylist ${playlistId} renamed to "${name}".`);
132
+ }
133
+ catch (err) {
134
+ console.error(`Error: ${err.message}`);
135
+ process.exit(1);
136
+ }
137
+ }
138
+ async function deletePlaylistData(playlistId, client) {
105
139
  const { error } = await client.DELETE('/playlists/{id}', {
106
140
  params: { path: { id: playlistId } },
107
141
  });
108
142
  if (error) {
109
- console.error(`Error: Failed to delete playlist — ${JSON.stringify(error)}`);
110
- process.exit(1);
111
- }
112
- if (json) {
113
- console.log(JSON.stringify({ id: playlistId, deleted: true }, null, 2));
114
- return;
143
+ throw new Error(`Failed to delete playlist — ${JSON.stringify(error)}`);
115
144
  }
116
- console.log(`\nPlaylist ${playlistId} deleted.`);
145
+ return { id: playlistId, deleted: true };
117
146
  }
118
- async function addTrackToPlaylist(playlistId, trackId, json) {
147
+ async function deletePlaylist(playlistId, json) {
119
148
  const client = await (0, auth_1.getApiClient)();
149
+ try {
150
+ const result = await deletePlaylistData(playlistId, client);
151
+ if (json) {
152
+ console.log(JSON.stringify(result, null, 2));
153
+ return;
154
+ }
155
+ console.log(`\nPlaylist ${playlistId} deleted.`);
156
+ }
157
+ catch (err) {
158
+ console.error(`Error: ${err.message}`);
159
+ process.exit(1);
160
+ }
161
+ }
162
+ async function addTrackToPlaylistData(playlistId, trackId, client) {
120
163
  const { error } = await client.POST('/playlists/{id}/relationships/items', {
121
164
  params: { path: { id: playlistId } },
122
165
  body: {
@@ -124,30 +167,36 @@ async function addTrackToPlaylist(playlistId, trackId, json) {
124
167
  },
125
168
  });
126
169
  if (error) {
127
- console.error(`Error: Failed to add track — ${JSON.stringify(error)}`);
128
- process.exit(1);
170
+ throw new Error(`Failed to add track — ${JSON.stringify(error)}`);
129
171
  }
130
- if (json) {
131
- console.log(JSON.stringify({ playlistId, trackId, added: true }, null, 2));
132
- return;
133
- }
134
- console.log(`\nTrack ${trackId} added to playlist ${playlistId}.`);
172
+ return { playlistId, trackId, added: true };
135
173
  }
136
- async function removeTrackFromPlaylist(playlistId, trackId, json) {
174
+ async function addTrackToPlaylist(playlistId, trackId, json) {
137
175
  const client = await (0, auth_1.getApiClient)();
138
- // Get playlist items to find the item index (required by the API)
176
+ try {
177
+ const result = await addTrackToPlaylistData(playlistId, trackId, client);
178
+ if (json) {
179
+ console.log(JSON.stringify(result, null, 2));
180
+ return;
181
+ }
182
+ console.log(`\nTrack ${trackId} added to playlist ${playlistId}.`);
183
+ }
184
+ catch (err) {
185
+ console.error(`Error: ${err.message}`);
186
+ process.exit(1);
187
+ }
188
+ }
189
+ async function removeTrackFromPlaylistData(playlistId, trackId, client) {
139
190
  const { data: itemsData, error: itemsError } = await client.GET('/playlists/{id}/relationships/items', {
140
191
  params: { path: { id: playlistId } },
141
192
  });
142
193
  if (itemsError || !itemsData) {
143
- console.error(`Error: Failed to get playlist items — ${JSON.stringify(itemsError)}`);
144
- process.exit(1);
194
+ throw new Error(`Failed to get playlist items — ${JSON.stringify(itemsError)}`);
145
195
  }
146
196
  const items = itemsData.data ?? [];
147
197
  const item = items.find((i) => i.id === trackId);
148
198
  if (!item) {
149
- console.error(`Error: Track ${trackId} not found in playlist ${playlistId}.`);
150
- process.exit(1);
199
+ throw new Error(`Track ${trackId} not found in playlist ${playlistId}.`);
151
200
  }
152
201
  const { error } = await client.DELETE('/playlists/{id}/relationships/items', {
153
202
  params: { path: { id: playlistId } },
@@ -156,71 +205,82 @@ async function removeTrackFromPlaylist(playlistId, trackId, json) {
156
205
  },
157
206
  });
158
207
  if (error) {
159
- console.error(`Error: Failed to remove track — ${JSON.stringify(error)}`);
160
- process.exit(1);
208
+ throw new Error(`Failed to remove track — ${JSON.stringify(error)}`);
161
209
  }
162
- if (json) {
163
- console.log(JSON.stringify({ playlistId, trackId, removed: true }, null, 2));
164
- return;
165
- }
166
- console.log(`\nTrack ${trackId} removed from playlist ${playlistId}.`);
210
+ return { playlistId, trackId, removed: true };
167
211
  }
168
- async function addAlbumToPlaylist(playlistId, albumId, json) {
212
+ async function removeTrackFromPlaylist(playlistId, trackId, json) {
169
213
  const client = await (0, auth_1.getApiClient)();
170
- // First get album tracks
214
+ try {
215
+ const result = await removeTrackFromPlaylistData(playlistId, trackId, client);
216
+ if (json) {
217
+ console.log(JSON.stringify(result, null, 2));
218
+ return;
219
+ }
220
+ console.log(`\nTrack ${trackId} removed from playlist ${playlistId}.`);
221
+ }
222
+ catch (err) {
223
+ console.error(`Error: ${err.message}`);
224
+ process.exit(1);
225
+ }
226
+ }
227
+ async function addAlbumToPlaylistData(playlistId, albumId, client, countryCode) {
171
228
  const { data: albumData, error: albumError } = await client.GET('/albums/{id}', {
172
229
  params: {
173
230
  path: { id: albumId },
174
- query: { countryCode: await (0, auth_1.getCountryCode)(), include: ['items'] },
231
+ query: { countryCode, include: ['items'] },
175
232
  },
176
233
  });
177
234
  if (albumError || !albumData) {
178
- console.error(`Error: Failed to get album — ${JSON.stringify(albumError)}`);
179
- process.exit(1);
235
+ throw new Error(`Failed to get album — ${JSON.stringify(albumError)}`);
180
236
  }
181
- // Extract track IDs from included items
182
237
  const included = albumData.included ?? [];
183
238
  const trackIds = included
184
239
  .filter((item) => item.type === 'tracks')
185
240
  .map((item) => ({ id: item.id, type: 'tracks' }));
186
241
  if (trackIds.length === 0) {
187
- console.error('Error: No tracks found in album.');
188
- process.exit(1);
242
+ throw new Error('No tracks found in album.');
189
243
  }
190
244
  const { error } = await client.POST('/playlists/{id}/relationships/items', {
191
245
  params: { path: { id: playlistId } },
192
246
  body: { data: trackIds },
193
247
  });
194
248
  if (error) {
195
- console.error(`Error: Failed to add album tracks — ${JSON.stringify(error)}`);
196
- process.exit(1);
249
+ throw new Error(`Failed to add album tracks — ${JSON.stringify(error)}`);
197
250
  }
198
- if (json) {
199
- console.log(JSON.stringify({ playlistId, albumId, tracksAdded: trackIds.length }, null, 2));
200
- return;
201
- }
202
- console.log(`\n${trackIds.length} tracks from album ${albumId} added to playlist ${playlistId}.`);
251
+ return { playlistId, albumId, tracksAdded: trackIds.length };
203
252
  }
204
- async function moveTrackInPlaylist(playlistId, trackId, positionBefore, json) {
253
+ async function addAlbumToPlaylist(playlistId, albumId, json) {
205
254
  const client = await (0, auth_1.getApiClient)();
206
- // Get playlist items to find the itemId for the track
255
+ const countryCode = await (0, auth_1.getCountryCode)();
256
+ try {
257
+ const result = await addAlbumToPlaylistData(playlistId, albumId, client, countryCode);
258
+ if (json) {
259
+ console.log(JSON.stringify(result, null, 2));
260
+ return;
261
+ }
262
+ console.log(`\n${result.tracksAdded} tracks from album ${albumId} added to playlist ${playlistId}.`);
263
+ }
264
+ catch (err) {
265
+ console.error(`Error: ${err.message}`);
266
+ process.exit(1);
267
+ }
268
+ }
269
+ async function moveTrackInPlaylistData(playlistId, trackId, positionBefore, client) {
207
270
  const { data: itemsData, error: itemsError } = await client.GET('/playlists/{id}/relationships/items', {
208
271
  params: { path: { id: playlistId } },
209
272
  });
210
273
  if (itemsError || !itemsData) {
211
- console.error(`Error: Failed to get playlist items — ${JSON.stringify(itemsError)}`);
212
- process.exit(1);
274
+ throw new Error(`Failed to get playlist items — ${JSON.stringify(itemsError)}`);
213
275
  }
214
276
  const items = itemsData.data ?? [];
215
277
  const item = items.find((i) => i.id === trackId);
216
278
  if (!item) {
217
- console.error(`Error: Track ${trackId} not found in playlist ${playlistId}.`);
218
- process.exit(1);
279
+ throw new Error(`Track ${trackId} not found in playlist ${playlistId}.`);
219
280
  }
220
281
  const itemId = item.meta?.itemId;
221
282
  if (!itemId) {
222
- console.error(`Error: Could not find itemId for track ${trackId}.`);
223
- process.exit(1);
283
+ throw new Error(`Could not find itemId for track ${trackId}.`);
224
284
  }
225
285
  const meta = {};
226
286
  if (positionBefore !== 'end') {
@@ -234,18 +294,27 @@ async function moveTrackInPlaylist(playlistId, trackId, positionBefore, json) {
234
294
  },
235
295
  });
236
296
  if (error) {
237
- console.error(`Error: Failed to move track — ${JSON.stringify(error)}`);
238
- process.exit(1);
239
- }
240
- if (json) {
241
- console.log(JSON.stringify({ playlistId, trackId, positionBefore, moved: true }, null, 2));
242
- return;
297
+ throw new Error(`Failed to move track — ${JSON.stringify(error)}`);
243
298
  }
244
- const posDesc = positionBefore === 'end' ? 'to end of playlist' : `before item ${positionBefore}`;
245
- console.log(`\nTrack ${trackId} moved ${posDesc} in playlist ${playlistId}.`);
299
+ return { playlistId, trackId, positionBefore, moved: true };
246
300
  }
247
- async function updatePlaylistDescription(playlistId, description, json) {
301
+ async function moveTrackInPlaylist(playlistId, trackId, positionBefore, json) {
248
302
  const client = await (0, auth_1.getApiClient)();
303
+ try {
304
+ const result = await moveTrackInPlaylistData(playlistId, trackId, positionBefore, client);
305
+ if (json) {
306
+ console.log(JSON.stringify(result, null, 2));
307
+ return;
308
+ }
309
+ const posDesc = positionBefore === 'end' ? 'to end of playlist' : `before item ${positionBefore}`;
310
+ console.log(`\nTrack ${trackId} moved ${posDesc} in playlist ${playlistId}.`);
311
+ }
312
+ catch (err) {
313
+ console.error(`Error: ${err.message}`);
314
+ process.exit(1);
315
+ }
316
+ }
317
+ async function updatePlaylistDescriptionData(playlistId, description, client) {
249
318
  const { error } = await client.PATCH('/playlists/{id}', {
250
319
  params: { path: { id: playlistId } },
251
320
  body: {
@@ -257,13 +326,23 @@ async function updatePlaylistDescription(playlistId, description, json) {
257
326
  },
258
327
  });
259
328
  if (error) {
260
- console.error(`Error: Failed to update playlist description — ${JSON.stringify(error)}`);
261
- process.exit(1);
329
+ throw new Error(`Failed to update playlist description — ${JSON.stringify(error)}`);
262
330
  }
263
- if (json) {
264
- console.log(JSON.stringify({ id: playlistId, description, success: true }, null, 2));
265
- return;
331
+ return { id: playlistId, description, success: true };
332
+ }
333
+ async function updatePlaylistDescription(playlistId, description, json) {
334
+ const client = await (0, auth_1.getApiClient)();
335
+ try {
336
+ const result = await updatePlaylistDescriptionData(playlistId, description, client);
337
+ if (json) {
338
+ console.log(JSON.stringify(result, null, 2));
339
+ return;
340
+ }
341
+ console.log(`\nPlaylist ${playlistId} description updated.`);
342
+ }
343
+ catch (err) {
344
+ console.error(`Error: ${err.message}`);
345
+ process.exit(1);
266
346
  }
267
- console.log(`\nPlaylist ${playlistId} description updated.`);
268
347
  }
269
348
  //# sourceMappingURL=playlist.js.map
@@ -1 +1,4 @@
1
- export declare function getRecommendations(json: boolean): Promise<void>;
1
+ import type { MixCategory, RecommendationItem } from './types';
2
+ export type { MixCategory, RecommendationItem };
3
+ export declare function getRecommendationsData(client: any, countryCode: string, category?: MixCategory): Promise<RecommendationItem[]>;
4
+ export declare function getRecommendations(category: MixCategory | undefined, json: boolean): Promise<void>;
package/dist/recommend.js CHANGED
@@ -1,36 +1,88 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRecommendationsData = getRecommendationsData;
3
4
  exports.getRecommendations = getRecommendations;
4
5
  const auth_1 = require("./auth");
5
- async function getRecommendations(json) {
6
- const client = await (0, auth_1.getApiClient)();
7
- const { data, error } = await client.GET('/userRecommendations/me', {
6
+ const categoryEndpoints = {
7
+ daily: '/userDailyMixes/{id}',
8
+ discovery: '/userDiscoveryMixes/{id}',
9
+ 'new-release': '/userNewReleaseMixes/{id}',
10
+ offline: '/userOfflineMixes/{id}',
11
+ };
12
+ async function getCategoryItems(category, client, countryCode) {
13
+ const { data, error } = await client.GET(categoryEndpoints[category], {
8
14
  params: {
15
+ path: { id: 'me' },
9
16
  query: {
10
- countryCode: await (0, auth_1.getCountryCode)(),
11
- include: ['discoveryMixes', 'myMixes', 'newArrivalMixes'],
17
+ countryCode,
18
+ include: ['items'],
12
19
  },
13
20
  },
14
21
  });
15
22
  if (error || !data) {
16
- console.error(`Error: Failed to get recommendations${JSON.stringify(error)}`);
17
- process.exit(1);
23
+ // Some categories (e.g. offline) may 404 for users without entitlement treat as empty.
24
+ return [];
18
25
  }
19
26
  const included = data.included ?? [];
20
- if (json) {
21
- console.log(JSON.stringify(included, null, 2));
22
- return;
27
+ return included.map((item) => {
28
+ const attrs = item.attributes ?? {};
29
+ return {
30
+ id: item.id,
31
+ type: item.type,
32
+ name: attrs.title ?? attrs.name ?? 'Untitled',
33
+ category,
34
+ };
35
+ });
36
+ }
37
+ async function getRecommendationsData(client, countryCode, category) {
38
+ if (category) {
39
+ return getCategoryItems(category, client, countryCode);
23
40
  }
24
- if (included.length === 0) {
25
- console.log('No recommendations found.');
26
- return;
41
+ const categories = ['daily', 'discovery', 'new-release', 'offline'];
42
+ const results = await Promise.all(categories.map((c) => getCategoryItems(c, client, countryCode)));
43
+ return results.flat();
44
+ }
45
+ async function getRecommendations(category, json) {
46
+ const client = await (0, auth_1.getApiClient)();
47
+ const countryCode = await (0, auth_1.getCountryCode)();
48
+ try {
49
+ const items = await getRecommendationsData(client, countryCode, category);
50
+ if (json) {
51
+ console.log(JSON.stringify(items, null, 2));
52
+ return;
53
+ }
54
+ if (items.length === 0) {
55
+ console.log('No recommendations found.');
56
+ return;
57
+ }
58
+ if (category) {
59
+ console.log(`\nYour ${category} mixes:\n`);
60
+ for (const item of items) {
61
+ console.log(` [${item.id}] (${item.type}) ${item.name}`);
62
+ }
63
+ }
64
+ else {
65
+ console.log('\nYour recommendations:\n');
66
+ const grouped = items.reduce((acc, item) => {
67
+ const key = item.category ?? 'other';
68
+ (acc[key] ??= []).push(item);
69
+ return acc;
70
+ }, {});
71
+ for (const cat of ['daily', 'discovery', 'new-release', 'offline']) {
72
+ const list = grouped[cat];
73
+ if (!list?.length)
74
+ continue;
75
+ console.log(` ${cat}:`);
76
+ for (const item of list) {
77
+ console.log(` [${item.id}] (${item.type}) ${item.name}`);
78
+ }
79
+ }
80
+ }
81
+ console.log();
27
82
  }
28
- console.log('\nYour recommendations:\n');
29
- for (const item of included) {
30
- const attrs = item.attributes;
31
- const name = attrs?.title ?? attrs?.name ?? 'Untitled';
32
- console.log(` [${item.id}] (${item.type}) ${name}`);
83
+ catch (err) {
84
+ console.error(`Error: ${err.message}`);
85
+ process.exit(1);
33
86
  }
34
- console.log();
35
87
  }
36
88
  //# sourceMappingURL=recommend.js.map
@@ -0,0 +1,16 @@
1
+ import type { SavedItem, SavedItemType } from './types';
2
+ export type { SavedItem, SavedItemType };
3
+ export declare function listSavedItemsData(client: any): Promise<SavedItem[]>;
4
+ export declare function listSavedItems(json: boolean): Promise<void>;
5
+ export declare function addSavedItemData(itemType: SavedItemType, itemId: string, client: any): Promise<{
6
+ id: string;
7
+ type: SavedItemType;
8
+ added: boolean;
9
+ }>;
10
+ export declare function addSavedItem(itemType: SavedItemType, itemId: string, json: boolean): Promise<void>;
11
+ export declare function removeSavedItemData(itemType: SavedItemType, itemId: string, client: any): Promise<{
12
+ id: string;
13
+ type: SavedItemType;
14
+ removed: boolean;
15
+ }>;
16
+ export declare function removeSavedItem(itemType: SavedItemType, itemId: string, json: boolean): Promise<void>;