@sansenjian/qq-music-api 2.1.1 → 2.2.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.
- package/.babelrc +4 -0
- package/.eslintrc.json +20 -19
- package/AGENTS.md +153 -0
- package/README.md +162 -136
- package/{app.js → app.ts} +24 -31
- package/config/user-info.ts +71 -0
- package/index.ts +1 -0
- package/{jest.config.js → jest.config.ts} +19 -7
- package/middlewares/koa-cors.ts +81 -0
- package/module/apis/UCommon/UCommon.ts +13 -0
- package/module/apis/album/getAlbumInfo.ts +22 -0
- package/module/apis/comments/getComments.ts +23 -0
- package/module/apis/digitalAlbum/getDigitalAlbumLists.ts +23 -0
- package/module/apis/downloadQQMusic.ts +51 -0
- package/module/apis/music/getLyric.ts +34 -0
- package/module/apis/mv/getMvByTag.ts +24 -0
- package/module/apis/radio/getRadioLists.ts +27 -0
- package/module/apis/rank/getTopLists.ts +37 -0
- package/module/apis/search/getHotKey.ts +24 -0
- package/module/apis/search/getSearchByKey.ts +31 -0
- package/module/apis/search/getSmartbox.ts +43 -0
- package/module/apis/singers/getSimilarSinger.ts +25 -0
- package/module/apis/singers/getSingerDesc.ts +25 -0
- package/module/apis/singers/getSingerMv.ts +24 -0
- package/module/apis/singers/getSingerStarNum.ts +24 -0
- package/module/apis/songLists/songListCategories.ts +22 -0
- package/module/apis/songLists/songListDetail.ts +27 -0
- package/module/apis/songLists/songLists.ts +35 -0
- package/module/apis/u_common.ts +29 -0
- package/module/apis/user/checkQQLoginQr.ts +230 -0
- package/module/apis/user/getQQLoginQr.ts +28 -0
- package/module/apis/user/getUserAvatar.ts +32 -0
- package/module/apis/user/getUserLikedSongs.ts +145 -0
- package/module/apis/user/getUserPlaylists.ts +163 -0
- package/module/apis/y_common.ts +44 -0
- package/module/config.ts +24 -0
- package/module/index.ts +95 -0
- package/package.json +25 -6
- package/pnpm-workspace.yaml +2 -0
- package/public/index.html +411 -29
- package/routers/context/batchGetSongInfo.ts +60 -0
- package/routers/context/batchGetSongLists.ts +46 -0
- package/routers/context/checkQQLoginQr.ts +19 -0
- package/routers/context/{cookies.js → cookies.ts} +14 -12
- package/routers/context/getAlbumInfo.ts +31 -0
- package/routers/context/getComments.ts +51 -0
- package/routers/context/getDigitalAlbumLists.ts +18 -0
- package/routers/context/getDownloadQQMusic.ts +17 -0
- package/routers/context/getHotkey.ts +25 -0
- package/routers/context/getImageUrl.ts +29 -0
- package/routers/context/getLyric.ts +32 -0
- package/routers/context/getMusicPlay.ts +102 -0
- package/routers/context/getMv.ts +61 -0
- package/routers/context/getMvByTag.ts +18 -0
- package/routers/context/getMvPlay.ts +114 -0
- package/routers/context/getNewDisks.ts +58 -0
- package/routers/context/getQQLoginQr.ts +16 -0
- package/routers/context/getRadioLists.ts +18 -0
- package/routers/context/getRanks.ts +67 -0
- package/routers/context/getRecommend.ts +92 -0
- package/routers/context/getSearchByKey.ts +34 -0
- package/routers/context/getSimilarSinger.ts +29 -0
- package/routers/context/getSingerAlbum.ts +58 -0
- package/routers/context/getSingerDesc.ts +30 -0
- package/routers/context/getSingerHotsong.ts +58 -0
- package/routers/context/getSingerList.ts +56 -0
- package/routers/context/getSingerMv.ts +41 -0
- package/routers/context/getSingerStarNum.ts +29 -0
- package/routers/context/getSmartbox.ts +27 -0
- package/routers/context/getSongInfo.ts +51 -0
- package/routers/context/{getSongListCategories.js → getSongListCategories.ts} +5 -4
- package/routers/context/getSongListDetail.ts +22 -0
- package/routers/context/getSongLists.ts +30 -0
- package/routers/context/getTicketInfo.ts +51 -0
- package/routers/context/getTopLists.ts +18 -0
- package/routers/context/getUserAvatar.ts +53 -0
- package/routers/context/getUserLikedSongs.ts +28 -0
- package/routers/context/getUserPlaylists.ts +29 -0
- package/routers/context/index.ts +87 -0
- package/routers/{router.js → router.ts} +7 -55
- package/routers/types.ts +18 -0
- package/routers/util.ts +231 -0
- package/tests/integration/api/api.test.ts +852 -0
- package/tests/integration/middleware/{cors.test.js → cors.test.ts} +7 -3
- package/tests/setup/jest.setup.ts +15 -0
- package/tests/setup/testUtils.ts +35 -0
- package/tests/unit/util/request.test.ts +177 -0
- package/tsconfig.json +20 -0
- package/tsconfig.test.json +8 -0
- package/types/api.ts +105 -0
- package/types/global.d.ts +26 -0
- package/types/index.d.ts +97 -0
- package/util/apiResponse.ts +97 -0
- package/util/colors.ts +31 -0
- package/util/cookie.ts +40 -0
- package/util/{loginUtils.js → loginUtils.ts} +3 -5
- package/util/lyricParse.ts +86 -0
- package/util/request.ts +141 -0
- package/.github/FUNDING.yml +0 -12
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
- package/.github/ISSUE_TEMPLATE/custom.md +0 -24
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/config/user-info.js +0 -42
- package/index.js +0 -1
- package/middlewares/koa-cors.js +0 -97
- package/module/apis/UCommon/UCommon.js +0 -6
- package/module/apis/album/getAlbumInfo.js +0 -33
- package/module/apis/comments/getComments.js +0 -35
- package/module/apis/digitalAlbum/getDigitalAlbumLists.js +0 -34
- package/module/apis/downloadQQMusic.js +0 -41
- package/module/apis/music/getLyric.js +0 -41
- package/module/apis/mv/getMvByTag.js +0 -35
- package/module/apis/radio/getRadioLists.js +0 -38
- package/module/apis/rank/getTopLists.js +0 -44
- package/module/apis/search/getHotKey.js +0 -35
- package/module/apis/search/getSearchByKey.js +0 -45
- package/module/apis/search/getSmartbox.js +0 -34
- package/module/apis/singers/getSimilarSinger.js +0 -36
- package/module/apis/singers/getSingerDesc.js +0 -37
- package/module/apis/singers/getSingerMv.js +0 -35
- package/module/apis/singers/getSingerStarNum.js +0 -35
- package/module/apis/songLists/songListCategories.js +0 -33
- package/module/apis/songLists/songListDetail.js +0 -38
- package/module/apis/songLists/songLists.js +0 -41
- package/module/apis/u_common.js +0 -17
- package/module/apis/user/checkQQLoginQr.js +0 -125
- package/module/apis/user/getQQLoginQr.js +0 -17
- package/module/apis/y_common.js +0 -27
- package/module/config.js +0 -31
- package/module/index.js +0 -82
- package/routers/context/batchGetSongInfo.js +0 -59
- package/routers/context/batchGetSongLists.js +0 -50
- package/routers/context/checkQQLoginQr.js +0 -17
- package/routers/context/getAlbumInfo.js +0 -27
- package/routers/context/getComments.js +0 -51
- package/routers/context/getDigitalAlbumLists.js +0 -14
- package/routers/context/getDownloadQQMusic.js +0 -14
- package/routers/context/getHotkey.js +0 -14
- package/routers/context/getImageUrl.js +0 -34
- package/routers/context/getLyric.js +0 -26
- package/routers/context/getMusicPlay.js +0 -116
- package/routers/context/getMv.js +0 -56
- package/routers/context/getMvByTag.js +0 -15
- package/routers/context/getMvPlay.js +0 -128
- package/routers/context/getNewDisks.js +0 -50
- package/routers/context/getQQLoginQr.js +0 -12
- package/routers/context/getRadioLists.js +0 -14
- package/routers/context/getRanks.js +0 -103
- package/routers/context/getRecommend.js +0 -86
- package/routers/context/getSearchByKey.js +0 -33
- package/routers/context/getSimilarSinger.js +0 -25
- package/routers/context/getSingerAlbum.js +0 -52
- package/routers/context/getSingerDesc.js +0 -25
- package/routers/context/getSingerHotsong.js +0 -52
- package/routers/context/getSingerList.js +0 -51
- package/routers/context/getSingerMv.js +0 -32
- package/routers/context/getSingerStarNum.js +0 -24
- package/routers/context/getSmartbox.js +0 -24
- package/routers/context/getSongInfo.js +0 -49
- package/routers/context/getSongListDetail.js +0 -25
- package/routers/context/getSongLists.js +0 -32
- package/routers/context/getTicketInfo.js +0 -45
- package/routers/context/getTopLists.js +0 -15
- package/routers/context/index.js +0 -74
- package/tests/integration/api/api.test.js +0 -116
- package/tests/setup/jest.setup.js +0 -46
- package/tests/setup/testUtils.js +0 -106
- package/tests/unit/util/lyricParse.test.js +0 -97
- package/tests/unit/util/request.test.js +0 -66
- package/util/colors.js +0 -16
- package/util/cookie.js +0 -22
- package/util/lyricParse.js +0 -67
- package/util/request.js +0 -57
package/.babelrc
CHANGED
package/.eslintrc.json
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"commonjs": true,
|
|
5
|
+
"es2021": true,
|
|
6
|
+
"node": true
|
|
7
|
+
},
|
|
8
|
+
"extends": ["eslint:recommended", "standard"],
|
|
9
|
+
"parserOptions": {
|
|
10
|
+
"ecmaVersion": "latest"
|
|
11
|
+
},
|
|
12
|
+
"plugins": ["n"],
|
|
13
|
+
"rules": {
|
|
14
|
+
"indent": ["error", "tab"],
|
|
15
|
+
"no-tabs": "off",
|
|
16
|
+
"linebreak-style": ["error", "unix"],
|
|
17
|
+
"quotes": ["error", "single"],
|
|
18
|
+
"semi": ["error", "always"],
|
|
19
|
+
"camelcase": "off"
|
|
20
|
+
},
|
|
21
|
+
"ignorePatterns": ["jest.config.js"]
|
|
21
22
|
}
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## 项目概览
|
|
4
|
+
|
|
5
|
+
这是一个基于 Koa 的 QQ 音乐 API 服务项目,当前代码库已完成从 JavaScript 到 TypeScript 的迁移。
|
|
6
|
+
|
|
7
|
+
- 运行时:Node.js 20+
|
|
8
|
+
- 开发语言:TypeScript
|
|
9
|
+
- Web 框架:Koa 2
|
|
10
|
+
- 路由系统:@koa/router
|
|
11
|
+
- 文档系统:VitePress
|
|
12
|
+
- 测试框架:Jest
|
|
13
|
+
|
|
14
|
+
## 启动与构建
|
|
15
|
+
|
|
16
|
+
### 安装依赖
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 开发模式
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm run dev
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
默认启动入口为 `app.ts`,默认端口为 `3200`。
|
|
29
|
+
|
|
30
|
+
### 生产构建
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm run build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 生产运行
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm run start
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 常用命令
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm run dev # 本地开发
|
|
46
|
+
npm run build # TypeScript 编译
|
|
47
|
+
npm run start # 运行 dist/app.js
|
|
48
|
+
npm run test # 运行测试
|
|
49
|
+
npm run test:watch # 测试监听模式
|
|
50
|
+
npm run test:coverage # 测试覆盖率
|
|
51
|
+
npm run docs:dev # 启动文档站点
|
|
52
|
+
npm run docs:build # 构建文档
|
|
53
|
+
npm run eslint # 执行 ESLint 自动修复
|
|
54
|
+
npm run prettier # 执行 Prettier 格式化
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 目录结构
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
app.ts 应用启动入口
|
|
61
|
+
index.ts 包导出入口
|
|
62
|
+
module/ API 请求封装层
|
|
63
|
+
routers/ HTTP 控制器与路由注册
|
|
64
|
+
middlewares/ Koa 中间件
|
|
65
|
+
util/ 通用工具函数
|
|
66
|
+
config/ 运行时配置
|
|
67
|
+
types/ 全局类型与公共类型定义
|
|
68
|
+
docs/ VitePress 文档站点
|
|
69
|
+
tests/ 单元测试与集成测试
|
|
70
|
+
public/ 静态资源
|
|
71
|
+
scripts/ 辅助脚本
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 分层说明
|
|
75
|
+
|
|
76
|
+
### module/
|
|
77
|
+
|
|
78
|
+
负责直接请求 QQ 音乐相关接口,通常只处理:
|
|
79
|
+
|
|
80
|
+
- 请求参数拼装
|
|
81
|
+
- 调用上游接口
|
|
82
|
+
- 基础数据格式转换
|
|
83
|
+
- 返回统一响应结构
|
|
84
|
+
|
|
85
|
+
### routers/context/
|
|
86
|
+
|
|
87
|
+
负责 HTTP 层控制器逻辑,通常只处理:
|
|
88
|
+
|
|
89
|
+
- 读取 `ctx.query` 或 `ctx.request.body`
|
|
90
|
+
- 参数校验
|
|
91
|
+
- 调用 `module/` 中对应能力
|
|
92
|
+
- 设置 `ctx.body` 与 `ctx.status`
|
|
93
|
+
|
|
94
|
+
### routers/router.ts
|
|
95
|
+
|
|
96
|
+
负责统一注册所有路由。
|
|
97
|
+
|
|
98
|
+
### util/
|
|
99
|
+
|
|
100
|
+
放置跨模块复用的通用逻辑,例如响应包装、颜色输出等。
|
|
101
|
+
|
|
102
|
+
## 编码约定
|
|
103
|
+
|
|
104
|
+
1. 新增功能时,优先保持现有目录分层,不要把路由逻辑和接口请求逻辑混写。
|
|
105
|
+
2. 新增接口时,通常需要同时补充:
|
|
106
|
+
- `module/apis/...` 中的接口实现
|
|
107
|
+
- `routers/context/...` 中的控制器
|
|
108
|
+
- `routers/context/index.ts` 或相关导出
|
|
109
|
+
- `routers/router.ts` 中的路由注册
|
|
110
|
+
- 必要时补充文档与测试
|
|
111
|
+
3. 统一使用 TypeScript,避免继续引入新的 `.js` 业务文件。
|
|
112
|
+
4. 尽量复用已有类型定义,公共类型优先放到 `types/`。
|
|
113
|
+
5. 保持返回结构一致,优先复用已有响应工具。
|
|
114
|
+
6. 修改全局配置或 Cookie 相关逻辑时,注意兼容扫码登录相关接口。
|
|
115
|
+
|
|
116
|
+
## 测试与验证
|
|
117
|
+
|
|
118
|
+
提交前建议至少执行:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm run build
|
|
122
|
+
npm run test
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
如果修改了文档,再执行:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm run docs:build
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
如果修改了格式或风格敏感文件,再执行:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm run eslint
|
|
135
|
+
npm run prettier
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 关键注意事项
|
|
139
|
+
|
|
140
|
+
1. 项目默认端口为 `3200`。
|
|
141
|
+
2. 生产启动依赖 `dist/` 目录,因此发布前必须先执行构建。
|
|
142
|
+
3. 当前仓库包含扫码登录相关接口实现,不要在未理解流程前随意调整登录状态字段。
|
|
143
|
+
4. 文档内容位于 `docs/`,接口能力变更时要同步更新文档。
|
|
144
|
+
5. 现有测试以 Jest 为主,新增行为建议补充对应测试。
|
|
145
|
+
|
|
146
|
+
## 建议的开发流程
|
|
147
|
+
|
|
148
|
+
1. 阅读相关模块现有实现。
|
|
149
|
+
2. 在 `module/` 增加或调整接口能力。
|
|
150
|
+
3. 在 `routers/context/` 接入 HTTP 控制器。
|
|
151
|
+
4. 在路由层完成注册。
|
|
152
|
+
5. 补充类型、测试与文档。
|
|
153
|
+
6. 执行构建和测试,确认无误后再提交。
|
package/README.md
CHANGED
|
@@ -6,196 +6,222 @@
|
|
|
6
6
|
|
|
7
7
|
  
|
|
8
8
|
<br />
|
|
9
|
-

|
|
10
10
|
<br />
|
|
11
11
|
      
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
> 🍴 本项目 Fork 自 [Rain120/qq-music-api](https://github.com/Rain120/qq-music-api),原项目已停止维护,此版本持续更新中
|
|
16
|
-
>
|
|
17
|
-
>
|
|
15
|
+
> 🍴 本项目 Fork 自 [Rain120/qq-music-api](https://github.com/Rain120/qq-music-api),原项目已停止维护,此版本持续更新中
|
|
16
|
+
> 基于 Koa 2 与 TypeScript 的 QQ 音乐 API 服务,包含扫码登录、用户头像、MV 播放地址、批量接口等能力。
|
|
17
|
+
> 当前代码仅供学习与研究使用,不可做商业用途。
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## 项目概览
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
- 运行时:Node.js 20+
|
|
22
|
+
- 服务框架:Koa 2
|
|
23
|
+
- 开发语言:TypeScript
|
|
24
|
+
- 路由系统:[@koa/router](package.json:53)
|
|
25
|
+
- 文档系统:[`VitePress`](package.json:100)
|
|
26
|
+
- 测试框架:[`Jest`](package.json:89)
|
|
27
|
+
- 默认端口:`3200`
|
|
28
|
+
|
|
29
|
+
## API 结构图
|
|
30
|
+
|
|
31
|
+
> 当前版本已包含扫码登录相关接口,并已完成 TypeScript 迁移。
|
|
22
32
|
|
|
23
33
|

|
|
24
34
|
|
|
25
|
-
📖 **详细 API
|
|
35
|
+
📖 **详细 API 文档**: [查看完整 API 文档](https://sansenjian.github.io/qq-music-api/)
|
|
26
36
|
|
|
27
|
-
|
|
37
|
+
## 环境要求
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
本项目基于 `Koa 2 + TypeScript`,需要 Node.js 20.0.0+。
|
|
30
40
|
|
|
31
|
-
```
|
|
41
|
+
```bash
|
|
32
42
|
node -v
|
|
33
43
|
```
|
|
34
44
|
|
|
35
|
-
|
|
45
|
+
## 安装
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
### 方式一:克隆仓库
|
|
48
|
+
|
|
49
|
+
```bash
|
|
39
50
|
git clone git@github.com:sansenjian/qq-music-api.git
|
|
40
51
|
cd qq-music-api
|
|
41
52
|
npm install
|
|
42
53
|
```
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
### 方式二:NPM 安装
|
|
56
|
+
|
|
57
|
+
```bash
|
|
46
58
|
npm install @sansenjian/qq-music-api
|
|
47
59
|
```
|
|
48
60
|
|
|
49
61
|
在项目中使用:
|
|
62
|
+
|
|
50
63
|
```javascript
|
|
51
|
-
// 启动 API 服务
|
|
52
64
|
const { spawn } = require('child_process');
|
|
53
65
|
const path = require('path');
|
|
54
66
|
|
|
55
67
|
const qqMusicPath = path.join(__dirname, 'node_modules', '@sansenjian/qq-music-api', 'app.js');
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
|
|
69
|
+
spawn('node', [qqMusicPath], {
|
|
70
|
+
env: { ...process.env, PORT: '3200' },
|
|
71
|
+
stdio: 'inherit',
|
|
59
72
|
});
|
|
60
73
|
```
|
|
61
74
|
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
// npm i -g nodemon
|
|
65
|
-
npm run start
|
|
75
|
+
## 项目启动
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
项目监听端口是 `3200`
|
|
71
|
-
|
|
72
|
-
### 📋 依赖更新 (2026-03)
|
|
73
|
-
|
|
74
|
-
本项目已完成依赖现代化升级,主要变更如下:
|
|
75
|
-
|
|
76
|
-
**生产依赖**
|
|
77
|
-
| 依赖 | 版本 | 说明 |
|
|
78
|
-
|-----|------|-----|
|
|
79
|
-
| axios | ^1.6.0 | 修复安全漏洞 CVE-2021-3749 |
|
|
80
|
-
| koa | ^2.15.0 | 框架更新 |
|
|
81
|
-
| koa-bodyparser | ^4.4.0 | 解析器更新 |
|
|
82
|
-
| @koa/router | ^15.3.1 | 替代 koa-router |
|
|
83
|
-
| koa-static | ^5.0.0 | 静态文件服务 |
|
|
84
|
-
| date-fns | ^4.1.0 | 日期处理库 (轻量级) |
|
|
85
|
-
|
|
86
|
-
**开发依赖**
|
|
87
|
-
| 依赖 | 版本 | 说明 |
|
|
88
|
-
|-----|------|-----|
|
|
89
|
-
| eslint | ^8.56.0 | 代码检查 |
|
|
90
|
-
| eslint-config-standard | ^17.0.0 | 标准配置 |
|
|
91
|
-
| prettier | ^3.0.0 | 代码格式化 |
|
|
92
|
-
| husky | ^9.0.0 | Git 钩子 |
|
|
93
|
-
| lint-staged | ^15.0.0 | 暂存区检查 |
|
|
94
|
-
| @commitlint/* | ^18.0.0 | 提交信息规范 |
|
|
95
|
-
| @babel/* | ^7.23.0 | 编译工具 |
|
|
96
|
-
| nodemon | ^3.0.0 | 开发热重载 |
|
|
97
|
-
| vitepress | ^1.6.4 | 文档工具 (基于 Vite) |
|
|
98
|
-
| vue | ^3.5.29 | 渐进式 JS 框架 |
|
|
99
|
-
|
|
100
|
-
**已移除的依赖**
|
|
101
|
-
- `colors` - 存在安全问题,已用 chalk 替代
|
|
102
|
-
- `moment` - 已用 date-fns 替代
|
|
103
|
-
- `dayjs` - 已用 date-fns 替代 (更小的打包体积)
|
|
104
|
-
- `docsify-cli` - 已用 vitepress 替代 (更好的性能和功能)
|
|
105
|
-
- `lodash.get` - 已用原生可选链 `?.` 替代
|
|
106
|
-
- `eslint-plugin-node` - 已用 eslint-plugin-n 替代
|
|
107
|
-
- `eslint-plugin-standard` - 已集成到 eslint-config-standard
|
|
108
|
-
|
|
109
|
-
### 功能特性
|
|
110
|
-
|
|
111
|
-
#### 🎵 音乐播放
|
|
112
|
-
- ✅ **歌曲播放链接** - 获取 QQ 音乐歌曲的播放地址
|
|
113
|
-
- ✅ **歌曲与专辑图片** - 获取歌曲封面和专辑 artwork 图片
|
|
114
|
-
- ✅ **歌曲歌词** - 获取歌曲的歌词信息(含翻译)
|
|
115
|
-
- ✅ **MV 播放信息** - 获取 MV 的播放地址和相关信息
|
|
116
|
-
|
|
117
|
-
#### 🎤 歌手相关
|
|
118
|
-
- ✅ **歌手热门歌曲** - 获取歌手的热门歌曲列表
|
|
119
|
-
- ✅ **歌手信息** - 获取歌手的基本资料信息
|
|
120
|
-
- ✅ **相似歌手** - 获取与指定歌手风格相似的其他歌手
|
|
121
|
-
- ✅ **歌手关注数** - 获取歌手的被关注数量信息
|
|
122
|
-
- ✅ **歌手 MV** - 获取歌手的 MV 作品列表
|
|
123
|
-
- ✅ **歌手专辑** - 获取歌手的专辑作品列表
|
|
124
|
-
|
|
125
|
-
#### 📋 歌单相关
|
|
126
|
-
- ✅ **歌单分类** - 获取 QQ 音乐的歌单分类标签
|
|
127
|
-
- ✅ **歌单列表** - 获取指定分类下的歌单列表
|
|
128
|
-
- ✅ **歌单详情** - 获取歌单的详细信息和歌曲列表
|
|
129
|
-
|
|
130
|
-
#### 🔍 搜索功能
|
|
131
|
-
- ✅ **搜索热词** - 获取当前热门搜索关键词
|
|
132
|
-
- ✅ **搜索提示** - 根据关键字获取搜索建议
|
|
133
|
-
- ✅ **搜索结果** - 获取歌曲、歌手、专辑等搜索结果
|
|
134
|
-
|
|
135
|
-
#### 📊 排行榜
|
|
136
|
-
- ✅ **排行榜单** - 获取所有音乐排行榜列表
|
|
137
|
-
- ✅ **榜单详情** - 获取指定排行榜的歌曲列表
|
|
138
|
-
|
|
139
|
-
#### 💿 专辑相关
|
|
140
|
-
- ✅ **专辑信息** - 获取专辑的详细信息
|
|
141
|
-
- ✅ **数字专辑** - 获取数字专辑的售卖信息
|
|
142
|
-
- ✅ **新碟上架** - 获取最新发布的专辑信息
|
|
143
|
-
|
|
144
|
-
#### 🎬 MV 视频
|
|
145
|
-
- ✅ **MV 标签** - 获取 MV 的分类标签
|
|
146
|
-
- ✅ **MV 列表** - 获取 MV 视频列表
|
|
147
|
-
|
|
148
|
-
#### 🔧 其他功能
|
|
149
|
-
- ✅ **自定义 Cookie** - 支持配置自定义 Cookie 信息
|
|
150
|
-
- ✅ **产品下载** - 获取 QQ 音乐数字产品的下载地址
|
|
151
|
-
- ✅ **电台列表** - 获取网络电台节目列表
|
|
152
|
-
- ✅ **票务信息** - 获取音乐演出票务信息
|
|
153
|
-
- ✅ **评论信息** - 获取歌曲、专辑等评论数据
|
|
154
|
-
- ✅ **首页推荐** - 获取 APP 首页推荐内容
|
|
155
|
-
|
|
156
|
-
### 使用文档
|
|
157
|
-
|
|
158
|
-
使用 `apis` 详见 [文档](https://sansenjian.github.io/qq-music-api/)
|
|
159
|
-
|
|
160
|
-
### 关于项目
|
|
161
|
-
|
|
162
|
-
**灵感来自**
|
|
163
|
-
|
|
164
|
-
[Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
|
|
165
|
-
|
|
166
|
-
[Vue2.0 开发企业级移动端音乐 Web App](https://coding.imooc.com/class/107.html)
|
|
77
|
+
```bash
|
|
78
|
+
# 开发模式
|
|
79
|
+
npm run dev
|
|
167
80
|
|
|
168
|
-
|
|
81
|
+
# 生产构建
|
|
82
|
+
npm run build
|
|
169
83
|
|
|
170
|
-
|
|
84
|
+
# 生产运行
|
|
85
|
+
npm run start
|
|
171
86
|
|
|
172
|
-
|
|
87
|
+
# 运行测试
|
|
88
|
+
npm run test
|
|
173
89
|
|
|
174
|
-
|
|
90
|
+
# 启动文档站点
|
|
91
|
+
npm run docs:dev
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
项目默认监听端口为 `3200`。
|
|
95
|
+
|
|
96
|
+
## 依赖版本说明(同步 [`package.json`](package.json:1))
|
|
97
|
+
|
|
98
|
+
### 生产依赖
|
|
99
|
+
|
|
100
|
+
| 依赖 | 当前版本 |
|
|
101
|
+
| ----------------------- | --------- |
|
|
102
|
+
| `@koa/router` | `^15.3.1` |
|
|
103
|
+
| `axios` | `^1.13.6` |
|
|
104
|
+
| `date-fns` | `^4.1.0` |
|
|
105
|
+
| `is-generator-function` | `1.0.10` |
|
|
106
|
+
| `koa` | `^2.16.1` |
|
|
107
|
+
| `koa-bodyparser` | `^4.4.1` |
|
|
108
|
+
| `koa-static` | `^5.0.0` |
|
|
109
|
+
| `reflect-metadata` | `^0.2.2` |
|
|
110
|
+
|
|
111
|
+
### 开发依赖
|
|
112
|
+
|
|
113
|
+
| 依赖 | 当前版本 |
|
|
114
|
+
| -------------------------------------------- | --------- |
|
|
115
|
+
| `@babel/core` | `^7.23.0` |
|
|
116
|
+
| `@babel/plugin-transform-async-to-generator` | `^7.23.0` |
|
|
117
|
+
| `@babel/preset-env` | `^7.29.0` |
|
|
118
|
+
| `@babel/preset-typescript` | `^7.28.5` |
|
|
119
|
+
| `@babel/register` | `^7.23.0` |
|
|
120
|
+
| `@commitlint/cli` | `^18.0.0` |
|
|
121
|
+
| `@commitlint/config-conventional` | `^18.0.0` |
|
|
122
|
+
| `@types/jest` | `^30.0.0` |
|
|
123
|
+
| `@types/koa` | `^3.0.1` |
|
|
124
|
+
| `@types/koa__router` | `^12.0.5` |
|
|
125
|
+
| `@types/koa-bodyparser` | `^4.3.13` |
|
|
126
|
+
| `@types/node` | `^25.3.3` |
|
|
127
|
+
| `@types/supertest` | `^7.2.0` |
|
|
128
|
+
| `chalk` | `^4.1.0` |
|
|
129
|
+
| `conventional-changelog-cli` | `^4.0.0` |
|
|
130
|
+
| `eslint` | `^8.57.0` |
|
|
131
|
+
| `eslint-config-standard` | `^17.0.0` |
|
|
132
|
+
| `eslint-plugin-import` | `^2.29.0` |
|
|
133
|
+
| `eslint-plugin-n` | `^16.0.0` |
|
|
134
|
+
| `eslint-plugin-promise` | `^6.0.0` |
|
|
135
|
+
| `husky` | `^9.0.0` |
|
|
136
|
+
| `jest` | `^30.2.0` |
|
|
137
|
+
| `lint-staged` | `^15.0.0` |
|
|
138
|
+
| `nodemon` | `^3.1.14` |
|
|
139
|
+
| `prettier` | `^3.8.1` |
|
|
140
|
+
| `rimraf` | `^6.1.3` |
|
|
141
|
+
| `sinon` | `^21.0.1` |
|
|
142
|
+
| `supertest` | `^7.2.2` |
|
|
143
|
+
| `ts-jest` | `^29.4.6` |
|
|
144
|
+
| `ts-node` | `^10.9.2` |
|
|
145
|
+
| `tsx` | `^4.21.0` |
|
|
146
|
+
| `typescript` | `5.7.3` |
|
|
147
|
+
| `vitepress` | `^1.6.4` |
|
|
148
|
+
| `vue` | `^3.5.29` |
|
|
149
|
+
|
|
150
|
+
## 当前主要能力
|
|
151
|
+
|
|
152
|
+
### 音乐与播放
|
|
153
|
+
|
|
154
|
+
- 歌曲播放链接
|
|
155
|
+
- 歌曲与专辑图片
|
|
156
|
+
- 歌词与翻译歌词
|
|
157
|
+
- MV 播放信息
|
|
158
|
+
|
|
159
|
+
### 歌手与歌单
|
|
160
|
+
|
|
161
|
+
- 歌手热门歌曲、资料、相似歌手、关注数
|
|
162
|
+
- 歌手 MV 与歌手专辑
|
|
163
|
+
- 歌单分类、歌单列表、歌单详情
|
|
164
|
+
- 排行榜列表与详情
|
|
165
|
+
|
|
166
|
+
### 用户与登录
|
|
167
|
+
|
|
168
|
+
- 用户头像
|
|
169
|
+
- 用户歌单
|
|
170
|
+
- QQ 扫码登录
|
|
171
|
+
- Cookie / 登录态相关接口
|
|
172
|
+
|
|
173
|
+
### 其他能力
|
|
174
|
+
|
|
175
|
+
- 评论信息
|
|
176
|
+
- 数字专辑
|
|
177
|
+
- 电台列表
|
|
178
|
+
- 首页推荐
|
|
179
|
+
- 下载地址
|
|
180
|
+
- 票务信息
|
|
181
|
+
|
|
182
|
+
## 文档入口
|
|
183
|
+
|
|
184
|
+
- 用户接口说明:[`docs/api/user.md`](docs/api/user.md)
|
|
185
|
+
- 其他接口说明:[`docs/api/other.md`](docs/api/other.md)
|
|
186
|
+
- 用户歌单测试说明:[`docs/TEST_USER_PLAYLISTS.md`](docs/TEST_USER_PLAYLISTS.md)
|
|
187
|
+
- 在线文档主页: [https://sansenjian.github.io/qq-music-api/](https://sansenjian.github.io/qq-music-api/)
|
|
188
|
+
|
|
189
|
+
## 关于项目
|
|
190
|
+
|
|
191
|
+
**灵感来源**
|
|
192
|
+
|
|
193
|
+
- [Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
|
|
194
|
+
- [Vue2.0 开发企业级移动端音乐 Web App](https://coding.imooc.com/class/107.html)
|
|
195
|
+
|
|
196
|
+
**参考内容**
|
|
175
197
|
|
|
176
|
-
|
|
198
|
+
- [Koa 2](https://koa.bootcss.com/)
|
|
199
|
+
- [Axios](https://github.com/axios/axios)
|
|
200
|
+
- [阮一峰老师 - HTTP Referer 教程](http://www.ruanyifeng.com/blog/2019/06/http-referer.html)
|
|
177
201
|
|
|
178
|
-
|
|
202
|
+
## 当前限制
|
|
179
203
|
|
|
180
|
-
|
|
204
|
+
1. 部分用户能力仍依赖有效 Cookie。
|
|
205
|
+
2. 上游 QQ 音乐接口字段可能变更,个别接口需要持续跟踪。
|
|
206
|
+
3. 用户歌单接口仍在持续验证与调整中,详见 [`docs/TEST_USER_PLAYLISTS.md`](docs/TEST_USER_PLAYLISTS.md)。
|
|
181
207
|
|
|
182
|
-
|
|
208
|
+
## 贡献
|
|
183
209
|
|
|
184
|
-
We welcome all contributions. You can submit any ideas as [pull requests](https://github.com/sansenjian/qq-music-api/pulls) or as
|
|
210
|
+
We welcome all contributions. You can submit any ideas as [pull requests](https://github.com/sansenjian/qq-music-api/pulls) or as GitHub [issues](https://github.com/sansenjian/qq-music-api/issues).
|
|
185
211
|
|
|
186
|
-
|
|
212
|
+
## 维护者
|
|
187
213
|
|
|
188
214
|
- [GitHub](https://github.com/sansenjian)
|
|
189
215
|
|
|
190
|
-
|
|
216
|
+
## 原作者
|
|
191
217
|
|
|
192
|
-
本项目基于 [Rain120](https://github.com/Rain120)
|
|
218
|
+
本项目基于 [Rain120](https://github.com/Rain120) 的开源项目,感谢原作者的贡献。
|
|
193
219
|
|
|
194
220
|
- [GitHub](https://github.com/Rain120)
|
|
195
221
|
- [知乎](https://www.zhihu.com/people/yan-yang-nian-hua-120/activities)
|
|
196
222
|
- [掘金](https://juejin.im/user/57c616496be3ff00584f54db)
|
|
197
223
|
|
|
198
|
-
|
|
224
|
+
## License
|
|
199
225
|
|
|
200
226
|
[MIT](https://github.com/sansenjian/qq-music-api/blob/master/LICENSE)
|
|
201
227
|
|
package/{app.js → app.ts}
RENAMED
|
@@ -1,42 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import Koa from 'koa';
|
|
3
|
+
import bodyParser from 'koa-bodyparser';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import koaStatic from 'koa-static';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import cors from './middlewares/koa-cors';
|
|
8
|
+
import router from './routers/router';
|
|
9
|
+
import cookieMiddleware from './util/cookie';
|
|
10
|
+
import colors from './util/colors';
|
|
11
|
+
import userInfoImport from './config/user-info';
|
|
12
|
+
import pkg from './package.json';
|
|
13
|
+
import type { UserInfo } from './types/global';
|
|
14
|
+
|
|
3
15
|
const app = new Koa();
|
|
4
|
-
const bodyParser = require('koa-bodyparser');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const static = require('koa-static');
|
|
7
|
-
const exec = require('child_process').exec;
|
|
8
|
-
const chalk = require('chalk');
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
const router = require('./routers/router');
|
|
12
|
-
const cookie = require('./util/cookie');
|
|
13
|
-
const colors = require('./util/colors');
|
|
14
|
-
const userInfo = require('./config/user-info');
|
|
15
|
-
const package = require('./package.json');
|
|
16
|
-
global.userInfo = Object.assign({}, userInfo);
|
|
17
|
+
global.userInfo = userInfoImport as UserInfo;
|
|
17
18
|
|
|
18
19
|
console.log(chalk.green('\n🥳🎉 We had supported config the user cookies. \n'));
|
|
20
|
+
console.log(colors.info(`Current Version: ${pkg.version}`));
|
|
19
21
|
|
|
20
|
-
if
|
|
22
|
+
if(!((global.userInfo as any).loginUin || (global.userInfo as any).uin)){
|
|
21
23
|
console.log(chalk.yellow(`😔 The configuration ${chalk.red('loginUin')} or your ${chalk.red('cookie')} in file ${chalk.green('config/user-info')} has not configured. \n`));
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
if (!global.userInfo.cookie) {
|
|
26
|
+
if (!(global.userInfo as any).cookie) {
|
|
25
27
|
console.log(chalk.yellow(`😔 The configuration ${chalk.red('cookie')} in file ${chalk.green('config/user-info')} has not configured. \n`));
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
exec('npm info QQ-Music-API version', (err, stdout, stderr) => {
|
|
29
|
-
if(!err){
|
|
30
|
-
let version = stdout.trim();
|
|
31
|
-
if(package.version < version){
|
|
32
|
-
console.log(colors.prompt(`Current Version: ${version}, Current Version: ${package.version}, Please update it.`));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
30
|
app.use(bodyParser());
|
|
38
|
-
app.use(
|
|
39
|
-
app.use(
|
|
31
|
+
app.use(cookieMiddleware() as any);
|
|
32
|
+
app.use(koaStatic(
|
|
40
33
|
path.join(__dirname, 'public')
|
|
41
34
|
));
|
|
42
35
|
|
|
@@ -49,13 +42,13 @@ app.use(async (ctx, next) => {
|
|
|
49
42
|
|
|
50
43
|
// cors
|
|
51
44
|
app.use(cors({
|
|
52
|
-
origin:
|
|
45
|
+
origin: ctx => (ctx.request as any).header?.origin || '*',
|
|
53
46
|
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
|
|
54
47
|
maxAge: 5,
|
|
55
48
|
credentials: true,
|
|
56
49
|
allowMethods: ['GET', 'POST', 'DELETE'],
|
|
57
50
|
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
|
|
58
|
-
}));
|
|
51
|
+
}) as any);
|
|
59
52
|
|
|
60
53
|
// x-response-time
|
|
61
54
|
app.use(async (ctx, next) => {
|
|
@@ -68,8 +61,8 @@ app.use(async (ctx, next) => {
|
|
|
68
61
|
app.use(router.routes())
|
|
69
62
|
.use(router.allowedMethods());
|
|
70
63
|
|
|
71
|
-
const PORT = process.env.PORT || 3200;
|
|
64
|
+
const PORT: number = typeof process.env.PORT === 'string' ? parseInt(process.env.PORT, 10) : (process.env.PORT || 3200);
|
|
72
65
|
|
|
73
|
-
app.listen(PORT, () => {
|
|
66
|
+
(app.listen as any)(PORT, () => {
|
|
74
67
|
console.log(colors.prompt(`server running @ http://localhost:${PORT}`));
|
|
75
68
|
});
|