lastfm-nodejs-client 1.2.2 → 1.2.4

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/.env.example CHANGED
@@ -1,5 +1,5 @@
1
- LASTFM_API_BASE_URL=""
2
- LASTFM_API_KEY=""
3
- LASTFM_APPNAME=""
4
- LASTFM_SHARED_SECRET=""
5
- LASTFM_USER=""
1
+ LASTFM_API_BASE_URL="https://ws.audioscrobbler.com/2.0/"
2
+ LASTFM_API_KEY="abcdefghijkhlmnopqrstuvwxyz"
3
+ LASTFM_APPNAME="your app name"
4
+ LASTFM_SHARED_SECRET="xxxxxxxxxxxxxxxxxxxxx"
5
+ LASTFM_USER="your username"
@@ -0,0 +1,36 @@
1
+ name: Playwright Tests
2
+ on:
3
+ push:
4
+ branches: [main, master]
5
+ pull_request:
6
+ branches: [main, master]
7
+ jobs:
8
+ test:
9
+ timeout-minutes: 60
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v3
13
+ - uses: actions/setup-node@v3
14
+ with:
15
+ node-version: 16
16
+ - uses: pnpm/action-setup@v2
17
+ with:
18
+ version: 7.14.1
19
+ - name: Install dependencies
20
+ run: pnpm install
21
+ - name: Install Playwright Browsers
22
+ run: npx playwright install --with-deps
23
+ - name: Install @playwright/test package
24
+ run: pnpm add -D @playwright/test
25
+ - name: Creates environment variables
26
+ run: |
27
+ echo "LASTFM_API_BASE_URL: https://ws.audioscrobbler.com/2.0/"
28
+ echo "LASTFM_API_KEY: abcdefghijklmnopqrstuvxyz"
29
+ - name: Run Playwright tests
30
+ run: pnpm dlx playwright test
31
+ - uses: actions/upload-artifact@v2
32
+ if: always()
33
+ with:
34
+ name: playwright-report
35
+ path: playwright-report/
36
+ retention-days: 30
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ v20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.4
4
+
5
+ - Updates npm dependencies
6
+ - Refactors request methods options and updates all callsites.
7
+ - Add nvmrc file for easy switching node version.
8
+
9
+ ## 1.2.3
10
+
11
+ - Adds tests, using Playwright
12
+ - Adds dotenv npm module as a new dependency
13
+
3
14
  ## 1.2.2
4
15
 
5
16
  - Put log back, some APIs do get Bad Request for MBIDs that don't exist, don't have solve for this yet, so not throwing any more as it grinds future request to a halt. This is a working version.
package/SECURITY.md CHANGED
@@ -1,14 +1,13 @@
1
- # Security Policy
1
+ # 🔐 Security Policy
2
2
 
3
3
  ## Supported Versions
4
4
 
5
- Dependebot alerts have been enabled and security patches to any dependecies will be brought to light and merged manually by maintainer.
5
+ Dependabot alerts have been enabled and security patches to any dependencies will be brought to light and merged manually by maintainer.
6
6
 
7
7
  | Version | Supported |
8
8
  | ------- | ------------------ |
9
9
  | 1.0.x | :white_check_mark: |
10
10
 
11
-
12
11
  ## Reporting a Vulnerability
13
12
 
14
13
  If you find anything at all kindly report it as bug report here on github ✌️
package/dist/config.js CHANGED
@@ -1,5 +1,30 @@
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
+ const dotenv = __importStar(require("dotenv"));
27
+ dotenv.config();
3
28
  exports.default = {
4
29
  api_key: `${process.env.LASTFM_API_KEY}`,
5
30
  app_name: `${process.env.LASTFM_APPNAME}`,
package/dist/index.js CHANGED
@@ -17,99 +17,165 @@ function LastFmApi() {
17
17
  * Can only used once (they are consumed when a session is created).
18
18
  * @returns Auth token
19
19
  */
20
- const auth = (method, user, period, limit) => {
21
- return (0, request_1.default)(method, user, period, limit);
22
- };
20
+ function auth(method, user, period, limit) {
21
+ const options = {
22
+ method,
23
+ user,
24
+ period,
25
+ limit,
26
+ };
27
+ return (0, request_1.default)(options);
28
+ }
23
29
  /**
24
30
  * GET: User profile information - LastFM
25
31
  *
26
32
  * https://www.last.fm/api/show/user.getInfo
27
33
  * @returns User profile data
28
34
  */
29
- const getInfo = (method, user, period, limit) => {
30
- return (0, request_1.default)(method, user, period, limit);
31
- };
35
+ function getInfo(method, user, period, limit) {
36
+ const options = {
37
+ method,
38
+ user,
39
+ period,
40
+ limit,
41
+ };
42
+ return (0, request_1.default)(options);
43
+ }
32
44
  /**
33
45
  * GET: Love Tracks - LastFM
34
46
  *
35
47
  * https://www.last.fm/api/show/user.getLovedTracks
36
48
  * @returns Loved Tracks;
37
49
  */
38
- const getLovedTracks = (method, user, period, limit) => {
39
- return (0, request_1.default)(method, user, period, limit);
40
- };
50
+ function getLovedTracks(method, user, period, limit) {
51
+ const options = {
52
+ method,
53
+ user,
54
+ period,
55
+ limit,
56
+ };
57
+ return (0, request_1.default)(options);
58
+ }
41
59
  /**
42
60
  * GET: Recent Tracks - LastFM
43
61
  *
44
62
  * https://www.last.fm/api/show/user.getRecentTracks
45
63
  * @returns Recent Tracks
46
64
  */
47
- const getRecentTracks = (method, user, period, limit) => {
48
- return (0, request_1.default)(method, user, period, limit);
49
- };
65
+ function getRecentTracks(method, user, period, limit) {
66
+ const options = {
67
+ method,
68
+ user,
69
+ period,
70
+ limit,
71
+ };
72
+ return (0, request_1.default)(options);
73
+ }
50
74
  /**
51
75
  * GET: Top Albums - LastFM
52
76
  *
53
77
  * https://www.last.fm/api/show/user.getTopAlbums
54
78
  * @returns Top Albums
55
79
  */
56
- const getTopAlbums = (method, user, period, limit) => {
57
- return (0, request_1.default)(method, user, period, limit);
58
- };
80
+ function getTopAlbums(method, user, period, limit) {
81
+ const options = {
82
+ method,
83
+ user,
84
+ period,
85
+ limit,
86
+ };
87
+ return (0, request_1.default)(options);
88
+ }
59
89
  /**
60
90
  * GET: Top Artist - LastFM
61
91
  *
62
92
  * https://www.last.fm/api/show/user.getTopArtists
63
93
  * @returns Top Artists
64
94
  */
65
- const getTopArtists = (method, user, period, limit) => {
66
- return (0, request_1.default)(method, user, period, limit);
67
- };
95
+ function getTopArtists(method, user, period, limit) {
96
+ const options = {
97
+ method,
98
+ user,
99
+ period,
100
+ limit,
101
+ };
102
+ return (0, request_1.default)(options);
103
+ }
68
104
  /**
69
105
  * GET: Top Tracks - LastFM
70
106
  *
71
107
  * https://www.last.fm/api/show/user.getTopTracks
72
108
  * @returns Top Tracks
73
109
  */
74
- const getTopTracks = (method, user, period, limit) => {
75
- return (0, request_1.default)(method, user, period, limit);
76
- };
110
+ function getTopTracks(method, user, period, limit) {
111
+ const options = {
112
+ method,
113
+ user,
114
+ period,
115
+ limit,
116
+ };
117
+ return (0, request_1.default)(options);
118
+ }
77
119
  /**
78
120
  * GET: Weekly album chart - LastFM
79
121
  *
80
122
  * https://www.last.fm/api/show/user.getWeeklyAlbumChart
81
123
  * @returns Weekly album chart
82
124
  */
83
- const getWeeklyAlbumChart = (method, user, period, limit) => {
84
- return (0, request_1.default)(method, user, period, limit);
85
- };
125
+ function getWeeklyAlbumChart(method, user, period, limit) {
126
+ const options = {
127
+ method,
128
+ user,
129
+ period,
130
+ limit,
131
+ };
132
+ return (0, request_1.default)(options);
133
+ }
86
134
  /**
87
135
  * GET: Weekly artist chart - LastFM
88
136
  *
89
137
  * https://www.last.fm/api/show/user.getWeeklyArtistChart
90
138
  * @returns Weekly artist chart
91
139
  */
92
- const getWeeklyArtistChart = (method, user, period, limit) => {
93
- return (0, request_1.default)(method, user, period, limit);
94
- };
140
+ function getWeeklyArtistChart(method, user, period, limit) {
141
+ const options = {
142
+ method,
143
+ user,
144
+ period,
145
+ limit,
146
+ };
147
+ return (0, request_1.default)(options);
148
+ }
95
149
  /**
96
150
  * GET: Weekly chart list - LastFM
97
151
  *
98
152
  * https://www.last.fm/api/show/user.getWeeklyChartList
99
153
  * @returns Weekly chart list
100
154
  */
101
- const getWeeklyChartList = (method, user, period, limit) => {
102
- return (0, request_1.default)(method, user, period, limit);
103
- };
155
+ function getWeeklyChartList(method, user, period, limit) {
156
+ const options = {
157
+ method,
158
+ user,
159
+ period,
160
+ limit,
161
+ };
162
+ return (0, request_1.default)(options);
163
+ }
104
164
  /**
105
165
  * GET: Weekly track chart - LastFM
106
166
  *
107
167
  * https://www.last.fm/api/show/user.getWeeklyTrackChart
108
168
  * @returns Weekly track chart
109
169
  */
110
- const getWeeklyTrackChart = (method, user, period, limit) => {
111
- return (0, request_1.default)(method, user, period, limit);
112
- };
170
+ function getWeeklyTrackChart(method, user, period, limit) {
171
+ const options = {
172
+ method,
173
+ user,
174
+ period,
175
+ limit,
176
+ };
177
+ return (0, request_1.default)(options);
178
+ }
113
179
  return {
114
180
  auth,
115
181
  config: config_1.default,
package/dist/request.d.ts CHANGED
@@ -1,2 +1,8 @@
1
- declare const request: <Response_1>(method: string, user: string, period?: string, limit?: string) => Promise<Response_1>;
1
+ interface RequestOptions {
2
+ method: string;
3
+ user?: string;
4
+ period?: string;
5
+ limit?: string;
6
+ }
7
+ declare const request: <Response_1>(options: RequestOptions) => Promise<Response_1>;
2
8
  export default request;
package/dist/request.js CHANGED
@@ -14,9 +14,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const cross_fetch_1 = __importDefault(require("cross-fetch"));
16
16
  const config_1 = __importDefault(require("./config"));
17
- const request = (method, user, period, limit) => __awaiter(void 0, void 0, void 0, function* () {
18
- const url = `
19
- ${config_1.default.base_url}?method=${method}${user ? '&user=' : ''}${user}${user ? '&user=' : ''}${user}${period ? '&period=' : ''}${period}&${limit ? '&limit=' : ''}${limit}&api_key=${config_1.default.api_key}&format=${config_1.default.format.json}`;
17
+ const buildUrl = (options) => {
18
+ const params = new URLSearchParams();
19
+ params.append('method', options.method);
20
+ if (options.user)
21
+ params.append('user', options.user);
22
+ if (options.period)
23
+ params.append('period', options.period);
24
+ if (options.limit)
25
+ params.append('limit', options.limit);
26
+ params.append('api_key', config_1.default.api_key);
27
+ params.append('format', config_1.default.format.json);
28
+ return `${config_1.default.base_url}?${params.toString()}`;
29
+ };
30
+ const request = (options) => __awaiter(void 0, void 0, void 0, function* () {
31
+ const url = buildUrl(options);
20
32
  return (yield (0, cross_fetch_1.default)(url, {
21
33
  headers: {
22
34
  'Content-Type': 'application/json',
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "lastfm-nodejs-client",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "A NodeJS wrapper client for LastFm API. Fetching public data by username using the LastFm public API",
5
5
  "main": "./dist",
6
+ "scripts": {
7
+ "build": "rimraf dist && tsc",
8
+ "clean": "rimraf dist",
9
+ "dev": "npm run clean && tsc --watch --project tsconfig.dev.json",
10
+ "test": "npx playwright test --reporter=list"
11
+ },
6
12
  "keywords": [
7
13
  "client",
8
14
  "lastFm",
@@ -16,12 +22,14 @@
16
22
  ],
17
23
  "license": "MIT",
18
24
  "dependencies": {
19
- "cross-fetch": "^3.1.5",
20
- "rimraf": "^3.0.2"
25
+ "cross-fetch": "^4.0.0",
26
+ "dotenv": "^16.3.1",
27
+ "rimraf": "^5.0.1"
21
28
  },
22
29
  "devDependencies": {
23
- "@types/node": "^18.11.7",
24
- "typescript": "^4.8.4"
30
+ "@playwright/test": "^1.37.1",
31
+ "@types/node": "^20.5.1",
32
+ "typescript": "^5.1.6"
25
33
  },
26
34
  "repository": {
27
35
  "type": "git",
@@ -30,10 +38,5 @@
30
38
  "bugs": {
31
39
  "url": "https://github.com/mannuelf/lastfm-nodejs-client/issues"
32
40
  },
33
- "homepage": "https://github.com/mannuelf/lastfm-nodejs-client#readme",
34
- "scripts": {
35
- "build": "rimraf dist && tsc",
36
- "dev": "tsc --watch",
37
- "test": "echo \"Error: no test specified\" && exit 1"
38
- }
39
- }
41
+ "homepage": "https://github.com/mannuelf/lastfm-nodejs-client#readme"
42
+ }
@@ -0,0 +1,37 @@
1
+ import { devices, PlaywrightTestConfig } from '@playwright/test';
2
+ import * as dotenv from 'dotenv'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
3
+ dotenv.config();
4
+
5
+ /**
6
+ * See https://playwright.dev/docs/test-configuration.
7
+ */
8
+ const config: PlaywrightTestConfig = {
9
+ testDir: './tests',
10
+ timeout: 30 * 1000,
11
+ expect: {
12
+ timeout: 5000,
13
+ },
14
+ fullyParallel: true,
15
+ forbidOnly: !!process.env.CI,
16
+ retries: process.env.CI ? 2 : 0,
17
+ workers: process.env.CI ? 1 : undefined,
18
+ reporter: 'html',
19
+ use: {
20
+ actionTimeout: 0,
21
+ trace: 'on-first-retry',
22
+ headless: true,
23
+ },
24
+ projects: [
25
+ {
26
+ name: 'chromium',
27
+ use: { ...devices['Desktop Chrome'] },
28
+ },
29
+ ],
30
+ // outputDir: 'test-results/',
31
+ // webServer: {
32
+ // command: 'npm run dev',
33
+ // port: 3000,
34
+ // },
35
+ };
36
+
37
+ export default config;
package/src/config.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import * as dotenv from 'dotenv';
2
+ dotenv.config();
3
+
1
4
  export default {
2
5
  api_key: `${process.env.LASTFM_API_KEY}`,
3
6
  app_name: `${process.env.LASTFM_APPNAME}`,
package/src/index.ts CHANGED
@@ -26,14 +26,20 @@ function LastFmApi() {
26
26
  * Can only used once (they are consumed when a session is created).
27
27
  * @returns Auth token
28
28
  */
29
- const auth = (
29
+ function auth(
30
30
  method: string,
31
31
  user: string,
32
32
  period: string,
33
33
  limit: string,
34
- ): Promise<AuthResponse> => {
35
- return request(method, user, period, limit);
36
- };
34
+ ): Promise<AuthResponse> {
35
+ const options = {
36
+ method,
37
+ user,
38
+ period,
39
+ limit,
40
+ }
41
+ return request<AuthResponse>(options);
42
+ }
37
43
 
38
44
  /**
39
45
  * GET: User profile information - LastFM
@@ -41,14 +47,20 @@ function LastFmApi() {
41
47
  * https://www.last.fm/api/show/user.getInfo
42
48
  * @returns User profile data
43
49
  */
44
- const getInfo = (
50
+ function getInfo(
45
51
  method: string,
46
52
  user: string,
47
53
  period: string,
48
54
  limit: string,
49
- ): Promise<UserResponse> => {
50
- return request(method, user, period, limit);
51
- };
55
+ ): Promise<UserResponse> {
56
+ const options = {
57
+ method,
58
+ user,
59
+ period,
60
+ limit,
61
+ }
62
+ return request<UserResponse>(options);
63
+ }
52
64
 
53
65
  /**
54
66
  * GET: Love Tracks - LastFM
@@ -56,14 +68,20 @@ function LastFmApi() {
56
68
  * https://www.last.fm/api/show/user.getLovedTracks
57
69
  * @returns Loved Tracks;
58
70
  */
59
- const getLovedTracks = (
71
+ function getLovedTracks(
60
72
  method: string,
61
73
  user: string,
62
74
  period: string,
63
75
  limit: string,
64
- ): Promise<LovedTracksResponse> => {
65
- return request(method, user, period, limit);
66
- };
76
+ ): Promise<LovedTracksResponse> {
77
+ const options = {
78
+ method,
79
+ user,
80
+ period,
81
+ limit,
82
+ }
83
+ return request<LovedTracksResponse>(options);
84
+ }
67
85
 
68
86
  /**
69
87
  * GET: Recent Tracks - LastFM
@@ -71,14 +89,20 @@ function LastFmApi() {
71
89
  * https://www.last.fm/api/show/user.getRecentTracks
72
90
  * @returns Recent Tracks
73
91
  */
74
- const getRecentTracks = (
92
+ function getRecentTracks(
75
93
  method: string,
76
94
  user: string,
77
95
  period: string,
78
96
  limit: string,
79
- ): Promise<RecentTracksResponse> => {
80
- return request(method, user, period, limit);
81
- };
97
+ ): Promise<RecentTracksResponse> {
98
+ const options = {
99
+ method,
100
+ user,
101
+ period,
102
+ limit,
103
+ }
104
+ return request<RecentTracksResponse>(options);
105
+ }
82
106
 
83
107
  /**
84
108
  * GET: Top Albums - LastFM
@@ -86,14 +110,20 @@ function LastFmApi() {
86
110
  * https://www.last.fm/api/show/user.getTopAlbums
87
111
  * @returns Top Albums
88
112
  */
89
- const getTopAlbums = (
113
+ function getTopAlbums(
90
114
  method: string,
91
115
  user: string,
92
116
  period: string,
93
117
  limit: string,
94
- ): Promise<TopAlbumsResponse> => {
95
- return request(method, user, period, limit);
96
- };
118
+ ): Promise<TopAlbumsResponse> {
119
+ const options = {
120
+ method,
121
+ user,
122
+ period,
123
+ limit,
124
+ }
125
+ return request<TopAlbumsResponse>(options);
126
+ }
97
127
 
98
128
  /**
99
129
  * GET: Top Artist - LastFM
@@ -101,14 +131,20 @@ function LastFmApi() {
101
131
  * https://www.last.fm/api/show/user.getTopArtists
102
132
  * @returns Top Artists
103
133
  */
104
- const getTopArtists = (
134
+ function getTopArtists(
105
135
  method: string,
106
136
  user: string,
107
137
  period: string,
108
138
  limit: string,
109
- ): Promise<TopArtistsResponse> => {
110
- return request(method, user, period, limit);
111
- };
139
+ ): Promise<TopArtistsResponse> {
140
+ const options = {
141
+ method,
142
+ user,
143
+ period,
144
+ limit,
145
+ }
146
+ return request<TopArtistsResponse>(options);
147
+ }
112
148
 
113
149
  /**
114
150
  * GET: Top Tracks - LastFM
@@ -116,14 +152,20 @@ function LastFmApi() {
116
152
  * https://www.last.fm/api/show/user.getTopTracks
117
153
  * @returns Top Tracks
118
154
  */
119
- const getTopTracks = (
155
+ function getTopTracks(
120
156
  method: string,
121
157
  user: string,
122
158
  period: string,
123
159
  limit: string,
124
- ): Promise<TopTrackResponse> => {
125
- return request(method, user, period, limit);
126
- };
160
+ ): Promise<TopTrackResponse> {
161
+ const options = {
162
+ method,
163
+ user,
164
+ period,
165
+ limit,
166
+ }
167
+ return request<TopTrackResponse>(options);
168
+ }
127
169
 
128
170
  /**
129
171
  * GET: Weekly album chart - LastFM
@@ -131,14 +173,20 @@ function LastFmApi() {
131
173
  * https://www.last.fm/api/show/user.getWeeklyAlbumChart
132
174
  * @returns Weekly album chart
133
175
  */
134
- const getWeeklyAlbumChart = (
176
+ function getWeeklyAlbumChart(
135
177
  method: string,
136
178
  user: string,
137
179
  period: string,
138
180
  limit: string,
139
- ): Promise<WeeklyAlbumChartResponse> => {
140
- return request(method, user, period, limit);
141
- };
181
+ ): Promise<WeeklyAlbumChartResponse> {
182
+ const options = {
183
+ method,
184
+ user,
185
+ period,
186
+ limit,
187
+ }
188
+ return request<WeeklyAlbumChartResponse>(options);
189
+ }
142
190
 
143
191
  /**
144
192
  * GET: Weekly artist chart - LastFM
@@ -146,14 +194,20 @@ function LastFmApi() {
146
194
  * https://www.last.fm/api/show/user.getWeeklyArtistChart
147
195
  * @returns Weekly artist chart
148
196
  */
149
- const getWeeklyArtistChart = (
197
+ function getWeeklyArtistChart(
150
198
  method: string,
151
199
  user: string,
152
200
  period: string,
153
201
  limit: string,
154
- ): Promise<WeeklyArtistChartResponse> => {
155
- return request(method, user, period, limit);
156
- };
202
+ ): Promise<WeeklyArtistChartResponse> {
203
+ const options = {
204
+ method,
205
+ user,
206
+ period,
207
+ limit,
208
+ }
209
+ return request<WeeklyArtistChartResponse>(options);
210
+ }
157
211
 
158
212
  /**
159
213
  * GET: Weekly chart list - LastFM
@@ -161,14 +215,20 @@ function LastFmApi() {
161
215
  * https://www.last.fm/api/show/user.getWeeklyChartList
162
216
  * @returns Weekly chart list
163
217
  */
164
- const getWeeklyChartList = (
218
+ function getWeeklyChartList(
165
219
  method: string,
166
220
  user: string,
167
221
  period: string,
168
222
  limit: string,
169
- ): Promise<WeeklyChartListResponse> => {
170
- return request(method, user, period, limit);
171
- };
223
+ ): Promise<WeeklyChartListResponse> {
224
+ const options = {
225
+ method,
226
+ user,
227
+ period,
228
+ limit,
229
+ }
230
+ return request<WeeklyChartListResponse>(options);
231
+ }
172
232
 
173
233
  /**
174
234
  * GET: Weekly track chart - LastFM
@@ -176,14 +236,20 @@ function LastFmApi() {
176
236
  * https://www.last.fm/api/show/user.getWeeklyTrackChart
177
237
  * @returns Weekly track chart
178
238
  */
179
- const getWeeklyTrackChart = (
239
+ function getWeeklyTrackChart(
180
240
  method: string,
181
241
  user: string,
182
242
  period: string,
183
243
  limit: string,
184
- ): Promise<WeeklyTrackChartResponse> => {
185
- return request(method, user, period, limit);
186
- };
244
+ ): Promise<WeeklyTrackChartResponse> {
245
+ const options = {
246
+ method,
247
+ user,
248
+ period,
249
+ limit,
250
+ }
251
+ return request<WeeklyTrackChartResponse>(options);
252
+ }
187
253
 
188
254
  return {
189
255
  auth,
package/src/request.ts CHANGED
@@ -1,18 +1,26 @@
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
+ const buildUrl = (options: RequestOptions): string => {
12
+ const params = new URLSearchParams();
13
+ params.append('method', options.method);
14
+ if (options.user) params.append('user', options.user);
15
+ if (options.period) params.append('period', options.period);
16
+ if (options.limit) params.append('limit', options.limit);
17
+ params.append('api_key', config.api_key);
18
+ params.append('format', config.format.json);
19
+ return `${config.base_url}?${params.toString()}`;
20
+ }
21
+
22
+ const request = async <Response>(options: RequestOptions): Promise<Response> => {
23
+ const url = buildUrl(options);
16
24
 
17
25
  return (await fetch(url, {
18
26
  headers: {
@@ -0,0 +1,21 @@
1
+ import { test, expect } from '@playwright/test';
2
+ import dotenv from 'dotenv';
3
+ import path from 'path';
4
+
5
+ dotenv.config();
6
+ dotenv.config({ path: path.resolve(__dirname, '..', process.env.CI ? '.env.example' : '.env') });
7
+
8
+ const { LASTFM_API_BASE_URL, LASTFM_API_KEY } = process.env;
9
+
10
+ let environmentVarWarning =
11
+ '❗ No environment variable found, use the .env.example file to create your own .env file with required properties and values.';
12
+
13
+ test.describe('Environment variables present and configured', async () => {
14
+ test('LASTFM_API_BASE_URL is present', async () => {
15
+ expect(LASTFM_API_BASE_URL, environmentVarWarning).toBeDefined();
16
+ });
17
+
18
+ test('LASTFM_API_KEY is present', async () => {
19
+ expect(LASTFM_API_KEY, environmentVarWarning).toBeDefined();
20
+ });
21
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": false
5
+ },
6
+ "exclude": ["tests/**/*.spec.ts", "tests/**/*.test.ts", "./playwright.config.ts"]
7
+ }
package/tsconfig.json CHANGED
@@ -1,4 +1,5 @@
1
1
  {
2
+ "exclude": ["tests/**/*.spec.ts", "tests/**/*.test.ts", "./playwright.config.ts"],
2
3
  "compilerOptions": {
3
4
  /* Visit https://aka.ms/tsconfig to read more about this file */
4
5