@sansenjian/qq-music-api 2.2.1 → 2.2.7
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/CHANGELOG.md +120 -42
- package/dist/app.js +58 -0
- package/dist/config/user-info.js +59 -0
- package/dist/index.js +3 -0
- package/dist/jest.config.js +40 -0
- package/dist/middlewares/koa-cors.js +63 -0
- package/dist/module/apis/UCommon/UCommon.js +10 -0
- package/dist/module/apis/album/getAlbumInfo.js +23 -0
- package/dist/module/apis/comments/getComments.js +24 -0
- package/dist/module/apis/digitalAlbum/getDigitalAlbumLists.js +22 -0
- package/dist/module/apis/downloadQQMusic.js +48 -0
- package/dist/module/apis/extend/getPlaylistTags.js +158 -0
- package/dist/module/apis/music/getLyric.js +32 -0
- package/dist/module/apis/mv/getMvByTag.js +23 -0
- package/dist/module/apis/radio/getRadioLists.js +26 -0
- package/dist/module/apis/rank/getTopLists.js +35 -0
- package/dist/module/apis/recommend/getDailyRecommend.js +124 -0
- package/dist/module/apis/recommend/getPersonalRecommend.js +114 -0
- package/dist/module/apis/search/getHotKey.js +25 -0
- package/dist/module/apis/search/getSearchByKey.js +32 -0
- package/dist/module/apis/search/getSmartbox.js +40 -0
- package/dist/module/apis/singers/getSimilarSinger.js +24 -0
- package/dist/module/apis/singers/getSingerDesc.js +24 -0
- package/dist/module/apis/singers/getSingerMv.js +23 -0
- package/dist/module/apis/singers/getSingerStarNum.js +23 -0
- package/dist/module/apis/songLists/songListCategories.js +23 -0
- package/dist/module/apis/songLists/songListDetail.js +28 -0
- package/dist/module/apis/songLists/songLists.js +35 -0
- package/dist/module/apis/u_common.js +56 -0
- package/dist/module/apis/user/checkQQLoginQr.js +189 -0
- package/dist/module/apis/user/getQQLoginQr.js +23 -0
- package/dist/module/apis/user/getUserAvatar.js +25 -0
- package/dist/module/apis/user/getUserLikedSongs.js +129 -0
- package/dist/module/apis/user/getUserPlaylists.js +138 -0
- package/dist/module/apis/y_common.js +69 -0
- package/dist/module/config.js +24 -0
- package/dist/module/index.js +70 -0
- package/dist/package.json +117 -0
- package/dist/routers/context/batchGetSongInfo.js +53 -0
- package/dist/routers/context/batchGetSongLists.js +37 -0
- package/dist/routers/context/checkQQLoginQr.js +16 -0
- package/dist/routers/context/cookies.js +36 -0
- package/dist/routers/context/getAlbumInfo.js +29 -0
- package/dist/routers/context/getComments.js +38 -0
- package/dist/routers/context/getDailyRecommend.js +45 -0
- package/dist/routers/context/getDigitalAlbumLists.js +16 -0
- package/dist/routers/context/getDownloadQQMusic.js +16 -0
- package/dist/routers/context/getHotkey.js +21 -0
- package/dist/routers/context/getImageUrl.js +25 -0
- package/dist/routers/context/getLyric.js +29 -0
- package/dist/routers/context/getMusicPlay.js +91 -0
- package/dist/routers/context/getMv.js +57 -0
- package/dist/routers/context/getMvByTag.js +16 -0
- package/dist/routers/context/getMvPlay.js +105 -0
- package/dist/routers/context/getNewDisks.js +52 -0
- package/dist/routers/context/getPersonalRecommend.js +54 -0
- package/dist/routers/context/getPlaylistTags.js +60 -0
- package/dist/routers/context/getQQLoginQr.js +14 -0
- package/dist/routers/context/getRadioLists.js +16 -0
- package/dist/routers/context/getRanks.js +60 -0
- package/dist/routers/context/getRecommend.js +88 -0
- package/dist/routers/context/getSearchByKey.js +32 -0
- package/dist/routers/context/getSimilarSinger.js +27 -0
- package/dist/routers/context/getSingerAlbum.js +54 -0
- package/dist/routers/context/getSingerDesc.js +28 -0
- package/dist/routers/context/getSingerHotsong.js +54 -0
- package/dist/routers/context/getSingerList.js +51 -0
- package/dist/routers/context/getSingerMv.js +36 -0
- package/dist/routers/context/getSingerStarNum.js +27 -0
- package/dist/routers/context/getSmartbox.js +27 -0
- package/dist/routers/context/getSongInfo.js +47 -0
- package/dist/routers/context/getSongListCategories.js +23 -0
- package/dist/routers/context/getSongListDetail.js +19 -0
- package/dist/routers/context/getSongLists.js +25 -0
- package/dist/routers/context/getTicketInfo.js +47 -0
- package/dist/routers/context/getTopLists.js +16 -0
- package/dist/routers/context/getUserAvatar.js +48 -0
- package/dist/routers/context/getUserLikedSongs.js +24 -0
- package/dist/routers/context/getUserPlaylists.js +24 -0
- package/dist/routers/context/index.js +107 -0
- package/dist/routers/router.js +69 -0
- package/dist/routers/types.js +2 -0
- package/dist/routers/util.js +188 -0
- package/dist/types/api.js +55 -0
- package/dist/util/apiResponse.js +88 -0
- package/dist/util/colors.js +19 -0
- package/dist/util/cookie.js +26 -0
- package/dist/util/loginUtils.js +30 -0
- package/dist/util/lyricParse.js +72 -0
- package/dist/util/request.js +109 -0
- package/docs-dist/404.html +24 -0
- package/docs-dist/CHANGELOG-ARCHITECTURE.html +131 -0
- package/docs-dist/COOKIE_CONFIG_GUIDE.html +39 -0
- package/docs-dist/README.html +447 -0
- package/docs-dist/TEST_USER_PLAYLISTS.html +42 -0
- package/docs-dist/USER_AVATAR_GUIDE.html +100 -0
- package/docs-dist/api/comments.html +48 -0
- package/docs-dist/api/index.html +27 -0
- package/docs-dist/api/music.html +51 -0
- package/docs-dist/api/other.html +33 -0
- package/docs-dist/api/playlist.html +77 -0
- package/docs-dist/api/rank.html +48 -0
- package/docs-dist/api/search.html +62 -0
- package/docs-dist/api/singer.html +47 -0
- package/docs-dist/api/user.html +64 -0
- package/docs-dist/assets/CHANGELOG-ARCHITECTURE.md.BOe0ZtyR.js +105 -0
- package/docs-dist/assets/CHANGELOG-ARCHITECTURE.md.BOe0ZtyR.lean.js +1 -0
- package/docs-dist/assets/COOKIE_CONFIG_GUIDE.md.D68AwXR2.js +13 -0
- package/docs-dist/assets/COOKIE_CONFIG_GUIDE.md.D68AwXR2.lean.js +1 -0
- package/docs-dist/assets/README.md.ZJQGJ1Gb.js +421 -0
- package/docs-dist/assets/README.md.ZJQGJ1Gb.lean.js +1 -0
- package/docs-dist/assets/TEST_USER_PLAYLISTS.md.C02575X2.js +16 -0
- package/docs-dist/assets/TEST_USER_PLAYLISTS.md.C02575X2.lean.js +1 -0
- package/docs-dist/assets/USER_AVATAR_GUIDE.md.BOqjn5Cm.js +74 -0
- package/docs-dist/assets/USER_AVATAR_GUIDE.md.BOqjn5Cm.lean.js +1 -0
- package/docs-dist/assets/api_comments.md.DADvndEA.js +22 -0
- package/docs-dist/assets/api_comments.md.DADvndEA.lean.js +1 -0
- package/docs-dist/assets/api_index.md.D5IASxxG.js +1 -0
- package/docs-dist/assets/api_index.md.D5IASxxG.lean.js +1 -0
- package/docs-dist/assets/api_music.md.BgB8NmZq.js +25 -0
- package/docs-dist/assets/api_music.md.BgB8NmZq.lean.js +1 -0
- package/docs-dist/assets/api_other.md.BkRWXX2z.js +7 -0
- package/docs-dist/assets/api_other.md.BkRWXX2z.lean.js +1 -0
- package/docs-dist/assets/api_playlist.md.Dc0hTrZ4.js +51 -0
- package/docs-dist/assets/api_playlist.md.Dc0hTrZ4.lean.js +1 -0
- package/docs-dist/assets/api_rank.md.DRisCFyT.js +22 -0
- package/docs-dist/assets/api_rank.md.DRisCFyT.lean.js +1 -0
- package/docs-dist/assets/api_search.md.DNnMUZK0.js +36 -0
- package/docs-dist/assets/api_search.md.DNnMUZK0.lean.js +1 -0
- package/docs-dist/assets/api_singer.md.DCmuxQkk.js +21 -0
- package/docs-dist/assets/api_singer.md.DCmuxQkk.lean.js +1 -0
- package/docs-dist/assets/api_user.md.Cjm9GG3z.js +38 -0
- package/docs-dist/assets/api_user.md.Cjm9GG3z.lean.js +1 -0
- package/docs-dist/assets/app.Dx_1wB58.js +1 -0
- package/docs-dist/assets/chunks/@localSearchIndexroot.CMY5EIwU.js +1 -0
- package/docs-dist/assets/chunks/VPLocalSearchBox.DwKWtsdX.js +9 -0
- package/docs-dist/assets/chunks/framework.o40iizuP.js +19 -0
- package/docs-dist/assets/chunks/theme.pGVgJ9Cx.js +2 -0
- package/docs-dist/assets/guide_architecture.md.DGtNyuMH.js +258 -0
- package/docs-dist/assets/guide_architecture.md.DGtNyuMH.lean.js +1 -0
- package/docs-dist/assets/guide_authentication.md.mtI5LfCw.js +4 -0
- package/docs-dist/assets/guide_authentication.md.mtI5LfCw.lean.js +1 -0
- package/docs-dist/assets/guide_index.md.B-0SG46T.js +1 -0
- package/docs-dist/assets/guide_index.md.B-0SG46T.lean.js +1 -0
- package/docs-dist/assets/guide_installation.md.k-KpAfxv.js +7 -0
- package/docs-dist/assets/guide_installation.md.k-KpAfxv.lean.js +1 -0
- package/docs-dist/assets/guide_quickstart.md.Bff_KFOD.js +13 -0
- package/docs-dist/assets/guide_quickstart.md.Bff_KFOD.lean.js +1 -0
- package/docs-dist/assets/index.md.xrs-uIyo.js +1 -0
- package/docs-dist/assets/index.md.xrs-uIyo.lean.js +1 -0
- package/docs-dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/docs-dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/docs-dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/docs-dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/docs-dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/docs-dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/docs-dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/docs-dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/docs-dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/docs-dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/docs-dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/docs-dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/docs-dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/docs-dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/docs-dist/assets/reference_response-format.md.DKYTK6uJ.js +12 -0
- package/docs-dist/assets/reference_response-format.md.DKYTK6uJ.lean.js +1 -0
- package/docs-dist/assets/style.DM4qKDd4.css +1 -0
- package/docs-dist/guide/architecture.html +284 -0
- package/docs-dist/guide/authentication.html +30 -0
- package/docs-dist/guide/index.html +27 -0
- package/docs-dist/guide/installation.html +33 -0
- package/docs-dist/guide/quickstart.html +39 -0
- package/docs-dist/hashmap.json +1 -0
- package/docs-dist/index.html +27 -0
- package/docs-dist/logo.svg +4 -0
- package/docs-dist/reference/response-format.html +38 -0
- package/docs-dist/version.json +7 -0
- package/docs-dist/vp-icons.css +1 -0
- package/package.json +28 -17
- package/.babelrc +0 -7
- package/.dockerignore +0 -5
- package/.editorconfig +0 -31
- package/.eslintrc.json +0 -22
- package/.github/workflows/deploy-docs.yml +0 -54
- package/.github/workflows/release.yml +0 -37
- package/.github/workflows/test.yml +0 -70
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -1
- package/.prettierignore +0 -1
- package/.prettierrc +0 -9
- package/AGENTS.md +0 -153
- package/Dockerfile +0 -18
- package/QQ/351/237/263/344/271/220-v0.xmind +0 -0
- package/QQ/351/237/263/344/271/220-v1.xmind +0 -0
- package/app.ts +0 -68
- package/commitlint.config.js +0 -20
- package/config/user-info.ts +0 -71
- package/index.ts +0 -1
- package/jest.config.ts +0 -41
- package/middlewares/koa-cors.ts +0 -81
- package/module/apis/UCommon/UCommon.ts +0 -13
- package/module/apis/album/getAlbumInfo.ts +0 -22
- package/module/apis/comments/getComments.ts +0 -23
- package/module/apis/digitalAlbum/getDigitalAlbumLists.ts +0 -23
- package/module/apis/downloadQQMusic.ts +0 -51
- package/module/apis/music/getLyric.ts +0 -34
- package/module/apis/mv/getMvByTag.ts +0 -24
- package/module/apis/radio/getRadioLists.ts +0 -27
- package/module/apis/rank/getTopLists.ts +0 -37
- package/module/apis/search/getHotKey.ts +0 -24
- package/module/apis/search/getSearchByKey.ts +0 -31
- package/module/apis/search/getSmartbox.ts +0 -43
- package/module/apis/singers/getSimilarSinger.ts +0 -25
- package/module/apis/singers/getSingerDesc.ts +0 -25
- package/module/apis/singers/getSingerMv.ts +0 -24
- package/module/apis/singers/getSingerStarNum.ts +0 -24
- package/module/apis/songLists/songListCategories.ts +0 -22
- package/module/apis/songLists/songListDetail.ts +0 -27
- package/module/apis/songLists/songLists.ts +0 -35
- package/module/apis/u_common.ts +0 -29
- package/module/apis/user/checkQQLoginQr.ts +0 -230
- package/module/apis/user/getQQLoginQr.ts +0 -28
- package/module/apis/user/getUserAvatar.ts +0 -32
- package/module/apis/user/getUserLikedSongs.ts +0 -145
- package/module/apis/user/getUserPlaylists.ts +0 -163
- package/module/apis/y_common.ts +0 -44
- package/module/config.ts +0 -24
- package/module/index.ts +0 -95
- package/music.png +0 -0
- package/pnpm-workspace.yaml +0 -2
- package/public/index.html +0 -430
- package/routers/context/batchGetSongInfo.ts +0 -60
- package/routers/context/batchGetSongLists.ts +0 -46
- package/routers/context/checkQQLoginQr.ts +0 -19
- package/routers/context/cookies.ts +0 -38
- package/routers/context/getAlbumInfo.ts +0 -31
- package/routers/context/getComments.ts +0 -51
- package/routers/context/getDigitalAlbumLists.ts +0 -18
- package/routers/context/getDownloadQQMusic.ts +0 -17
- package/routers/context/getHotkey.ts +0 -25
- package/routers/context/getImageUrl.ts +0 -29
- package/routers/context/getLyric.ts +0 -32
- package/routers/context/getMusicPlay.ts +0 -102
- package/routers/context/getMv.ts +0 -61
- package/routers/context/getMvByTag.ts +0 -18
- package/routers/context/getMvPlay.ts +0 -114
- package/routers/context/getNewDisks.ts +0 -58
- package/routers/context/getQQLoginQr.ts +0 -16
- package/routers/context/getRadioLists.ts +0 -18
- package/routers/context/getRanks.ts +0 -67
- package/routers/context/getRecommend.ts +0 -92
- package/routers/context/getSearchByKey.ts +0 -34
- package/routers/context/getSimilarSinger.ts +0 -29
- package/routers/context/getSingerAlbum.ts +0 -58
- package/routers/context/getSingerDesc.ts +0 -30
- package/routers/context/getSingerHotsong.ts +0 -58
- package/routers/context/getSingerList.ts +0 -56
- package/routers/context/getSingerMv.ts +0 -41
- package/routers/context/getSingerStarNum.ts +0 -29
- package/routers/context/getSmartbox.ts +0 -27
- package/routers/context/getSongInfo.ts +0 -51
- package/routers/context/getSongListCategories.ts +0 -23
- package/routers/context/getSongListDetail.ts +0 -22
- package/routers/context/getSongLists.ts +0 -30
- package/routers/context/getTicketInfo.ts +0 -51
- package/routers/context/getTopLists.ts +0 -18
- package/routers/context/getUserAvatar.ts +0 -53
- package/routers/context/getUserLikedSongs.ts +0 -28
- package/routers/context/getUserPlaylists.ts +0 -29
- package/routers/context/index.ts +0 -87
- package/routers/router.ts +0 -88
- package/routers/types.ts +0 -18
- package/routers/util.ts +0 -231
- package/screenshot/album-image.png +0 -0
- package/screenshot/batchGetSongInfo.png +0 -0
- package/screenshot/batchGetSongLists.png +0 -0
- package/screenshot/downloadQQMusic.png +0 -0
- package/screenshot/get-album-image.png +0 -0
- package/screenshot/get-play-all-data.png +0 -0
- package/screenshot/get-song-album-id.png +0 -0
- package/screenshot/get-song-id.png +0 -0
- package/screenshot/get-song-image.png +0 -0
- package/screenshot/getAlbumInfo.png +0 -0
- package/screenshot/getComments-id.png +0 -0
- package/screenshot/getComments-param.png +0 -0
- package/screenshot/getComments.png +0 -0
- package/screenshot/getDigitalAlbumLists.png +0 -0
- package/screenshot/getLyric-parse.png +0 -0
- package/screenshot/getLyric.png +0 -0
- package/screenshot/getMusicPlay.png +0 -0
- package/screenshot/getMv.png +0 -0
- package/screenshot/getMvByTag.png +0 -0
- package/screenshot/getMvPlay.png +0 -0
- package/screenshot/getNewDisks.png +0 -0
- package/screenshot/getRadioLists.png +0 -0
- package/screenshot/getRanks.png +0 -0
- package/screenshot/getRecommend.png +0 -0
- package/screenshot/getSearchByKey.png +0 -0
- package/screenshot/getSimilarSinger.png +0 -0
- package/screenshot/getSingerAlbum.png +0 -0
- package/screenshot/getSingerDesc.png +0 -0
- package/screenshot/getSingerHotsong.png +0 -0
- package/screenshot/getSingerList.png +0 -0
- package/screenshot/getSingerMv-default.png +0 -0
- package/screenshot/getSingerMv-listen.png +0 -0
- package/screenshot/getSingerMv-time.png +0 -0
- package/screenshot/getSingerStarNum.png +0 -0
- package/screenshot/getSmartbox.png +0 -0
- package/screenshot/getSongInfo.png +0 -0
- package/screenshot/getSongListCategories.png +0 -0
- package/screenshot/getSongListDetail.png +0 -0
- package/screenshot/getSongLists-params.png +0 -0
- package/screenshot/getSongLists.png +0 -0
- package/screenshot/getTicketInfo.png +0 -0
- package/screenshot/getTopLists.png +0 -0
- package/screenshot/gethotkey.png +0 -0
- package/screenshot/just-get-play-url.png +0 -0
- package/screenshot/musicPlay.png +0 -0
- package/screenshot/new-feature-error-tips.png +0 -0
- package/screenshot/normalize-cookie.png +0 -0
- package/screenshot/qq-music-v0.png +0 -0
- package/screenshot/qq-music.png +0 -0
- package/screenshot/song-image.png +0 -0
- package/screenshot/song-quality-128.png +0 -0
- package/screenshot/song-quality-m4a.png +0 -0
- package/scripts/build-images.js +0 -36
- package/scripts/commit-push.sh +0 -103
- package/tests/integration/api/api.test.ts +0 -852
- package/tests/integration/middleware/cors.test.ts +0 -41
- package/tests/setup/jest.setup.ts +0 -15
- package/tests/setup/testUtils.ts +0 -35
- package/tests/unit/util/request.test.ts +0 -177
- package/tsconfig.json +0 -20
- package/tsconfig.test.json +0 -8
- package/types/api.ts +0 -105
- package/types/global.d.ts +0 -26
- package/types/index.d.ts +0 -97
- package/util/apiResponse.ts +0 -97
- package/util/colors.ts +0 -31
- package/util/cookie.ts +0 -40
- package/util/loginUtils.ts +0 -26
- package/util/lyricParse.ts +0 -86
- package/util/request.ts +0 -141
- package/vercel.json +0 -15
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const router_1 = __importDefault(require("@koa/router"));
|
|
7
|
+
const context_1 = __importDefault(require("./context"));
|
|
8
|
+
const router = new router_1.default();
|
|
9
|
+
router.get('/user/getCookie', context_1.default.getCookie);
|
|
10
|
+
router.get('/user/setCookie', context_1.default.setCookie);
|
|
11
|
+
router.get('/user/getUserPlaylists', context_1.default.getUserPlaylists);
|
|
12
|
+
router.get('/user/getUserAvatar', context_1.default.getUserAvatar);
|
|
13
|
+
router.get('/user/getUserLikedSongs', context_1.default.getUserLikedSongs);
|
|
14
|
+
router.get('/downloadQQMusic', context_1.default.getDownloadQQMusic);
|
|
15
|
+
router.get('/getHotkey', context_1.default.getHotKey);
|
|
16
|
+
router.get('/getSearchByKey/:key', context_1.default.getSearchByKey);
|
|
17
|
+
router.get('/getSearchByKey', context_1.default.getSearchByKey);
|
|
18
|
+
router.get('/getSmartbox/:key', context_1.default.getSmartbox);
|
|
19
|
+
router.get('/getSmartbox', context_1.default.getSmartbox);
|
|
20
|
+
router.get('/getSongListCategories', context_1.default.getSongListCategories);
|
|
21
|
+
router.get('/getSongLists/:page/:limit/:categoryId/:sortId', context_1.default.getSongLists);
|
|
22
|
+
router.get('/getSongLists', context_1.default.getSongLists);
|
|
23
|
+
router.post('/batchGetSongLists', context_1.default.batchGetSongLists);
|
|
24
|
+
router.get('/getSongInfo/:songmid', context_1.default.getSongInfo);
|
|
25
|
+
router.get('/getSongInfo', context_1.default.getSongInfo);
|
|
26
|
+
router.post('/batchGetSongInfo', context_1.default.batchGetSongInfo);
|
|
27
|
+
router.get('/getSongListDetail/:disstid', context_1.default.getSongListDetail);
|
|
28
|
+
router.get('/getSongListDetail', context_1.default.getSongListDetail);
|
|
29
|
+
router.get('/getNewDisks', context_1.default.getNewDisks);
|
|
30
|
+
router.get('/getMvByTag', context_1.default.getMvByTag);
|
|
31
|
+
router.get('/getMv', context_1.default.getMv);
|
|
32
|
+
router.get('/getSingerList', context_1.default.getSingerList);
|
|
33
|
+
router.get('/getSimilarSinger', context_1.default.getSimilarSinger);
|
|
34
|
+
router.get('/getSingerAlbum', context_1.default.getSingerAlbum);
|
|
35
|
+
router.get('/getSingerHotsong', context_1.default.getSingerHotsong);
|
|
36
|
+
router.get('/getSingerMv', context_1.default.getSingerMv);
|
|
37
|
+
router.get('/getSingerDesc', context_1.default.getSingerDesc);
|
|
38
|
+
router.get('/getSingerStarNum', context_1.default.getSingerStarNum);
|
|
39
|
+
router.get('/getRadioLists', context_1.default.getRadioLists);
|
|
40
|
+
router.get('/getDigitalAlbumLists', context_1.default.getDigitalAlbumLists);
|
|
41
|
+
router.get('/getLyric/:songmid', context_1.default.getLyric);
|
|
42
|
+
router.get('/getLyric', context_1.default.getLyric);
|
|
43
|
+
router.get('/getMusicPlay/:songmid', context_1.default.getMusicPlay);
|
|
44
|
+
router.get('/getMusicPlay', context_1.default.getMusicPlay);
|
|
45
|
+
router.get('/getAlbumInfo/:albummid', context_1.default.getAlbumInfo);
|
|
46
|
+
router.get('/getAlbumInfo', context_1.default.getAlbumInfo);
|
|
47
|
+
router.get('/getComments', context_1.default.getComments);
|
|
48
|
+
router.get('/getRecommend', context_1.default.getRecommend);
|
|
49
|
+
router.get('/getMvPlay', context_1.default.getMvPlay);
|
|
50
|
+
router.get('/getTopLists', context_1.default.getTopLists);
|
|
51
|
+
router.get('/getRanks', context_1.default.getRanks);
|
|
52
|
+
router.get('/getTicketInfo', context_1.default.getTicketInfo);
|
|
53
|
+
router.get('/getImageUrl', context_1.default.getImageUrl);
|
|
54
|
+
router.get('/getQQLoginQr', context_1.default.getQQLoginQr);
|
|
55
|
+
router.get('/user/getQQLoginQr', context_1.default.getQQLoginQr);
|
|
56
|
+
router.post('/checkQQLoginQr', context_1.default.checkQQLoginQr);
|
|
57
|
+
router.post('/user/checkQQLoginQr', context_1.default.checkQQLoginQr);
|
|
58
|
+
// 推荐相关
|
|
59
|
+
router.get('/getDailyRecommend', context_1.default.getDailyRecommend);
|
|
60
|
+
router.get('/getPrivateFM', context_1.default.getPrivateFM);
|
|
61
|
+
router.get('/getNewSongs', context_1.default.getNewSongs);
|
|
62
|
+
router.get('/getPersonalRecommend', context_1.default.getPersonalRecommend);
|
|
63
|
+
router.get('/getSimilarSongs', context_1.default.getSimilarSongs);
|
|
64
|
+
// 扩展功能
|
|
65
|
+
router.get('/getPlaylistTags', context_1.default.getPlaylistTags);
|
|
66
|
+
router.get('/getPlaylistsByTag', context_1.default.getPlaylistsByTag);
|
|
67
|
+
router.get('/getHotComments', context_1.default.getHotComments);
|
|
68
|
+
router.get('/getSingerListByArea', context_1.default.getSingerListByArea);
|
|
69
|
+
exports.default = router;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createController = createController;
|
|
4
|
+
exports.createPostController = createPostController;
|
|
5
|
+
exports.validateRequired = validateRequired;
|
|
6
|
+
exports.handleControllerResponse = handleControllerResponse;
|
|
7
|
+
exports.createCustomController = createCustomController;
|
|
8
|
+
const INTERNAL_ERROR_MESSAGE = '服务器内部错误';
|
|
9
|
+
const normalizeErrorMessage = (error) => {
|
|
10
|
+
if (error instanceof Error && error.message) {
|
|
11
|
+
return error.message;
|
|
12
|
+
}
|
|
13
|
+
return INTERNAL_ERROR_MESSAGE;
|
|
14
|
+
};
|
|
15
|
+
const setInternalErrorResponse = (ctx, error) => {
|
|
16
|
+
console.error('Controller error:', error);
|
|
17
|
+
ctx.status = 500;
|
|
18
|
+
ctx.body = {
|
|
19
|
+
error: INTERNAL_ERROR_MESSAGE,
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
const isMissingRequiredValue = (value) => {
|
|
23
|
+
if (value === undefined || value === null) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
if (typeof value === 'string') {
|
|
27
|
+
return value.trim() === '';
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* 创建 Controller 的工厂函数
|
|
33
|
+
* @param apiFunction API 函数
|
|
34
|
+
* @param options 配置选项
|
|
35
|
+
* @example
|
|
36
|
+
* export default createController(
|
|
37
|
+
* require('../../module').getSingerDesc,
|
|
38
|
+
* {
|
|
39
|
+
* validator: (params) => {
|
|
40
|
+
* if (!params.singermid) {
|
|
41
|
+
* return { valid: false, error: '缺少 singermid 参数' };
|
|
42
|
+
* }
|
|
43
|
+
* return { valid: true };
|
|
44
|
+
* },
|
|
45
|
+
* errorMessage: 'no singermid'
|
|
46
|
+
* }
|
|
47
|
+
* );
|
|
48
|
+
*/
|
|
49
|
+
function createController(apiFunction, options) {
|
|
50
|
+
return async (ctx, next) => {
|
|
51
|
+
try {
|
|
52
|
+
// 从 query 和 params 中提取参数
|
|
53
|
+
const params = {
|
|
54
|
+
...ctx.query,
|
|
55
|
+
...ctx.params,
|
|
56
|
+
};
|
|
57
|
+
// 验证参数
|
|
58
|
+
if (options?.validator) {
|
|
59
|
+
const validation = options.validator(params);
|
|
60
|
+
if (!validation.valid) {
|
|
61
|
+
ctx.status = 400;
|
|
62
|
+
ctx.body = {
|
|
63
|
+
response: validation.error || options.errorMessage || 'Invalid parameters',
|
|
64
|
+
};
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 构建 API 调用参数
|
|
69
|
+
const apiProps = {
|
|
70
|
+
method: 'get',
|
|
71
|
+
params,
|
|
72
|
+
option: {},
|
|
73
|
+
};
|
|
74
|
+
// 调用 API
|
|
75
|
+
const { status, body } = await apiFunction(apiProps);
|
|
76
|
+
// 设置响应
|
|
77
|
+
Object.assign(ctx, { status, body });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (options?.onError) {
|
|
81
|
+
options.onError(ctx, error);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
setInternalErrorResponse(ctx, error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 创建需要 POST 数据的 Controller
|
|
91
|
+
* @param apiFunction API 函数
|
|
92
|
+
* @param options 配置选项
|
|
93
|
+
*/
|
|
94
|
+
function createPostController(apiFunction, options) {
|
|
95
|
+
return async (ctx, next) => {
|
|
96
|
+
try {
|
|
97
|
+
// 从 request.body 中提取参数
|
|
98
|
+
const params = ctx.request.body || {};
|
|
99
|
+
// 验证参数
|
|
100
|
+
if (options?.validator) {
|
|
101
|
+
const validation = options.validator(params);
|
|
102
|
+
if (!validation.valid) {
|
|
103
|
+
ctx.status = 400;
|
|
104
|
+
ctx.body = {
|
|
105
|
+
response: validation.error || options.errorMessage || 'Invalid parameters',
|
|
106
|
+
};
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// 构建 API 调用参数
|
|
111
|
+
const apiProps = {
|
|
112
|
+
method: 'post',
|
|
113
|
+
params,
|
|
114
|
+
option: {},
|
|
115
|
+
};
|
|
116
|
+
// 调用 API
|
|
117
|
+
const { status, body } = await apiFunction(apiProps);
|
|
118
|
+
// 设置响应
|
|
119
|
+
Object.assign(ctx, { status, body });
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (options?.onError) {
|
|
123
|
+
options.onError(ctx, error);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
setInternalErrorResponse(ctx, error);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 简单的参数验证器
|
|
133
|
+
* @param requiredFields 必需的字段列表
|
|
134
|
+
* @example
|
|
135
|
+
* validator: validateRequired(['singermid', 'songmid'])
|
|
136
|
+
*/
|
|
137
|
+
function validateRequired(fields) {
|
|
138
|
+
return (params) => {
|
|
139
|
+
const missingFields = fields.filter(field => isMissingRequiredValue(params[field]));
|
|
140
|
+
if (missingFields.length > 0) {
|
|
141
|
+
return {
|
|
142
|
+
valid: false,
|
|
143
|
+
error: `缺少必需参数:${missingFields.join(', ')}`,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return { valid: true };
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 处理 Controller 响应
|
|
151
|
+
* @param ctx Koa Context
|
|
152
|
+
* @param apiCall API 调用函数
|
|
153
|
+
*/
|
|
154
|
+
async function handleControllerResponse(ctx, apiCall) {
|
|
155
|
+
try {
|
|
156
|
+
const { status, body } = await apiCall();
|
|
157
|
+
Object.assign(ctx, { status, body });
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error('Controller response error:', normalizeErrorMessage(error));
|
|
161
|
+
ctx.status = 500;
|
|
162
|
+
ctx.body = { error: INTERNAL_ERROR_MESSAGE };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 创建带自定义参数处理的 Controller
|
|
167
|
+
* @param handler 自定义处理函数
|
|
168
|
+
* @param apiFunction API 函数
|
|
169
|
+
*/
|
|
170
|
+
function createCustomController(handler, apiFunction) {
|
|
171
|
+
return async (ctx, next) => {
|
|
172
|
+
try {
|
|
173
|
+
const customParams = handler(ctx);
|
|
174
|
+
const apiProps = {
|
|
175
|
+
method: 'get',
|
|
176
|
+
option: {},
|
|
177
|
+
...customParams,
|
|
178
|
+
};
|
|
179
|
+
const { status, body } = await apiFunction(apiProps);
|
|
180
|
+
Object.assign(ctx, { status, body });
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('Custom controller error:', normalizeErrorMessage(error));
|
|
184
|
+
ctx.status = 500;
|
|
185
|
+
ctx.body = { error: INTERNAL_ERROR_MESSAGE };
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSuccessResponse = createSuccessResponse;
|
|
4
|
+
exports.createErrorResponse = createErrorResponse;
|
|
5
|
+
exports.handleApi = handleApi;
|
|
6
|
+
/**
|
|
7
|
+
* 成功响应创建器
|
|
8
|
+
*/
|
|
9
|
+
function createSuccessResponse(data, status = 200) {
|
|
10
|
+
return {
|
|
11
|
+
status,
|
|
12
|
+
body: {
|
|
13
|
+
response: data,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 错误响应创建器
|
|
19
|
+
*/
|
|
20
|
+
function createErrorResponse(error, status = 500) {
|
|
21
|
+
return {
|
|
22
|
+
status,
|
|
23
|
+
body: {
|
|
24
|
+
error,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* API Promise 处理器 - 自动处理成功和错误情况
|
|
30
|
+
*/
|
|
31
|
+
async function handleApi(promise, options) {
|
|
32
|
+
try {
|
|
33
|
+
const result = await promise;
|
|
34
|
+
const responseData = options?.transformData
|
|
35
|
+
? options.transformData(result.data || result)
|
|
36
|
+
: result.data || result;
|
|
37
|
+
return {
|
|
38
|
+
status: options?.customStatus || 200,
|
|
39
|
+
body: {
|
|
40
|
+
response: responseData,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (options?.logError !== false) {
|
|
46
|
+
console.log('API error:', error);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
status: options?.customStatus || 500,
|
|
50
|
+
body: {
|
|
51
|
+
error,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.successResponse = successResponse;
|
|
4
|
+
exports.errorResponse = errorResponse;
|
|
5
|
+
exports.handleApi = handleApi;
|
|
6
|
+
exports.customResponse = customResponse;
|
|
7
|
+
exports.badRequest = badRequest;
|
|
8
|
+
/**
|
|
9
|
+
* 创建成功的 API 响应
|
|
10
|
+
* @param data 响应数据
|
|
11
|
+
* @param status HTTP 状态码,默认 200
|
|
12
|
+
*/
|
|
13
|
+
function successResponse(data, status = 200) {
|
|
14
|
+
return {
|
|
15
|
+
status,
|
|
16
|
+
body: {
|
|
17
|
+
response: data,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 创建错误的 API 响应
|
|
23
|
+
* @param error 错误信息
|
|
24
|
+
* @param status HTTP 状态码,默认 500
|
|
25
|
+
*/
|
|
26
|
+
function errorResponse(error, status = 500) {
|
|
27
|
+
return {
|
|
28
|
+
status,
|
|
29
|
+
body: {
|
|
30
|
+
error,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 处理 API Promise,自动包装成功和错误响应
|
|
36
|
+
* @param promise API 请求 Promise
|
|
37
|
+
* @param options 可选配置
|
|
38
|
+
*/
|
|
39
|
+
async function handleApi(promise, options) {
|
|
40
|
+
try {
|
|
41
|
+
const result = await promise;
|
|
42
|
+
const resultAny = result;
|
|
43
|
+
const responseData = options?.transformData
|
|
44
|
+
? options.transformData(resultAny.data || result)
|
|
45
|
+
: resultAny.data || result;
|
|
46
|
+
return {
|
|
47
|
+
status: options?.customStatus || 200,
|
|
48
|
+
body: {
|
|
49
|
+
response: responseData,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// 只在非测试环境下记录错误日志
|
|
55
|
+
if (options?.logError !== false && process.env.NODE_ENV !== 'test') {
|
|
56
|
+
console.log('API error:', error);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
status: options?.customStatus || 500,
|
|
60
|
+
body: {
|
|
61
|
+
error,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 创建自定义结构的响应
|
|
68
|
+
* @param body 响应体
|
|
69
|
+
* @param status HTTP 状态码
|
|
70
|
+
*/
|
|
71
|
+
function customResponse(body, status = 200) {
|
|
72
|
+
return {
|
|
73
|
+
status,
|
|
74
|
+
body,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 处理 400 错误响应(参数错误)
|
|
79
|
+
* @param message 错误消息
|
|
80
|
+
*/
|
|
81
|
+
function badRequest(message) {
|
|
82
|
+
return {
|
|
83
|
+
status: 400,
|
|
84
|
+
body: {
|
|
85
|
+
response: message,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
const colors = {
|
|
8
|
+
silly: (text) => chalk_1.default.hex('#ff69b4')(text),
|
|
9
|
+
input: (text) => chalk_1.default.grey(text),
|
|
10
|
+
verbose: (text) => chalk_1.default.cyan(text),
|
|
11
|
+
prompt: (text) => chalk_1.default.white(text),
|
|
12
|
+
info: (text) => chalk_1.default.green(text),
|
|
13
|
+
data: (text) => chalk_1.default.grey(text),
|
|
14
|
+
help: (text) => chalk_1.default.cyan(text),
|
|
15
|
+
warn: (text) => chalk_1.default.yellow(text),
|
|
16
|
+
debug: (text) => chalk_1.default.blue(text),
|
|
17
|
+
error: (text) => chalk_1.default.red(text)
|
|
18
|
+
};
|
|
19
|
+
exports.default = colors;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const SAFE_COOKIE_NAMES = new Set(['qqmusic_key', 'qqmusic_uin']);
|
|
4
|
+
const cookieMiddleware = () => async (ctx, next) => {
|
|
5
|
+
if (global.userInfo?.cookie) {
|
|
6
|
+
// Extend Request interface if needed, or just cast
|
|
7
|
+
ctx.request.cookie = global.userInfo.cookie;
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(global.userInfo?.cookieList)) {
|
|
10
|
+
global.userInfo.cookieList.forEach((cookie) => {
|
|
11
|
+
const [key, ...valueParts] = cookie.split('=');
|
|
12
|
+
const normalizedKey = key?.trim();
|
|
13
|
+
const value = valueParts.join('=').trim();
|
|
14
|
+
if (normalizedKey && value && SAFE_COOKIE_NAMES.has(normalizedKey)) {
|
|
15
|
+
ctx.cookies.set(normalizedKey, value, {
|
|
16
|
+
// 仅同步前端业务必需且可公开的 Cookie,避免敏感登录态透传
|
|
17
|
+
overwrite: true,
|
|
18
|
+
httpOnly: false,
|
|
19
|
+
sameSite: 'lax'
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
await next();
|
|
25
|
+
};
|
|
26
|
+
exports.default = cookieMiddleware;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getGuid = exports.getGtk = exports.hash33 = void 0;
|
|
4
|
+
const hash33 = (t) => {
|
|
5
|
+
let e = 0;
|
|
6
|
+
for (let n = 0, o = t.length; n < o; ++n) {
|
|
7
|
+
e += (e << 5) + t.charCodeAt(n);
|
|
8
|
+
}
|
|
9
|
+
return 2147483647 & e;
|
|
10
|
+
};
|
|
11
|
+
exports.hash33 = hash33;
|
|
12
|
+
const getGtk = (p_skey) => {
|
|
13
|
+
const str = p_skey;
|
|
14
|
+
let hash = 5381;
|
|
15
|
+
for (let i = 0, len = str.length; i < len; ++i) {
|
|
16
|
+
hash += (hash << 5) + str.charCodeAt(i);
|
|
17
|
+
}
|
|
18
|
+
return hash & 0x7fffffff;
|
|
19
|
+
};
|
|
20
|
+
exports.getGtk = getGtk;
|
|
21
|
+
const getGuid = () => {
|
|
22
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
23
|
+
.replace(/[xy]/g, function (c) {
|
|
24
|
+
const r = (Math.random() * 16) | 0;
|
|
25
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
26
|
+
return v.toString(16);
|
|
27
|
+
})
|
|
28
|
+
.toUpperCase();
|
|
29
|
+
};
|
|
30
|
+
exports.getGuid = getGuid;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Lyric = void 0;
|
|
4
|
+
exports.lyricParse = lyricParse;
|
|
5
|
+
// [01:27.96]
|
|
6
|
+
const timeExp = /\[(\d{2,}):(\d{2})(?:\.(\d{2,3}))?]/g;
|
|
7
|
+
const TAGREGMAP = {
|
|
8
|
+
title: 'ti',
|
|
9
|
+
artist: 'ar',
|
|
10
|
+
album: 'al',
|
|
11
|
+
offset: 'offset',
|
|
12
|
+
by: 'by'
|
|
13
|
+
};
|
|
14
|
+
class Lyric {
|
|
15
|
+
constructor(lyric) {
|
|
16
|
+
this.lyric = lyric;
|
|
17
|
+
this.tags = {};
|
|
18
|
+
this.lines = [];
|
|
19
|
+
this._init();
|
|
20
|
+
}
|
|
21
|
+
_init() {
|
|
22
|
+
this._initTag();
|
|
23
|
+
this._initLines();
|
|
24
|
+
}
|
|
25
|
+
_initTag() {
|
|
26
|
+
for (const tag in TAGREGMAP) {
|
|
27
|
+
const matches = this.lyric.match(new RegExp(`\\[${TAGREGMAP[tag]}:([^\\]]*)]`, 'i'));
|
|
28
|
+
this.tags[tag] = (matches && matches[1]) || '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
_initLines() {
|
|
32
|
+
const lines = this.lyric.split('\n');
|
|
33
|
+
for (let i = 0; i < lines.length; i++) {
|
|
34
|
+
const line = lines[i].trim();
|
|
35
|
+
timeExp.lastIndex = 0;
|
|
36
|
+
const matches = [...line.matchAll(timeExp)];
|
|
37
|
+
if (matches.length > 0) {
|
|
38
|
+
const txt = line.replace(timeExp, '').trim();
|
|
39
|
+
if (txt) {
|
|
40
|
+
for (const result of matches) {
|
|
41
|
+
// RegExpMatchArray elements are strings, so we need to parse them
|
|
42
|
+
const minutes = parseInt(result[1], 10);
|
|
43
|
+
const seconds = parseInt(result[2], 10);
|
|
44
|
+
const milliseconds = result[3] ? parseInt(result[3], 10) : 0;
|
|
45
|
+
// If milliseconds is 2 digits (e.g. .96), it usually means 960ms or 96cs?
|
|
46
|
+
// Standard LRC is usually centiseconds (cs), so .96 is 960ms.
|
|
47
|
+
// If 3 digits, it's ms.
|
|
48
|
+
// The original code was `(result[3] || 0) * 10`.
|
|
49
|
+
// If result[3] is '96', parseInt is 96. 96 * 10 = 960. Correct.
|
|
50
|
+
// If result[3] is '123', parseInt is 123. 123 * 10 = 1230. Incorrect if it was already ms.
|
|
51
|
+
// But regex `\d{2,3}` captures 2 or 3 digits.
|
|
52
|
+
// If 3 digits, usually it is milliseconds. If 2 digits, it is centiseconds.
|
|
53
|
+
// The logic `* 10` implies it assumes 2 digits (centiseconds) mostly.
|
|
54
|
+
// Let's keep the original logic for compatibility.
|
|
55
|
+
const time = minutes * 60 * 1000 + seconds * 1000 + milliseconds * 10;
|
|
56
|
+
this.lines.push({
|
|
57
|
+
time,
|
|
58
|
+
txt
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
this.lines.sort((a, b) => {
|
|
65
|
+
return a.time - b.time;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.Lyric = Lyric;
|
|
70
|
+
function lyricParse(lyricString) {
|
|
71
|
+
return new Lyric(lyricString);
|
|
72
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const axios_1 = __importDefault(require("axios"));
|
|
7
|
+
const http_1 = __importDefault(require("http"));
|
|
8
|
+
const https_1 = __importDefault(require("https"));
|
|
9
|
+
const colors_1 = __importDefault(require("./colors"));
|
|
10
|
+
// Create dedicated instance
|
|
11
|
+
const service = axios_1.default.create({
|
|
12
|
+
withCredentials: true,
|
|
13
|
+
timeout: 15000,
|
|
14
|
+
responseType: 'json',
|
|
15
|
+
// Enable keep-alive for better performance
|
|
16
|
+
httpAgent: new http_1.default.Agent({ keepAlive: true }),
|
|
17
|
+
httpsAgent: new https_1.default.Agent({ keepAlive: true })
|
|
18
|
+
});
|
|
19
|
+
const ensureContentType = (config) => {
|
|
20
|
+
const method = (config.method || 'get').toLowerCase();
|
|
21
|
+
const hasBody = config.data !== undefined && config.data !== null;
|
|
22
|
+
const headers = config.headers || {};
|
|
23
|
+
const hasContentType = Boolean(headers['Content-Type'] || headers['content-type']);
|
|
24
|
+
if (hasBody && !hasContentType && ['post', 'put', 'patch', 'delete'].includes(method)) {
|
|
25
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
|
|
26
|
+
}
|
|
27
|
+
config.headers = headers;
|
|
28
|
+
};
|
|
29
|
+
// Request interceptor to ensure headers
|
|
30
|
+
service.interceptors.request.use(config => {
|
|
31
|
+
// Ensure User-Agent
|
|
32
|
+
if (config.headers && !config.headers['User-Agent']) {
|
|
33
|
+
config.headers['User-Agent'] =
|
|
34
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
|
35
|
+
}
|
|
36
|
+
ensureContentType(config);
|
|
37
|
+
return config;
|
|
38
|
+
}, error => {
|
|
39
|
+
return Promise.reject(error);
|
|
40
|
+
});
|
|
41
|
+
// Response interceptor
|
|
42
|
+
service.interceptors.response.use(response => {
|
|
43
|
+
if (!response) {
|
|
44
|
+
throw Error('response is null');
|
|
45
|
+
}
|
|
46
|
+
if (process.env.DEBUG === 'true') {
|
|
47
|
+
console.log(colors_1.default.info(`${response.config.url} request success`));
|
|
48
|
+
}
|
|
49
|
+
return response;
|
|
50
|
+
}, error => {
|
|
51
|
+
const url = error.config ? error.config.url : 'Unknown URL';
|
|
52
|
+
console.log(colors_1.default.error(`${url} request error: ${error.message}`));
|
|
53
|
+
return Promise.reject(error);
|
|
54
|
+
});
|
|
55
|
+
const yURL = 'https://y.qq.com';
|
|
56
|
+
const cURL = 'https://c.y.qq.com';
|
|
57
|
+
function request(configOrUrl, method, options, isUUrl = 'c') {
|
|
58
|
+
let url;
|
|
59
|
+
let reqMethod;
|
|
60
|
+
let reqOptions;
|
|
61
|
+
let reqIsUUrl;
|
|
62
|
+
if (typeof configOrUrl === 'object') {
|
|
63
|
+
url = configOrUrl.url || '';
|
|
64
|
+
reqMethod = configOrUrl.method || 'GET';
|
|
65
|
+
reqOptions = configOrUrl.options;
|
|
66
|
+
reqIsUUrl = configOrUrl.isUUrl || 'c';
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
url = configOrUrl;
|
|
70
|
+
reqMethod = method || 'GET';
|
|
71
|
+
reqOptions = options;
|
|
72
|
+
reqIsUUrl = isUUrl;
|
|
73
|
+
}
|
|
74
|
+
let baseURL = '';
|
|
75
|
+
switch (reqIsUUrl) {
|
|
76
|
+
case 'y':
|
|
77
|
+
baseURL = yURL + url;
|
|
78
|
+
break;
|
|
79
|
+
case 'u':
|
|
80
|
+
baseURL = url;
|
|
81
|
+
break;
|
|
82
|
+
case 'c':
|
|
83
|
+
baseURL = cURL + url;
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
baseURL = cURL + url;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
const config = {
|
|
90
|
+
...(reqOptions || {}),
|
|
91
|
+
url: baseURL,
|
|
92
|
+
method: reqMethod.toLowerCase()
|
|
93
|
+
};
|
|
94
|
+
const headers = config.headers || {};
|
|
95
|
+
if (headers.cookies) {
|
|
96
|
+
if (!headers.Cookie) {
|
|
97
|
+
headers.Cookie = headers.cookies;
|
|
98
|
+
}
|
|
99
|
+
delete headers.cookies;
|
|
100
|
+
}
|
|
101
|
+
if (!headers.Cookie && !headers.cookie) {
|
|
102
|
+
if (global.userInfo && global.userInfo.cookie) {
|
|
103
|
+
headers.Cookie = global.userInfo.cookie;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
config.headers = headers;
|
|
107
|
+
return service(config);
|
|
108
|
+
}
|
|
109
|
+
exports.default = request;
|