@khang07/zing-mp3-api 1.1.0 → 1.3.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/README.md +442 -476
- package/dist/cjs/index.cjs +302 -134
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/utils/refined.cjs +140 -0
- package/dist/cjs/utils/refined.cjs.map +1 -0
- package/dist/esm/index.js +302 -134
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/refined.js +132 -0
- package/dist/esm/utils/refined.js.map +1 -0
- package/dist/types/index.d.ts +34 -15
- package/dist/types/types/index.d.ts +7 -5
- package/dist/types/types/raw.d.ts +89 -0
- package/dist/types/types/response.d.ts +70 -0
- package/dist/types/utils/refined.d.ts +9 -0
- package/package.json +1 -2
- package/dist/types/types/fetch/response.d.ts +0 -22
- package/dist/types/types/fetch/uri.d.ts +0 -46
package/README.md
CHANGED
|
@@ -1,476 +1,442 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
import
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
###
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
import
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
import
|
|
113
|
-
import client from "@khang07/zing-mp3-api";
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
music
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
name: string;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
```ts
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
##
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
stream.pipe(fs.createWriteStream("track.mp3"));
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
main();
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
## Build
|
|
450
|
-
|
|
451
|
-
```bash
|
|
452
|
-
npm run build
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
Current scripts in the project:
|
|
456
|
-
|
|
457
|
-
```json
|
|
458
|
-
{
|
|
459
|
-
"build:esm": "tsc -p tsconfig.json",
|
|
460
|
-
"build:cjs": "rollup -c",
|
|
461
|
-
"build": "rm -rf dist && bun run build:esm && bun run build:cjs && rm -fr dist/esm/types dist/cjs/types",
|
|
462
|
-
"test": "mocha"
|
|
463
|
-
}
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
## Notes
|
|
467
|
-
|
|
468
|
-
- The default export is a preconfigured client instance.
|
|
469
|
-
- The named export is `ZingClient`.
|
|
470
|
-
- Search currently returns songs only.
|
|
471
|
-
- Video currently streams HLS `360p`.
|
|
472
|
-
- Errors are wrapped in `Lapse` for consistent handling.
|
|
473
|
-
|
|
474
|
-
## License
|
|
475
|
-
|
|
476
|
-
MIT
|
|
1
|
+
# `@khang07/zing-mp3-api`
|
|
2
|
+
|
|
3
|
+
The basic APIs provide the features of ZingMp3.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
* Search songs, videos, playlists, and artists
|
|
8
|
+
* Fetch playlist, artist, and song details
|
|
9
|
+
* Get readable streams for music and video
|
|
10
|
+
* Accept raw resource tokens or `URL` values for resource-based methods
|
|
11
|
+
* Provide a cookie jar utility through a public subpath export
|
|
12
|
+
* Ship ESM and CommonJS entry points
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @khang07/zing-mp3-api
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Public Exports
|
|
21
|
+
|
|
22
|
+
### Root export
|
|
23
|
+
|
|
24
|
+
#### Runtime exports
|
|
25
|
+
|
|
26
|
+
* `default`: a pre-created `Client` instance
|
|
27
|
+
* `Client`: the client class
|
|
28
|
+
|
|
29
|
+
#### Type exports
|
|
30
|
+
|
|
31
|
+
* `ClientOptions`
|
|
32
|
+
* `PlayList`
|
|
33
|
+
* `Artist`
|
|
34
|
+
* `Media`
|
|
35
|
+
* `SearhMedia`
|
|
36
|
+
* `SearchPlayList`
|
|
37
|
+
* `Cookies` *(type-only export from the root entry)*
|
|
38
|
+
|
|
39
|
+
### Public subpath exports
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { Cookies } from "@khang07/zing-mp3-api/utils/cookies";
|
|
43
|
+
import { createSignature } from "@khang07/zing-mp3-api/utils/encrypt";
|
|
44
|
+
import { Lapse } from "@khang07/zing-mp3-api/utils/lapse";
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Import
|
|
48
|
+
|
|
49
|
+
### ESM
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import client, { Client } from "@khang07/zing-mp3-api";
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### CommonJS
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const zing = require("@khang07/zing-mp3-api");
|
|
59
|
+
|
|
60
|
+
const client = zing.default;
|
|
61
|
+
const { Client } = zing;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Basic Usage
|
|
65
|
+
|
|
66
|
+
### Use the default client
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import client from "@khang07/zing-mp3-api";
|
|
70
|
+
|
|
71
|
+
const items = await client.searchMusic("Do For Love Bray");
|
|
72
|
+
console.log(items[0]);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Create a client
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { Client } from "@khang07/zing-mp3-api";
|
|
79
|
+
import { Cookies } from "@khang07/zing-mp3-api/utils/cookies";
|
|
80
|
+
|
|
81
|
+
const client = new Client({
|
|
82
|
+
maxLoad: 16 * 1024,
|
|
83
|
+
maxHighWaterMark: 16 * 1024,
|
|
84
|
+
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
|
|
85
|
+
jar: new Cookies()
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Fetch a playlist from a URL
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import client from "@khang07/zing-mp3-api";
|
|
93
|
+
|
|
94
|
+
const playlist = await client.playlist("https://zingmp3.vn/album/example/ZWZB9WAB.html");
|
|
95
|
+
console.log(playlist.name);
|
|
96
|
+
console.log(playlist.mediaCount);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Fetch artist details
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import client from "@khang07/zing-mp3-api";
|
|
103
|
+
|
|
104
|
+
const artist = await client.artist("https://zingmp3.vn/Obito");
|
|
105
|
+
console.log(artist.name);
|
|
106
|
+
console.log(artist.followCount);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Download a music stream
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { createWriteStream } from "node:fs";
|
|
113
|
+
import client from "@khang07/zing-mp3-api";
|
|
114
|
+
|
|
115
|
+
const items = await client.searchMusic("Do For Love Bray");
|
|
116
|
+
const stream = await client.music(items[0].id);
|
|
117
|
+
|
|
118
|
+
stream.pipe(createWriteStream("music.mp3"));
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Download a video stream
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { createWriteStream } from "node:fs";
|
|
125
|
+
import client from "@khang07/zing-mp3-api";
|
|
126
|
+
|
|
127
|
+
const items = await client.searchVideo("Do For Love Bray");
|
|
128
|
+
const stream = await client.video(items[0].id);
|
|
129
|
+
|
|
130
|
+
stream.pipe(createWriteStream("video.ts"));
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Use the immediate stream-returning methods
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { createWriteStream } from "node:fs";
|
|
137
|
+
import client from "@khang07/zing-mp3-api";
|
|
138
|
+
|
|
139
|
+
const stream = client.musicSync("ZWZB9WAB");
|
|
140
|
+
stream.pipe(createWriteStream("music.mp3"));
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Handle library errors
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import client from "@khang07/zing-mp3-api";
|
|
147
|
+
import { Lapse } from "@khang07/zing-mp3-api/utils/lapse";
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
await client.playlist("");
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error instanceof Lapse) {
|
|
153
|
+
console.error(error.name);
|
|
154
|
+
console.error(error.code);
|
|
155
|
+
console.error(error.status);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## API Reference
|
|
161
|
+
|
|
162
|
+
## `new Client(options?)`
|
|
163
|
+
|
|
164
|
+
Creates a new client instance.
|
|
165
|
+
|
|
166
|
+
### `ClientOptions`
|
|
167
|
+
|
|
168
|
+
| Field | Type | Default |
|
|
169
|
+
| ------------------ | --------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
170
|
+
| `maxLoad` | `number` | `1024 * 1024` |
|
|
171
|
+
| `maxHighWaterMark` | `number` | `16 * 1024` |
|
|
172
|
+
| `userAgent` | `string` | `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3` |
|
|
173
|
+
| `jar` | `Cookies` | `new Cookies()` |
|
|
174
|
+
|
|
175
|
+
`maxLoad` is passed to Axios as `maxRate`.
|
|
176
|
+
|
|
177
|
+
`maxHighWaterMark` is used as the `highWaterMark` when `musicSync()` and `videoSync()` create a `PassThrough` stream.
|
|
178
|
+
|
|
179
|
+
## `Client.getIDFromURL(url)`
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
static getIDFromURL(url: string): string
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Extracts a resource token from a ZingMp3 URL.
|
|
186
|
+
|
|
187
|
+
It throws `ERROR_INVALID_URL` when the input is not a non-empty string or when no token can be extracted.
|
|
188
|
+
|
|
189
|
+
## Instance Methods
|
|
190
|
+
|
|
191
|
+
| Method | Returns | Description |
|
|
192
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
193
|
+
| `video(videoID)` | `Promise<Readable>` | Fetches a video stream. Accepts a raw token, URL string, or `URL`. |
|
|
194
|
+
| `videoSync(videoID)` | `Readable` | Returns a `PassThrough` immediately and pipes the fetched video stream into it. |
|
|
195
|
+
| `music(musicID)` | `Promise<Readable>` | Fetches a music stream. Accepts a raw token, URL string, or `URL`. |
|
|
196
|
+
| `musicSync(musicID)` | `Readable` | Returns a `PassThrough` immediately and pipes the fetched music stream into it. |
|
|
197
|
+
| `playlist(playlistID)` | `Promise<PlayList>` | Fetches playlist details. Accepts a raw token, URL string, or `URL`. |
|
|
198
|
+
| `artist(aliasID)` | `Promise<Artist>` | Fetches artist details. Accepts an alias token, URL string, or `URL`. |
|
|
199
|
+
| `mediaDetails(mediaID)` | `Promise<Media>` | Fetches song details. Accepts a raw token, URL string, or `URL`. |
|
|
200
|
+
| `searchMusic(query)` | `Promise<SearhMedia[]>` | Searches songs. |
|
|
201
|
+
| `searchVideo(query)` | `Promise<SearhMedia[]>` | Searches videos. |
|
|
202
|
+
| `searchList(query)` | `Promise<SearchPlayList[]>` | Searches playlists. |
|
|
203
|
+
| `searchArtist(query)` | `Promise<SearchArtist[]>` | Searches artists. |
|
|
204
|
+
|
|
205
|
+
### Method notes
|
|
206
|
+
|
|
207
|
+
* `video()` selects `720p` first, then falls back to `360p`.
|
|
208
|
+
* `music()` selects `320` first when available and not equal to `"VIP"`, then falls back to `128`.
|
|
209
|
+
* When the music API returns `err === -1150`, `music()` retries the extra music endpoint up to 4 times and throws `ERROR_MUSIC_VIP_ONLY` if it still cannot resolve a playable URL.
|
|
210
|
+
* `searchMusic()`, `searchVideo()`, `searchList()`, and `searchArtist()` always request `page: 1` and `count: 20`.
|
|
211
|
+
|
|
212
|
+
## Public Types
|
|
213
|
+
|
|
214
|
+
### `Artist`
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
interface Artist {
|
|
218
|
+
alias: string;
|
|
219
|
+
birthday: string;
|
|
220
|
+
biography: string;
|
|
221
|
+
followCount: number;
|
|
222
|
+
name: string;
|
|
223
|
+
national: string;
|
|
224
|
+
realname: string;
|
|
225
|
+
thumbnail: {
|
|
226
|
+
w240: string;
|
|
227
|
+
w600: string;
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### `Media`
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
interface Media {
|
|
236
|
+
id: string;
|
|
237
|
+
name: string;
|
|
238
|
+
alias: string;
|
|
239
|
+
isOffical: boolean;
|
|
240
|
+
username: string;
|
|
241
|
+
artists: Array<{
|
|
242
|
+
alias: string;
|
|
243
|
+
followCount?: number;
|
|
244
|
+
name: string;
|
|
245
|
+
thumbnail: {
|
|
246
|
+
w240: string;
|
|
247
|
+
w600: string;
|
|
248
|
+
};
|
|
249
|
+
}>;
|
|
250
|
+
isWorldWide: boolean;
|
|
251
|
+
thumbnail: {
|
|
252
|
+
w94: string;
|
|
253
|
+
w240: string;
|
|
254
|
+
};
|
|
255
|
+
duration: number;
|
|
256
|
+
isPrivate: boolean;
|
|
257
|
+
releaseDate: number;
|
|
258
|
+
album: {
|
|
259
|
+
id: string;
|
|
260
|
+
name: string;
|
|
261
|
+
isOffical: boolean;
|
|
262
|
+
releaseDate: string;
|
|
263
|
+
releasedAt: number;
|
|
264
|
+
artists: Array<{
|
|
265
|
+
alias: string;
|
|
266
|
+
followCount?: number;
|
|
267
|
+
name: string;
|
|
268
|
+
thumbnail: {
|
|
269
|
+
w240: string;
|
|
270
|
+
w600: string;
|
|
271
|
+
};
|
|
272
|
+
}>;
|
|
273
|
+
thumbnail: {
|
|
274
|
+
w165: string;
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
hasLyric: boolean;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### `SearhMedia`
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
type SearchMedia = Omit<Media, 'album' | 'isPrivate' | 'releaseDate'>;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### `PlayList`
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
interface PlayList {
|
|
291
|
+
id: string;
|
|
292
|
+
name: string;
|
|
293
|
+
alias: string;
|
|
294
|
+
artists: Array<{
|
|
295
|
+
alias: string;
|
|
296
|
+
followCount?: number;
|
|
297
|
+
name: string;
|
|
298
|
+
thumbnail: {
|
|
299
|
+
w240: string;
|
|
300
|
+
w600: string;
|
|
301
|
+
};
|
|
302
|
+
}>;
|
|
303
|
+
description: string;
|
|
304
|
+
duration: number;
|
|
305
|
+
isOffical: boolean;
|
|
306
|
+
isPrivate: boolean;
|
|
307
|
+
isSingle: boolean;
|
|
308
|
+
likeCount: number;
|
|
309
|
+
listenCount: number;
|
|
310
|
+
media: Media[];
|
|
311
|
+
mediaCount: number;
|
|
312
|
+
releaseDate: string;
|
|
313
|
+
releasedAt: number;
|
|
314
|
+
thumbnail: {
|
|
315
|
+
w165: string;
|
|
316
|
+
w320: string;
|
|
317
|
+
};
|
|
318
|
+
updatedAt: number;
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### `SearchPlayList`
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
type SearchPlayList = Omit<
|
|
326
|
+
PlayList,
|
|
327
|
+
"updatedAt" | "mediaCount" | "listenCount" | "likeCount" | "duration" | "description" | "media"
|
|
328
|
+
>;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## `Cookies`
|
|
332
|
+
|
|
333
|
+
Import from `@khang07/zing-mp3-api/utils/cookies`.
|
|
334
|
+
|
|
335
|
+
### Methods
|
|
336
|
+
|
|
337
|
+
| Method | Returns |
|
|
338
|
+
| -------------------------------------- | ------------------------ |
|
|
339
|
+
| `setCookie(setCookie, requestUrl)` | `void` |
|
|
340
|
+
| `setCookies(setCookies, requestUrl)` | `void` |
|
|
341
|
+
| `getCookies(requestUrl)` | `CookieRecord[]` |
|
|
342
|
+
| `getCookieHeader(requestUrl)` | `string` |
|
|
343
|
+
| `applyToHeaders(requestUrl, headers?)` | `Record<string, string>` |
|
|
344
|
+
| `deleteCookie(domain, path, name)` | `void` |
|
|
345
|
+
| `cleanup()` | `void` |
|
|
346
|
+
| `toJSON()` | `CookieRecord[]` |
|
|
347
|
+
| `fromJSON(cookies)` | `void` |
|
|
348
|
+
|
|
349
|
+
### Cookie record shape
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
interface CookieRecord {
|
|
353
|
+
name: string;
|
|
354
|
+
value: string;
|
|
355
|
+
domain: string;
|
|
356
|
+
path: string;
|
|
357
|
+
expiresAt?: number;
|
|
358
|
+
secure: boolean;
|
|
359
|
+
httpOnly: boolean;
|
|
360
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
361
|
+
hostOnly: boolean;
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Example
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
import { Cookies } from "@khang07/zing-mp3-api/utils/cookies";
|
|
369
|
+
|
|
370
|
+
const jar = new Cookies();
|
|
371
|
+
jar.setCookie("sid=abc; Path=/; HttpOnly", "https://zingmp3.vn/");
|
|
372
|
+
|
|
373
|
+
console.log(jar.getCookieHeader("https://zingmp3.vn/"));
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## `createSignature(uri, params, secret)`
|
|
377
|
+
|
|
378
|
+
Import from `@khang07/zing-mp3-api/utils/encrypt`.
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
function createSignature(uri: string, params: string, secret: string): string
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Generates the request signature used by the client.
|
|
385
|
+
|
|
386
|
+
## `Lapse`
|
|
387
|
+
|
|
388
|
+
Import from `@khang07/zing-mp3-api/utils/lapse`.
|
|
389
|
+
|
|
390
|
+
```ts
|
|
391
|
+
class Lapse extends Error {
|
|
392
|
+
code: string;
|
|
393
|
+
status?: number;
|
|
394
|
+
cause?: unknown;
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Constructor
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
new Lapse(message: string, code: string, status?: number, cause?: unknown)
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Properties
|
|
405
|
+
|
|
406
|
+
* `name`: always set to `"ZING_MP3_ERROR"`
|
|
407
|
+
* `message`: inherited from `Error`
|
|
408
|
+
* `code`: library error code
|
|
409
|
+
* `status`: optional status or API error value
|
|
410
|
+
* `cause`: optional original error or response payload
|
|
411
|
+
|
|
412
|
+
## Error Codes
|
|
413
|
+
|
|
414
|
+
| Code | Used by |
|
|
415
|
+
| ---------------------------- | ------------------------------------------------------------------ |
|
|
416
|
+
| `ERROR_INVALID_URL` | `Client.getIDFromURL()` |
|
|
417
|
+
| `ERROR_INVALID_ID` | `video()`, `music()`, `playlist()`, `artist()`, `mediaDetails()` |
|
|
418
|
+
| `ERROR_INVALID_QUERY` | `searchMusic()`, `searchVideo()`, `searchList()`, `searchArtist()` |
|
|
419
|
+
| `ERROR_VIDEO_NOT_FOUND` | `video()` |
|
|
420
|
+
| `ERROR_VIDEO_FETCH` | `video()`, `videoSync()` |
|
|
421
|
+
| `ERROR_MUSIC_VIP_ONLY` | `music()` |
|
|
422
|
+
| `ERROR_MUSIC_FETCH` | `music()`, `musicSync()` |
|
|
423
|
+
| `ERROR_PLAYLIST_NOT_FOUND` | `playlist()` |
|
|
424
|
+
| `ERROR_PLAYLIST_FETCH` | `playlist()` |
|
|
425
|
+
| `ERROR_ARTIST_NOT_FOUND` | `artist()` |
|
|
426
|
+
| `ERROR_ARTIST_FETCH` | `artist()` |
|
|
427
|
+
| `ERROR_MEDIA_NOT_FOUND` | `mediaDetails()` |
|
|
428
|
+
| `ERROR_MEDIA_FETCH` | `mediaDetails()` |
|
|
429
|
+
| `ERROR_SEARCH_FAILED` | `searchMusic()`, `searchVideo()`, `searchList()`, `searchArtist()` |
|
|
430
|
+
| `ERROR_SEARCH_FETCH` | `searchMusic()`, `searchVideo()`, `searchList()`, `searchArtist()` |
|
|
431
|
+
| `ERROR_STREAM_URL_NOT_FOUND` | `video()`, `music()` |
|
|
432
|
+
| `ERROR_STREAM_DOWNLOAD` | `video()`, `videoSync()`, `music()`, `musicSync()` |
|
|
433
|
+
|
|
434
|
+
## Notes
|
|
435
|
+
|
|
436
|
+
* The root entry exports `Cookies` as a type only. To construct a cookie jar, import `Cookies` from `@khang07/zing-mp3-api/utils/cookies`.
|
|
437
|
+
* The root entry exports the type name `SearhMedia` exactly as written in source.
|
|
438
|
+
* `searchArtist()` is a public method, but its `SearchArtist` type is not re-exported from the root entry.
|
|
439
|
+
* No test, example, or demo files were included in the provided source bundle.
|
|
440
|
+
|
|
441
|
+
## License
|
|
442
|
+
[MIT](https://github.com/GiaKhang1810/zing-mp3-api?tab=MIT-1-ov-file)
|