lastfm-nodejs-client 1.2.3 → 1.3.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.
Files changed (57) hide show
  1. package/.github/workflows/playwright.yml +3 -1
  2. package/.nvmrc +1 -0
  3. package/@types/index.d.ts +16 -16
  4. package/CHANGELOG.md +35 -23
  5. package/README.md +4 -0
  6. package/SECURITY.md +1 -2
  7. package/bun.lockb +0 -0
  8. package/dist/auth.d.ts +12 -0
  9. package/dist/auth.js +23 -0
  10. package/dist/config.js +1 -0
  11. package/dist/createOptions.d.ts +6 -0
  12. package/dist/createOptions.js +12 -0
  13. package/dist/getInfo.d.ts +8 -0
  14. package/dist/getInfo.js +19 -0
  15. package/dist/getLovedTracks.d.ts +8 -0
  16. package/dist/getLovedTracks.js +19 -0
  17. package/dist/getRecentTracks.d.ts +8 -0
  18. package/dist/getRecentTracks.js +19 -0
  19. package/dist/getTopAlbums.d.ts +8 -0
  20. package/dist/getTopAlbums.js +19 -0
  21. package/dist/getTopArtists.d.ts +8 -0
  22. package/dist/getTopArtists.js +19 -0
  23. package/dist/getTopTracks.d.ts +8 -0
  24. package/dist/getTopTracks.js +19 -0
  25. package/dist/getWeeklyAlbumChart.d.ts +8 -0
  26. package/dist/getWeeklyAlbumChart.js +19 -0
  27. package/dist/getWeeklyArtistChart.d.ts +8 -0
  28. package/dist/getWeeklyArtistChart.js +19 -0
  29. package/dist/getWeeklyChartList.d.ts +8 -0
  30. package/dist/getWeeklyChartList.js +19 -0
  31. package/dist/getWeeklyTrackChart.d.ts +8 -0
  32. package/dist/getWeeklyTrackChart.js +19 -0
  33. package/dist/index.d.ts +23 -14
  34. package/dist/index.js +22 -115
  35. package/dist/method.d.ts +16 -0
  36. package/dist/method.js +2 -0
  37. package/dist/request.d.ts +7 -1
  38. package/dist/request.js +99 -6
  39. package/package.json +15 -14
  40. package/src/auth.ts +23 -0
  41. package/src/config.ts +13 -1
  42. package/src/createOptions.ts +12 -0
  43. package/src/getInfo.ts +17 -0
  44. package/src/getLovedTracks.ts +19 -0
  45. package/src/getRecentTracks.ts +19 -0
  46. package/src/getTopAlbums.ts +19 -0
  47. package/src/getTopArtists.ts +19 -0
  48. package/src/getTopTracks.ts +19 -0
  49. package/src/getWeeklyAlbumChart.ts +19 -0
  50. package/src/getWeeklyArtistChart.ts +19 -0
  51. package/src/getWeeklyChartList.ts +19 -0
  52. package/src/getWeeklyTrackChart.ts +20 -0
  53. package/src/index.ts +12 -186
  54. package/src/method.ts +19 -1
  55. package/src/request.ts +110 -15
  56. package/tsconfig.json +1 -1
  57. package/src/types.d.ts +0 -392
package/src/index.ts CHANGED
@@ -1,190 +1,18 @@
1
+ import { auth } from './auth';
1
2
  import config from './config';
3
+ import { getInfo } from './getInfo';
4
+ import { getLovedTracks } from './getLovedTracks';
5
+ import { getRecentTracks } from './getRecentTracks';
6
+ import { getTopAlbums } from './getTopAlbums';
7
+ import { getTopArtists } from './getTopArtists';
8
+ import { getTopTracks } from './getTopTracks';
9
+ import { getWeeklyAlbumChart } from './getWeeklyAlbumChart';
10
+ import { getWeeklyArtistChart } from './getWeeklyArtistChart';
11
+ import { getWeeklyChartList } from './getWeeklyChartList';
12
+ import { getWeeklyTrackChart } from './getWeeklyTrackChart';
2
13
  import method from './method';
3
- import request from './request';
4
- import {
5
- AuthResponse,
6
- LovedTracksResponse,
7
- RecentTracksResponse,
8
- TopAlbumsResponse,
9
- TopArtistsResponse,
10
- TopTrackResponse,
11
- UserResponse,
12
- WeeklyAlbumChartResponse,
13
- WeeklyArtistChartResponse,
14
- WeeklyChartListResponse,
15
- WeeklyTrackChartResponse,
16
- } from '../@types';
17
-
18
- function LastFmApi() {
19
- /**
20
- * POST: Auth - LastFM
21
- *
22
- * https://www.last.fm/api/show/auth.getToken
23
- *
24
- * Authentication tokens are API account specific.
25
- * They are valid for 60 minutes from the moment they are granted.
26
- * Can only used once (they are consumed when a session is created).
27
- * @returns Auth token
28
- */
29
- function auth(
30
- method: string,
31
- user: string,
32
- period: string,
33
- limit: string,
34
- ): Promise<AuthResponse> {
35
- return request(method, user, period, limit);
36
- }
37
-
38
- /**
39
- * GET: User profile information - LastFM
40
- *
41
- * https://www.last.fm/api/show/user.getInfo
42
- * @returns User profile data
43
- */
44
- function getInfo(
45
- method: string,
46
- user: string,
47
- period: string,
48
- limit: string,
49
- ): Promise<UserResponse> {
50
- return request(method, user, period, limit);
51
- }
52
-
53
- /**
54
- * GET: Love Tracks - LastFM
55
- *
56
- * https://www.last.fm/api/show/user.getLovedTracks
57
- * @returns Loved Tracks;
58
- */
59
- function getLovedTracks(
60
- method: string,
61
- user: string,
62
- period: string,
63
- limit: string,
64
- ): Promise<LovedTracksResponse> {
65
- return request(method, user, period, limit);
66
- }
67
-
68
- /**
69
- * GET: Recent Tracks - LastFM
70
- *
71
- * https://www.last.fm/api/show/user.getRecentTracks
72
- * @returns Recent Tracks
73
- */
74
- function getRecentTracks(
75
- method: string,
76
- user: string,
77
- period: string,
78
- limit: string,
79
- ): Promise<RecentTracksResponse> {
80
- return request(method, user, period, limit);
81
- }
82
-
83
- /**
84
- * GET: Top Albums - LastFM
85
- *
86
- * https://www.last.fm/api/show/user.getTopAlbums
87
- * @returns Top Albums
88
- */
89
- function getTopAlbums(
90
- method: string,
91
- user: string,
92
- period: string,
93
- limit: string,
94
- ): Promise<TopAlbumsResponse> {
95
- return request(method, user, period, limit);
96
- }
97
-
98
- /**
99
- * GET: Top Artist - LastFM
100
- *
101
- * https://www.last.fm/api/show/user.getTopArtists
102
- * @returns Top Artists
103
- */
104
- function getTopArtists(
105
- method: string,
106
- user: string,
107
- period: string,
108
- limit: string,
109
- ): Promise<TopArtistsResponse> {
110
- return request(method, user, period, limit);
111
- }
112
-
113
- /**
114
- * GET: Top Tracks - LastFM
115
- *
116
- * https://www.last.fm/api/show/user.getTopTracks
117
- * @returns Top Tracks
118
- */
119
- function getTopTracks(
120
- method: string,
121
- user: string,
122
- period: string,
123
- limit: string,
124
- ): Promise<TopTrackResponse> {
125
- return request(method, user, period, limit);
126
- }
127
-
128
- /**
129
- * GET: Weekly album chart - LastFM
130
- *
131
- * https://www.last.fm/api/show/user.getWeeklyAlbumChart
132
- * @returns Weekly album chart
133
- */
134
- function getWeeklyAlbumChart(
135
- method: string,
136
- user: string,
137
- period: string,
138
- limit: string,
139
- ): Promise<WeeklyAlbumChartResponse> {
140
- return request(method, user, period, limit);
141
- }
142
-
143
- /**
144
- * GET: Weekly artist chart - LastFM
145
- *
146
- * https://www.last.fm/api/show/user.getWeeklyArtistChart
147
- * @returns Weekly artist chart
148
- */
149
- function getWeeklyArtistChart(
150
- method: string,
151
- user: string,
152
- period: string,
153
- limit: string,
154
- ): Promise<WeeklyArtistChartResponse> {
155
- return request(method, user, period, limit);
156
- }
157
-
158
- /**
159
- * GET: Weekly chart list - LastFM
160
- *
161
- * https://www.last.fm/api/show/user.getWeeklyChartList
162
- * @returns Weekly chart list
163
- */
164
- function getWeeklyChartList(
165
- method: string,
166
- user: string,
167
- period: string,
168
- limit: string,
169
- ): Promise<WeeklyChartListResponse> {
170
- return request(method, user, period, limit);
171
- }
172
-
173
- /**
174
- * GET: Weekly track chart - LastFM
175
- *
176
- * https://www.last.fm/api/show/user.getWeeklyTrackChart
177
- * @returns Weekly track chart
178
- */
179
- function getWeeklyTrackChart(
180
- method: string,
181
- user: string,
182
- period: string,
183
- limit: string,
184
- ): Promise<WeeklyTrackChartResponse> {
185
- return request(method, user, period, limit);
186
- }
187
14
 
15
+ export default function LastFmApi() {
188
16
  return {
189
17
  auth,
190
18
  config,
@@ -201,5 +29,3 @@ function LastFmApi() {
201
29
  method,
202
30
  };
203
31
  }
204
-
205
- export default LastFmApi;
package/src/method.ts CHANGED
@@ -1,3 +1,21 @@
1
+ interface UserMethod {
2
+ getInfo: string;
3
+ loved_tracks: string;
4
+ recent_tracks: string;
5
+ top_albums: string;
6
+ top_artists: string;
7
+ top_tracks: string;
8
+ weekly_album_chart: string;
9
+ weekly_artist_chart: string;
10
+ weekly_chart_list: string;
11
+ weekly_track_chart: string;
12
+ };
13
+
14
+ export interface Method {
15
+ auth: string;
16
+ user: UserMethod;
17
+ };
18
+
1
19
  export default {
2
20
  auth: 'auth.getToken',
3
21
  user: {
@@ -12,4 +30,4 @@ export default {
12
30
  weekly_chart_list: 'user.getWeeklyChartList',
13
31
  weekly_track_chart: 'user.getWeeklyTrackChart',
14
32
  },
15
- };
33
+ } satisfies Method;
package/src/request.ts CHANGED
@@ -1,18 +1,47 @@
1
1
  import fetch from 'cross-fetch';
2
2
  import config from './config';
3
3
 
4
- const request = async <Response>(
5
- method: string,
6
- user: string,
7
- period?: string,
8
- limit?: string,
9
- ): Promise<Response> => {
10
- const url = `
11
- ${config.base_url}?method=${method}${user ? '&user=' : ''}${user}${
12
- user ? '&user=' : ''
13
- }${user}${period ? '&period=' : ''}${period}&${limit ? '&limit=' : ''}${limit}&api_key=${
14
- config.api_key
15
- }&format=${config.format.json}`;
4
+ interface RequestOptions {
5
+ method: string;
6
+ user?: string;
7
+ period?: string;
8
+ limit?: string;
9
+ }
10
+
11
+ enum ErrorResponse {
12
+ InvalidService = 2,
13
+ InvalidMethod = 3,
14
+ AuthenticationFailed = 4,
15
+ InvalidFormat = 5,
16
+ InvalidParameters = 6,
17
+ InvalidResource = 7,
18
+ OperationFailed = 8,
19
+ InvalidSessionKey = 9,
20
+ InvalidAPIKey = 10,
21
+ ServiceOffline = 11,
22
+ InvalidMethodSignature = 13,
23
+ TemporaryError = 16,
24
+ SuspendedAPIKey = 26,
25
+ RateLimitExceeded = 29
26
+ }
27
+
28
+ const buildUrl = (options: RequestOptions): string => {
29
+ const params = new URLSearchParams();
30
+
31
+ params.append('method', options.method);
32
+
33
+ if (options.user) params.append('user', options.user);
34
+ if (options.period) params.append('period', options.period);
35
+ if (options.limit) params.append('limit', options.limit);
36
+
37
+ params.append('api_key', config.api_key);
38
+ params.append('format', config.format.json);
39
+
40
+ return `${config.base_url}?${params.toString()}`;
41
+ }
42
+
43
+ const request = async <Response>(options: RequestOptions): Promise<Response> => {
44
+ const url = buildUrl(options);
16
45
 
17
46
  return (await fetch(url, {
18
47
  headers: {
@@ -20,10 +49,76 @@ const request = async <Response>(
20
49
  },
21
50
  })
22
51
  .then((res) => {
23
- if (res.status >= 400) {
24
- throw new Error('Bad response from server');
52
+ switch (res.status) {
53
+ case 200: {
54
+ return res.json();
55
+ }
56
+ case 400: {
57
+ throw new Error('Bad request');
58
+ }
59
+ case 401: {
60
+ throw new Error('Unauthorized');
61
+ }
62
+ case 403: {
63
+ throw new Error('Forbidden');
64
+ }
65
+ case 404: {
66
+ throw new Error('Not found');
67
+ }
68
+ case 500: {
69
+ throw new Error('Internal server error');
70
+ }
71
+ case 503: {
72
+ throw new Error('Service unavailable');
73
+ }
74
+ case ErrorResponse.InvalidAPIKey: {
75
+ throw new Error('Invalid API key');
76
+ }
77
+ case ErrorResponse.InvalidMethod: {
78
+ throw new Error('Invalid method');
79
+ }
80
+ case ErrorResponse.InvalidParameters: {
81
+ throw new Error('Invalid parameters');
82
+ }
83
+ case ErrorResponse.InvalidResource: {
84
+ throw new Error('Invalid resource');
85
+ }
86
+ case ErrorResponse.InvalidSessionKey: {
87
+ throw new Error('Invalid session key');
88
+ }
89
+ case ErrorResponse.InvalidService: {
90
+ throw new Error('Invalid service');
91
+ }
92
+ case ErrorResponse.OperationFailed: {
93
+ throw new Error('Operation failed');
94
+ }
95
+ case ErrorResponse.RateLimitExceeded: {
96
+ throw new Error('Rate limit exceeded');
97
+ }
98
+ case ErrorResponse.ServiceOffline: {
99
+ throw new Error('Service offline');
100
+ }
101
+ case ErrorResponse.SuspendedAPIKey: {
102
+ throw new Error('Suspended API key');
103
+ }
104
+ case ErrorResponse.TemporaryError: {
105
+ throw new Error('Temporary error');
106
+ }
107
+ case ErrorResponse.AuthenticationFailed: {
108
+ throw new Error('Authentication failed');
109
+ }
110
+ case ErrorResponse.InvalidFormat: {
111
+ throw new Error('Invalid format');
112
+ }
113
+ case ErrorResponse.InvalidMethodSignature: {
114
+ throw new Error('Invalid method signature');
115
+ }
116
+
117
+ default: {
118
+ throw new Error('Unknown error');
119
+ }
25
120
  }
26
- return res.json();
121
+
27
122
  })
28
123
  .then((json) => json)
29
124
  .catch((error) => {
package/tsconfig.json CHANGED
@@ -51,7 +51,7 @@
51
51
  // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
52
52
  // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
53
53
  "outDir": "./dist" /* Specify an output folder for all emitted files. */,
54
- // "removeComments": true, /* Disable emitting comments. */
54
+ "removeComments": false, /* Disable emitting comments. */
55
55
  // "noEmit": true, /* Disable emitting files from a compilation. */
56
56
  // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
57
57
  // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */