From 74bf714c289e9e88a73a3b524821287e01ee2b4b Mon Sep 17 00:00:00 2001 From: kunkka Date: Tue, 27 Oct 2020 23:08:38 +0800 Subject: [PATCH] feat: integrate api in electron app --- .gitignore | 1 - .npmrc | 5 +- napi/.editorconfig | 34 + napi/.eslintrc.js | 49 + napi/.gitignore | 5 + napi/.npmignore | 3 + napi/.prettierrc | 5 + napi/README.MD | 312 + napi/app.js | 117 + napi/buildScript.js | 60 + napi/interface.d.ts | 1311 +++ napi/main.js | 26 + napi/module/activate_init_profile.js | 19 + napi/module/album.js | 15 + napi/module/album_detail.js | 17 + napi/module/album_detail_dynamic.js | 17 + napi/module/album_list.js | 21 + napi/module/album_list_style.js | 20 + napi/module/album_new.js | 15 + napi/module/album_newest.js | 15 + napi/module/album_songsaleboard.js | 24 + napi/module/album_sub.js | 14 + napi/module/album_sublist.js | 15 + napi/module/artist_album.js | 20 + napi/module/artist_desc.js | 18 + napi/module/artist_list.js | 37 + napi/module/artist_mv.js | 16 + napi/module/artist_songs.js | 17 + napi/module/artist_sub.js | 20 + napi/module/artist_sublist.js | 15 + napi/module/artist_top_song.js | 12 + napi/module/artists.js | 15 + napi/module/audio_match.js | 19 + napi/module/avatar_upload.js | 27 + napi/module/banner.js | 17 + napi/module/batch.js | 19 + napi/module/calendar.js | 12 + napi/module/captcha_sent.js | 14 + napi/module/captcha_verify.js | 20 + napi/module/cellphone_existence_check.js | 20 + napi/module/check_music.js | 34 + napi/module/cloudsearch.js | 21 + napi/module/comment.js | 43 + napi/module/comment_album.js | 22 + napi/module/comment_dj.js | 22 + napi/module/comment_event.js | 20 + napi/module/comment_floor.js | 27 + napi/module/comment_hot.js | 30 + napi/module/comment_hotwall_list.js | 16 + napi/module/comment_like.js | 33 + napi/module/comment_music.js | 22 + napi/module/comment_mv.js | 22 + napi/module/comment_new.js | 38 + napi/module/comment_playlist.js | 22 + napi/module/comment_video.js | 22 + napi/module/countries_code_list.js | 16 + napi/module/daily_signin.js | 20 + napi/module/digitalAlbum_ordering.js | 27 + napi/module/digitalAlbum_purchased.js | 20 + napi/module/dj_banner.js | 17 + napi/module/dj_category_excludehot.js | 15 + napi/module/dj_category_recommend.js | 15 + napi/module/dj_catelist.js | 15 + napi/module/dj_detail.js | 13 + napi/module/dj_hot.js | 14 + napi/module/dj_paygift.js | 19 + napi/module/dj_personalize_recommend.js | 17 + napi/module/dj_program.js | 21 + napi/module/dj_program_detail.js | 13 + napi/module/dj_program_toplist.js | 14 + napi/module/dj_program_toplist_hours.js | 18 + napi/module/dj_radio_hot.js | 15 + napi/module/dj_recommend.js | 15 + napi/module/dj_recommend_type.js | 41 + napi/module/dj_sub.js | 19 + napi/module/dj_sublist.js | 20 + napi/module/dj_subscriber.js | 16 + napi/module/dj_today_perfered.js | 18 + napi/module/dj_toplist.js | 18 + napi/module/dj_toplist_hours.js | 14 + napi/module/dj_toplist_newcomer.js | 18 + napi/module/dj_toplist_pay.js | 18 + napi/module/dj_toplist_popular.js | 14 + napi/module/event.js | 14 + napi/module/event_del.js | 13 + napi/module/event_forward.js | 16 + napi/module/fm_trash.js | 20 + napi/module/follow.js | 17 + napi/module/history_recommend_songs.js | 17 + napi/module/history_recommend_songs_detail.js | 19 + napi/module/homepage_block_page.js | 17 + napi/module/homepage_dragon_ball.js | 19 + napi/module/hot_topic.js | 14 + napi/module/like.js | 23 + napi/module/likelist.js | 13 + napi/module/login.js | 47 + napi/module/login_cellphone.js | 39 + napi/module/login_refresh.js | 16 + napi/module/login_status.js | 23 + napi/module/logout.js | 16 + napi/module/lyric.js | 17 + napi/module/msg_comments.js | 22 + napi/module/msg_forwards.js | 15 + napi/module/msg_notices.js | 14 + napi/module/msg_private.js | 15 + napi/module/msg_private_history.js | 21 + napi/module/mv_all.js | 20 + napi/module/mv_detail.js | 13 + napi/module/mv_detail_info.js | 19 + napi/module/mv_exclusive_rcmd.js | 19 + napi/module/mv_first.js | 21 + napi/module/mv_sub.js | 15 + napi/module/mv_sublist.js | 20 + napi/module/mv_url.js | 19 + napi/module/personal_fm.js | 15 + napi/module/personalized.js | 21 + napi/module/personalized_djprogram.js | 15 + napi/module/personalized_mv.js | 15 + napi/module/personalized_newsong.js | 20 + napi/module/personalized_privatecontent.js | 15 + .../personalized_privatecontent_list.js | 20 + napi/module/playlist_catlist.js | 15 + napi/module/playlist_cover_update.js | 28 + napi/module/playlist_create.js | 16 + napi/module/playlist_delete.js | 14 + napi/module/playlist_desc_update.js | 20 + napi/module/playlist_detail.js | 15 + napi/module/playlist_highquality_tags.js | 15 + napi/module/playlist_hot.js | 15 + napi/module/playlist_mylike.js | 17 + napi/module/playlist_name_update.js | 20 + napi/module/playlist_order_update.js | 19 + napi/module/playlist_subscribe.js | 19 + napi/module/playlist_subscribers.js | 20 + napi/module/playlist_tags_update.js | 20 + napi/module/playlist_track_add.js | 20 + napi/module/playlist_track_delete.js | 26 + napi/module/playlist_tracks.js | 51 + napi/module/playlist_update.js | 18 + napi/module/playlist_video_recent.js | 14 + napi/module/playmode_intelligence_list.js | 22 + napi/module/program_recommend.js | 20 + napi/module/rebind.js | 21 + napi/module/recommend_resource.js | 15 + napi/module/recommend_songs.js | 17 + napi/module/register_cellphone.js | 18 + napi/module/related_allvideo.js | 19 + napi/module/related_playlist.js | 38 + napi/module/resource_like.js | 29 + napi/module/scrobble.js | 27 + napi/module/search.js | 16 + napi/module/search_default.js | 16 + napi/module/search_hot.js | 14 + napi/module/search_hot_detail.js | 15 + napi/module/search_multimatch.js | 19 + napi/module/search_suggest.js | 19 + napi/module/send_playlist.js | 17 + napi/module/send_text.js | 16 + napi/module/setting.js | 11 + napi/module/share_resource.js | 20 + napi/module/simi_artist.js | 18 + napi/module/simi_mv.js | 13 + napi/module/simi_playlist.js | 20 + napi/module/simi_song.js | 20 + napi/module/simi_user.js | 20 + napi/module/song_detail.js | 15 + napi/module/song_order_update.js | 22 + napi/module/song_url.js | 25 + napi/module/top_album.js | 27 + napi/module/top_artists.js | 15 + napi/module/top_list.js | 30 + napi/module/top_mv.js | 16 + napi/module/top_playlist.js | 17 + napi/module/top_playlist_highquality.js | 21 + napi/module/top_song.js | 21 + napi/module/toplist.js | 15 + napi/module/toplist_artist.js | 16 + napi/module/toplist_detail.js | 15 + napi/module/user_account.js | 9 + napi/module/user_audio.js | 18 + napi/module/user_binding.js | 14 + napi/module/user_cloud.js | 14 + napi/module/user_cloud_del.js | 13 + napi/module/user_cloud_detail.js | 19 + napi/module/user_detail.js | 15 + napi/module/user_dj.js | 19 + napi/module/user_event.js | 21 + napi/module/user_followeds.js | 21 + napi/module/user_follows.js | 20 + napi/module/user_level.js | 11 + napi/module/user_playlist.js | 16 + napi/module/user_record.js | 14 + napi/module/user_replacephone.js | 19 + napi/module/user_subcount.js | 15 + napi/module/user_update.js | 24 + napi/module/video_category_list.js | 20 + napi/module/video_detail.js | 18 + napi/module/video_detail_info.js | 19 + napi/module/video_group.js | 21 + napi/module/video_group_list.js | 16 + napi/module/video_sub.js | 19 + napi/module/video_timeline_all.js | 22 + napi/module/video_timeline_recommend.js | 17 + napi/module/video_url.js | 19 + napi/module/weblog.js | 15 + napi/module/yunbei.js | 10 + napi/module/yunbei_expense.js | 17 + napi/module/yunbei_info.js | 9 + napi/module/yunbei_receipt.js | 17 + napi/module/yunbei_sign.js | 11 + napi/module/yunbei_task_finish.js | 17 + napi/module/yunbei_tasks.js | 14 + napi/module/yunbei_tasks_todo.js | 14 + napi/module/yunbei_today.js | 9 + napi/package-lock.json | 4096 ++++++++ napi/package.json | 67 + napi/plugins/upload.js | 48 + napi/public/avatar_update.html | 82 + napi/public/index.html | 56 + napi/public/playlist_cover_update.html | 91 + napi/public/test.html | 61 + napi/renovate.json | 3 + napi/routes.js | 8810 +++++++++++++++++ napi/tsconfig.json | 20 + napi/util/apicache.js | 830 ++ napi/util/crypto.js | 67 + napi/util/index.js | 17 + napi/util/memory-cache.js | 63 + napi/util/request.js | 177 + package.json | 25 +- .../icons/android-chrome-maskable-192x192.png | Bin 6401 -> 0 bytes .../icons/android-chrome-maskable-512x512.png | Bin 23038 -> 0 bytes src/background.js | 95 +- src/electron/command.js | 116 + src/electron/menu.js | 161 + src/electron/preload.js | 0 src/electron/services.js | 61 + src/registerServiceWorker.js | 2 +- vue.config.js | 74 +- yarn.lock | 346 +- 240 files changed, 21004 insertions(+), 113 deletions(-) create mode 100644 napi/.editorconfig create mode 100644 napi/.eslintrc.js create mode 100644 napi/.gitignore create mode 100644 napi/.npmignore create mode 100644 napi/.prettierrc create mode 100644 napi/README.MD create mode 100644 napi/app.js create mode 100644 napi/buildScript.js create mode 100644 napi/interface.d.ts create mode 100644 napi/main.js create mode 100644 napi/module/activate_init_profile.js create mode 100644 napi/module/album.js create mode 100644 napi/module/album_detail.js create mode 100644 napi/module/album_detail_dynamic.js create mode 100644 napi/module/album_list.js create mode 100644 napi/module/album_list_style.js create mode 100644 napi/module/album_new.js create mode 100644 napi/module/album_newest.js create mode 100644 napi/module/album_songsaleboard.js create mode 100644 napi/module/album_sub.js create mode 100644 napi/module/album_sublist.js create mode 100644 napi/module/artist_album.js create mode 100644 napi/module/artist_desc.js create mode 100644 napi/module/artist_list.js create mode 100644 napi/module/artist_mv.js create mode 100644 napi/module/artist_songs.js create mode 100644 napi/module/artist_sub.js create mode 100644 napi/module/artist_sublist.js create mode 100644 napi/module/artist_top_song.js create mode 100644 napi/module/artists.js create mode 100644 napi/module/audio_match.js create mode 100644 napi/module/avatar_upload.js create mode 100644 napi/module/banner.js create mode 100644 napi/module/batch.js create mode 100644 napi/module/calendar.js create mode 100644 napi/module/captcha_sent.js create mode 100644 napi/module/captcha_verify.js create mode 100644 napi/module/cellphone_existence_check.js create mode 100644 napi/module/check_music.js create mode 100644 napi/module/cloudsearch.js create mode 100644 napi/module/comment.js create mode 100644 napi/module/comment_album.js create mode 100644 napi/module/comment_dj.js create mode 100644 napi/module/comment_event.js create mode 100644 napi/module/comment_floor.js create mode 100644 napi/module/comment_hot.js create mode 100644 napi/module/comment_hotwall_list.js create mode 100644 napi/module/comment_like.js create mode 100644 napi/module/comment_music.js create mode 100644 napi/module/comment_mv.js create mode 100644 napi/module/comment_new.js create mode 100644 napi/module/comment_playlist.js create mode 100644 napi/module/comment_video.js create mode 100644 napi/module/countries_code_list.js create mode 100644 napi/module/daily_signin.js create mode 100644 napi/module/digitalAlbum_ordering.js create mode 100644 napi/module/digitalAlbum_purchased.js create mode 100644 napi/module/dj_banner.js create mode 100644 napi/module/dj_category_excludehot.js create mode 100644 napi/module/dj_category_recommend.js create mode 100644 napi/module/dj_catelist.js create mode 100644 napi/module/dj_detail.js create mode 100644 napi/module/dj_hot.js create mode 100644 napi/module/dj_paygift.js create mode 100644 napi/module/dj_personalize_recommend.js create mode 100644 napi/module/dj_program.js create mode 100644 napi/module/dj_program_detail.js create mode 100644 napi/module/dj_program_toplist.js create mode 100644 napi/module/dj_program_toplist_hours.js create mode 100644 napi/module/dj_radio_hot.js create mode 100644 napi/module/dj_recommend.js create mode 100644 napi/module/dj_recommend_type.js create mode 100644 napi/module/dj_sub.js create mode 100644 napi/module/dj_sublist.js create mode 100644 napi/module/dj_subscriber.js create mode 100644 napi/module/dj_today_perfered.js create mode 100644 napi/module/dj_toplist.js create mode 100644 napi/module/dj_toplist_hours.js create mode 100644 napi/module/dj_toplist_newcomer.js create mode 100644 napi/module/dj_toplist_pay.js create mode 100644 napi/module/dj_toplist_popular.js create mode 100644 napi/module/event.js create mode 100644 napi/module/event_del.js create mode 100644 napi/module/event_forward.js create mode 100644 napi/module/fm_trash.js create mode 100644 napi/module/follow.js create mode 100644 napi/module/history_recommend_songs.js create mode 100644 napi/module/history_recommend_songs_detail.js create mode 100644 napi/module/homepage_block_page.js create mode 100644 napi/module/homepage_dragon_ball.js create mode 100644 napi/module/hot_topic.js create mode 100644 napi/module/like.js create mode 100644 napi/module/likelist.js create mode 100644 napi/module/login.js create mode 100644 napi/module/login_cellphone.js create mode 100644 napi/module/login_refresh.js create mode 100644 napi/module/login_status.js create mode 100644 napi/module/logout.js create mode 100644 napi/module/lyric.js create mode 100644 napi/module/msg_comments.js create mode 100644 napi/module/msg_forwards.js create mode 100644 napi/module/msg_notices.js create mode 100644 napi/module/msg_private.js create mode 100644 napi/module/msg_private_history.js create mode 100644 napi/module/mv_all.js create mode 100644 napi/module/mv_detail.js create mode 100644 napi/module/mv_detail_info.js create mode 100644 napi/module/mv_exclusive_rcmd.js create mode 100644 napi/module/mv_first.js create mode 100644 napi/module/mv_sub.js create mode 100644 napi/module/mv_sublist.js create mode 100644 napi/module/mv_url.js create mode 100644 napi/module/personal_fm.js create mode 100644 napi/module/personalized.js create mode 100644 napi/module/personalized_djprogram.js create mode 100644 napi/module/personalized_mv.js create mode 100644 napi/module/personalized_newsong.js create mode 100644 napi/module/personalized_privatecontent.js create mode 100644 napi/module/personalized_privatecontent_list.js create mode 100644 napi/module/playlist_catlist.js create mode 100644 napi/module/playlist_cover_update.js create mode 100644 napi/module/playlist_create.js create mode 100644 napi/module/playlist_delete.js create mode 100644 napi/module/playlist_desc_update.js create mode 100644 napi/module/playlist_detail.js create mode 100644 napi/module/playlist_highquality_tags.js create mode 100644 napi/module/playlist_hot.js create mode 100644 napi/module/playlist_mylike.js create mode 100644 napi/module/playlist_name_update.js create mode 100644 napi/module/playlist_order_update.js create mode 100644 napi/module/playlist_subscribe.js create mode 100644 napi/module/playlist_subscribers.js create mode 100644 napi/module/playlist_tags_update.js create mode 100644 napi/module/playlist_track_add.js create mode 100644 napi/module/playlist_track_delete.js create mode 100644 napi/module/playlist_tracks.js create mode 100644 napi/module/playlist_update.js create mode 100644 napi/module/playlist_video_recent.js create mode 100644 napi/module/playmode_intelligence_list.js create mode 100644 napi/module/program_recommend.js create mode 100644 napi/module/rebind.js create mode 100644 napi/module/recommend_resource.js create mode 100644 napi/module/recommend_songs.js create mode 100644 napi/module/register_cellphone.js create mode 100644 napi/module/related_allvideo.js create mode 100644 napi/module/related_playlist.js create mode 100644 napi/module/resource_like.js create mode 100644 napi/module/scrobble.js create mode 100644 napi/module/search.js create mode 100644 napi/module/search_default.js create mode 100644 napi/module/search_hot.js create mode 100644 napi/module/search_hot_detail.js create mode 100644 napi/module/search_multimatch.js create mode 100644 napi/module/search_suggest.js create mode 100644 napi/module/send_playlist.js create mode 100644 napi/module/send_text.js create mode 100644 napi/module/setting.js create mode 100644 napi/module/share_resource.js create mode 100644 napi/module/simi_artist.js create mode 100644 napi/module/simi_mv.js create mode 100644 napi/module/simi_playlist.js create mode 100644 napi/module/simi_song.js create mode 100644 napi/module/simi_user.js create mode 100644 napi/module/song_detail.js create mode 100644 napi/module/song_order_update.js create mode 100644 napi/module/song_url.js create mode 100644 napi/module/top_album.js create mode 100644 napi/module/top_artists.js create mode 100644 napi/module/top_list.js create mode 100644 napi/module/top_mv.js create mode 100644 napi/module/top_playlist.js create mode 100644 napi/module/top_playlist_highquality.js create mode 100644 napi/module/top_song.js create mode 100644 napi/module/toplist.js create mode 100644 napi/module/toplist_artist.js create mode 100644 napi/module/toplist_detail.js create mode 100644 napi/module/user_account.js create mode 100644 napi/module/user_audio.js create mode 100644 napi/module/user_binding.js create mode 100644 napi/module/user_cloud.js create mode 100644 napi/module/user_cloud_del.js create mode 100644 napi/module/user_cloud_detail.js create mode 100644 napi/module/user_detail.js create mode 100644 napi/module/user_dj.js create mode 100644 napi/module/user_event.js create mode 100644 napi/module/user_followeds.js create mode 100644 napi/module/user_follows.js create mode 100644 napi/module/user_level.js create mode 100644 napi/module/user_playlist.js create mode 100644 napi/module/user_record.js create mode 100644 napi/module/user_replacephone.js create mode 100644 napi/module/user_subcount.js create mode 100644 napi/module/user_update.js create mode 100644 napi/module/video_category_list.js create mode 100644 napi/module/video_detail.js create mode 100644 napi/module/video_detail_info.js create mode 100644 napi/module/video_group.js create mode 100644 napi/module/video_group_list.js create mode 100644 napi/module/video_sub.js create mode 100644 napi/module/video_timeline_all.js create mode 100644 napi/module/video_timeline_recommend.js create mode 100644 napi/module/video_url.js create mode 100644 napi/module/weblog.js create mode 100644 napi/module/yunbei.js create mode 100644 napi/module/yunbei_expense.js create mode 100644 napi/module/yunbei_info.js create mode 100644 napi/module/yunbei_receipt.js create mode 100644 napi/module/yunbei_sign.js create mode 100644 napi/module/yunbei_task_finish.js create mode 100644 napi/module/yunbei_tasks.js create mode 100644 napi/module/yunbei_tasks_todo.js create mode 100644 napi/module/yunbei_today.js create mode 100644 napi/package-lock.json create mode 100644 napi/package.json create mode 100644 napi/plugins/upload.js create mode 100644 napi/public/avatar_update.html create mode 100644 napi/public/index.html create mode 100644 napi/public/playlist_cover_update.html create mode 100644 napi/public/test.html create mode 100644 napi/renovate.json create mode 100644 napi/routes.js create mode 100644 napi/tsconfig.json create mode 100644 napi/util/apicache.js create mode 100644 napi/util/crypto.js create mode 100644 napi/util/index.js create mode 100644 napi/util/memory-cache.js create mode 100644 napi/util/request.js delete mode 100644 public/img/icons/android-chrome-maskable-192x192.png delete mode 100644 public/img/icons/android-chrome-maskable-512x512.png create mode 100644 src/electron/command.js create mode 100644 src/electron/menu.js create mode 100644 src/electron/preload.js create mode 100644 src/electron/services.js diff --git a/.gitignore b/.gitignore index 5f6a916..6b608ed 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,4 @@ pnpm-debug.log* #Electron-builder output /dist_electron -NeteaseCloudMusicApi-master NeteaseCloudMusicApi-master.zip diff --git a/.npmrc b/.npmrc index ed2598e..c154130 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,4 @@ # 如果发现 npm / yarn 安装太慢,可以解除注释 -# registry=https://registry.npm.taobao.org/ -# ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron \ No newline at end of file +registry=https://registry.npm.taobao.org/ +ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron +phantomjs_cdnurl=https://npm.taobao.org/dist/phantomjs \ No newline at end of file diff --git a/napi/.editorconfig b/napi/.editorconfig new file mode 100644 index 0000000..6c725ce --- /dev/null +++ b/napi/.editorconfig @@ -0,0 +1,34 @@ + +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{js,py}] +charset = utf-8 + +# 4 space indentation +[*.py] +indent_style = space +indent_size = 4 + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab + +# Indentation override for all JS under lib directory +[*.{js,ts}] +indent_style = space +indent_size = 2 + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/napi/.eslintrc.js b/napi/.eslintrc.js new file mode 100644 index 0000000..e4b2246 --- /dev/null +++ b/napi/.eslintrc.js @@ -0,0 +1,49 @@ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + ecmaVersion: 2018, + sourceType: 'module', + }, + plugins: ['html'], + extends: ['plugin:prettier/recommended'], + env: { + browser: true, + node: true, + }, + + rules: { + indent: ['error', 2, { SwitchCase: 1 }], + 'space-infix-ops': ['error', { int32Hint: false }], + 'key-spacing': [ + 2, + { + beforeColon: false, + afterColon: true, + }, + ], + 'no-octal': 2, + 'no-redeclare': 2, + 'comma-spacing': 2, + 'no-new-object': 2, + 'arrow-spacing': 2, + quotes: [ + 2, + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true, + }, + ], + }, + overrides: [ + { + files: ['**/*.ts'], + parser: '@typescript-eslint/parser', + extends: [ + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'prettier/@typescript-eslint', + ], + }, + ], +}; diff --git a/napi/.gitignore b/napi/.gitignore new file mode 100644 index 0000000..f284b53 --- /dev/null +++ b/napi/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules +*.log +.idea +.vscode \ No newline at end of file diff --git a/napi/.npmignore b/napi/.npmignore new file mode 100644 index 0000000..3f24434 --- /dev/null +++ b/napi/.npmignore @@ -0,0 +1,3 @@ +static +docs +node_modules \ No newline at end of file diff --git a/napi/.prettierrc b/napi/.prettierrc new file mode 100644 index 0000000..aea847c --- /dev/null +++ b/napi/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": true +} diff --git a/napi/README.MD b/napi/README.MD new file mode 100644 index 0000000..679cf3e --- /dev/null +++ b/napi/README.MD @@ -0,0 +1,312 @@ +# 网易云音乐 API + +网易云音乐 Node.js API service + +

+Version +License +devDependencies +devDependencies + +

+ +## 灵感来自 + +[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) + +[darknessomi/musicbox](https://github.com/darknessomi/musicbox) + +[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) + + +## 环境要求 + +需要 NodeJS 8.12+ 环境 + +## 安装 + +```shell + +$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git + +$ npm install +``` + +或者 +```shell +$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi.git + +$ npm install +``` + +## 运行 + +```shell +$ node app.js +``` + +服务器启动默认端口为 3000,若不想使用 3000 端口,可使用以下命令: Mac/Linux + +```shell +$ PORT=4000 node app.js +``` + +windows 下使用 git-bash 或者 cmder 等终端执行以下命令: + +```shell +$ set PORT=4000 && node app.js +``` + +## 可以在Node.js调用 +v3.31.0后支持Node.js调用,导入的方法为`module`内的文件名,返回内容包含`status`和`body`,`status`为状态码,`body`为请求返回内容,参考`module_example` 文件夹下的 `test.js` +```js +const { login_cellphone, user_cloud } = require('NeteaseCloudMusicApi') +async function main() { + try { + const result = await login_cellphone({ + phone: '手机号', + password: '密码' + }) + console.log(result) + const result2 = await user_cloud({ + cookie: result.body.cookie // 凭证 + }) + console.log(result2.body) + + } catch (error) { + console.log(error) + } +} +main() +``` + +## 支持 TypeScript +```ts +// test.ts +import { banner } from 'NeteaseCloudMusicApi' +banner({ type:0 }).then(res=>{ + console.log(res) +}) +``` + + +## 使用文档 + +[文档地址](https://binaryify.github.io/NeteaseCloudMusicApi) + +[文档地址2](https://neteasecloudmusicapi.vercel.app) + +![文档](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/docs.png) + + +## 功能特性 +1. 登录 +2. 刷新登录 +3. 发送验证码 +4. 校验验证码 +5. 注册(修改密码) +6. 获取用户信息 , 歌单,收藏,mv, dj 数量 +7. 获取用户歌单 +8. 获取用户电台 +9. 获取用户关注列表 +10. 获取用户粉丝列表 +11. 获取用户动态 +12. 获取用户播放记录 +13. 获取精品歌单 +14. 获取歌单详情 +15. 搜索 +16. 搜索建议 +17. 获取歌词 +18. 歌曲评论 +19. 收藏单曲到歌单 +20. 专辑评论 +21. 歌单评论 +22. mv 评论 +23. 电台节目评论 +24. banner +25. 获取歌曲详情 +26. 获取专辑内容 +27. 获取歌手单曲 +28. 获取歌手 mv +29. 获取歌手专辑 +30. 获取歌手描述 +31. 获取相似歌手 +32. 获取相似歌单 +33. 相似 mv +34. 获取相似音乐 +35. 获取最近 5 个听了这首歌的用户 +36. 获取每日推荐歌单 +37. 获取每日推荐歌曲 +38. 私人 FM +39. 签到 +40. 喜欢音乐 +41. 垃圾桶 +42. 歌单 ( 网友精选碟 ) +43. 新碟上架 +44. 热门歌手 +45. 最新 mv +46. 推荐 mv +47. 推荐歌单 +48. 推荐新音乐 +49. 推荐电台 +50. 推荐节目 +51. 独家放送 +52. mv 排行 +53. 获取 mv 数据 +54. 播放 mv/视频 +55. 排行榜 +56. 歌手榜 +57. 云盘 +58. 电台 - 推荐 +59. 电台 - 分类 +60. 电台 - 分类推荐 +61. 电台 - 订阅 +62. 电台 - 详情 +63. 电台 - 节目 +64. 给评论点赞 +65. 获取动态 +66. 热搜列表(简略) +67. 发送私信 +68. 发送私信歌单 +69. 新建歌单 +70. 收藏/取消收藏歌单 +71. 歌单分类 +72. 收藏的歌手列表 +73. 订阅的电台列表 +74. 相关歌单推荐 +75. 付费精选接口 +76. 音乐是否可用检查接口 +77. 登录状态 +78. 获取视频播放地址 +79. 发送/删除评论 +80. 热门评论 +81. 视频评论 +82. 退出登录 +83. 所有榜单 +84. 所有榜单内容摘要 +85. 收藏视频 +86. 收藏 MV +87. 视频详情 +88. 相关视频 +89. 关注用户 +90. 新歌速递 +91. 喜欢音乐列表(无序) +92. 收藏的 MV 列表 +93. 获取最新专辑 +94. 听歌打卡 +95. 获取视频标签/分类下的视频 +96. 已收藏专辑列表 +97. 获取动态评论 +98. 歌单收藏者列表 +99. 云盘歌曲删除 +100. 热门话题 +101. 电台 - 推荐类型 +102. 电台 - 非热门类型 +103. 电台 - 今日优选 +104. 心动模式/智能播放 +105. 转发动态 +106. 删除动态 +107. 分享歌曲、歌单、mv、电台、电台节目到动态 +108. 通知-私信 +109. 通知-评论 +110. 通知-@我 +111. 通知-通知 +112. 设置 +113. 云盘数据详情 +114. 私信内容 +115. 我的数字专辑 +116. batch批量请求接口 +117. 获取视频标签列表 +118. 全部mv +119. 网易出品mv +120. 收藏/取消收藏专辑 +121. 专辑动态信息 +122. 热搜列表(详细) +123. 更换绑定手机 +124. 检测手机号码是否已注册 +125. 初始化昵称 +126. 更新歌单描述 +127. 更新歌单名 +128. 更新歌单标签 +129. 默认搜索关键词 +130. 删除歌单 +131. 电台banner +132. 用户电台 +133. 热门电台 +134. 电台 - 节目详情 +135. 电台 - 节目榜 +136. 电台 - 新晋电台榜/热门电台榜 +137. 类别热门电台 +138. 云村热评 +139. 电台24小时节目榜 +140. 电台24小时主播榜 +141. 电台最热主播榜 +142. 电台主播新人榜 +143. 电台付费精品榜 +144. 歌手热门50首歌曲 +145. 购买数字专辑 +146. 获取 mv 点赞转发评论数数据 +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. 云贝todo任务 +184. 云贝今日签到信息 +185. 云贝完成任务 +186. 云贝收入 +187. 云贝支出 +188. 云贝账户信息 +189. 账号信息 + +## 更新日志 + +[changelog](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/CHANGELOG.MD) + +## 单元测试 + +```shell +$ npm test +``` + +![单元测试](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/screenshot1.png) +![单元测试](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/screenshot2.png) + +## 贡献者 +![](https://opencollective.com/NeteaseCloudMusicApi/contributors.svg?width=890) + + +## License + +[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/napi/app.js b/napi/app.js new file mode 100644 index 0000000..b1f3294 --- /dev/null +++ b/napi/app.js @@ -0,0 +1,117 @@ +const fs = require('fs'); +const path = require('path'); +const express = require('express'); +const bodyParser = require('body-parser'); +const request = require('./util/request'); +const packageJSON = require('./package.json'); +const exec = require('child_process').exec; +const cache = require('./util/apicache').middleware; +const { cookieToJson } = require('./util/index'); +const fileUpload = require('express-fileupload'); +// version check +exec('npm info NeteaseCloudMusicApi version', (err, stdout, stderr) => { + if (!err) { + let version = stdout.trim(); + if (packageJSON.version < version) { + console.log( + `最新版本: ${version}, 当前版本: ${packageJSON.version}, 请及时更新`, + ); + } + } +}); + +const app = express(); + +// CORS & Preflight request +app.use((req, res, next) => { + if (req.path !== '/' && !req.path.includes('.')) { + res.set({ + 'Access-Control-Allow-Credentials': true, + 'Access-Control-Allow-Origin': req.headers.origin || '*', + 'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type', + 'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS', + 'Content-Type': 'application/json; charset=utf-8', + }); + } + req.method === 'OPTIONS' ? res.status(204).end() : next(); +}); + +// cookie parser +app.use((req, res, next) => { + req.cookies = {}; + (req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => { + let crack = pair.indexOf('='); + if (crack < 1 || crack == pair.length - 1) return; + req.cookies[ + decodeURIComponent(pair.slice(0, crack)).trim() + ] = decodeURIComponent(pair.slice(crack + 1)).trim(); + }); + next(); +}); + +// body parser +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); + +app.use(fileUpload()); + +// static +app.use(express.static(path.join(__dirname, 'public'))); + +// cache +app.use(cache('2 minutes', (req, res) => res.statusCode === 200)); +// router +const special = { + 'daily_signin.js': '/daily_signin', + 'fm_trash.js': '/fm_trash', + 'personal_fm.js': '/personal_fm', +}; + +fs.readdirSync(path.join(__dirname, 'module')) + .reverse() + .forEach((file) => { + if (!file.endsWith('.js')) return; + let route = + file in special + ? special[file] + : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/'); + let question = require(path.join(__dirname, 'module', file)); + + app.use(route, (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + + question(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }); + }); + +const port = process.env.PORT || 3000; +const host = process.env.HOST || ''; + +app.server = app.listen(port, host, () => { + console.log(`server running @ http://${host ? host : 'localhost'}:${port}`); +}); + +module.exports = app; diff --git a/napi/buildScript.js b/napi/buildScript.js new file mode 100644 index 0000000..e557384 --- /dev/null +++ b/napi/buildScript.js @@ -0,0 +1,60 @@ +const fs = require('fs'); +const path = require('path'); +const express = require('express'); +const request = require('./util/request'); +const strip = require('strip-comments'); +var router = express.Router(); +const special = { + 'daily_signin.js': '/daily_signin', + 'fm_trash.js': '/fm_trash', + 'personal_fm.js': '/personal_fm', +}; + +const app = express(); +const temp = {}; + +fs.readdirSync(path.join(__dirname, 'module')) + .reverse() + .forEach((file) => { + if (!file.endsWith('.js')) return; + let route = + file in special + ? special[file] + : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/'); + let question = require(path.join(__dirname, 'module', file)); + // console.log(question.toString()) + const func = `(req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const ${file.replace(/\.js$/i, '')} = ${strip(question.toString())}; + ${file.replace(/\.js$/i, '')}(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + }`; + temp[route] = func; + }); + +fs.writeFileSync( + path.resolve(__dirname, './test_result.json'), + JSON.stringify(temp), +); diff --git a/napi/interface.d.ts b/napi/interface.d.ts new file mode 100644 index 0000000..548768d --- /dev/null +++ b/napi/interface.d.ts @@ -0,0 +1,1311 @@ +export interface RequestBaseConfig { + cookie?: string; + realIP?: string; // IPv4/IPv6 filled in X-Real-IP + proxy?: string; // HTTP proxy +} + +export interface MultiPageConfig { + limit?: string | number; + offset?: string | number; +} + +export interface ImageUploadConfig { + imgFile: { + name: string; + data: string | Buffer; + }; + imgSize?: number; + imgX?: number; + imgY?: number; +} + +export interface APIBaseResponse { + code: number; + cookie: string; + [index: string]: unknown; +} + +export interface Response { + status: number; // The Http Response Code + body: APIBaseResponse; // API Response body + cookie: string[]; +} + +export const enum SubAction { + sub = 1, + unsub = 0, +} + +export function activate_init_profile( + params: { nickname: string } & RequestBaseConfig, +): Promise; + +export function album( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function album_detail( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function album_detail_dynamic( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export const enum AlbumListArea { + all = 'ALL', + zh = 'ZH', + ea = 'EA', + kr = 'KR', + jp = 'JP', +} + +export const enum ListOrder { + hot = 'hot', + new = 'new', +} + +export function album_list( + params: { area?: AlbumListArea; type: string } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export const enum AlbumListStyleArea { + zh = 'Z_H', + ea = 'E_A', + kr = 'KR', + jp = 'JP', +} + +export function album_list_style( + params: { area?: AlbumListStyleArea } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function album_new( + params: { area?: AlbumListArea } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function album_newest(params: RequestBaseConfig): Promise; + +export const enum AlbumSongsaleboardType { + daily = 'daily', + week = 'week', + year = 'year', + total = 'total', +} + +export const enum AlbumSongsaleboardAlbumType { + album = 0, + single = 1, +} + +export function album_songsaleboard( + params: { + albumType?: AlbumSongsaleboardAlbumType; // 0 为数字专辑,1 为数字单曲 + type?: AlbumSongsaleboardType; + year?: string | number; // 年份,默认本年。 type 为 year 时有效 + } & RequestBaseConfig, +): Promise; + +export function album_sub( + params: { + id: string | number; + t: SubAction; + } & RequestBaseConfig, +): Promise; + +export function album_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function artist_album( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function artist_desc( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export const enum ArtistListArea { + zh = 'Z_H', + ea = 'E_A', + kr = 'KR', + jp = 'JP', +} + +export const enum ArtistArea { + all = '-1', + zh = '7', + ea = '96', + ja = '8', + kr = '16', + other = '0', +} + +export const enum ArtistType { + male = '1', + female = '2', + band = '3', +} + +export function artist_list( + params: { + area: ArtistArea; + initial?: + | 'a' + | 'b' + | 'c' + | 'd' + | 'e' + | 'f' + | 'g' + | 'h' + | 'i' + | 'j' + | 'k' + | 'l' + | 'm' + | 'n' + | 'o' + | 'p' + | 'q' + | 'r' + | 's' + | 't' + | 'u' + | 'v' + | 'w' + | 'x' + | 'y' + | 'z' + | 'A' + | 'B' + | 'C' + | 'D' + | 'E' + | 'F' + | 'G' + | 'H' + | 'I' + | 'J' + | 'K' + | 'L' + | 'M' + | 'N' + | 'O' + | 'P' + | 'Q' + | 'R' + | 'S' + | 'T' + | 'U' + | 'V' + | 'W' + | 'X' + | 'Y' + | 'Z'; + type?: ArtistType; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function artist_mv( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export const enum ArtistSongsOrder { + hot = 'hot', + time = 'time', +} + +export function artist_songs( + params: { + id: string | number; + order?: ArtistSongsOrder; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function artist_sub( + params: { id: string | number; t: SubAction } & RequestBaseConfig, +): Promise; + +export function artist_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function artist_top_song( + params: { + id: string | number; + } & RequestBaseConfig, +): Promise; + +export function artists( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function avatar_upload( + params: ImageUploadConfig & RequestBaseConfig, +): Promise; + +export const enum BannerType { + pc = 0, + android = 1, + iphone = 2, + ipad = 3, +} + +export function banner( + params: { type?: BannerType } & RequestBaseConfig, +): Promise; + +export function batch( + params: { [index: string]: unknown } & RequestBaseConfig, +): Promise; + +export function captcha_sent( + params: { cellphone: string; ctcode?: string } & RequestBaseConfig, +): Promise; + +export function captcha_verify( + params: { + ctcode?: string; + cellphone: string; + captcha: string; + } & RequestBaseConfig, +): Promise; + +export function cellphone_existence_check( + params: { cellphone: string; countrycode: string } & RequestBaseConfig, +): Promise; + +export function check_music( + params: { id: string | number; br: string | number } & RequestBaseConfig, +): Promise; + +export const enum SearchType { + single = 1, + album = 10, + artist = 100, + playlist = 1000, + user = 1002, + mv = 1004, + lyric = 1006, + dj = 1009, + video = 1014, + complex = 1018, +} + +export function cloudsearch( + params: { + keywords: string; + type?: SearchType; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export const enum CommentType { + song = 0, + mv = 1, + playlist = 2, + album = 3, + dj = 4, + video = 5, + event = 6, +} + +export const enum CommentAction { + add = 1, + delete = 0, + reply = 2, +} + +export function comment( + params: { + id: string | number; + type: CommentType; + t: CommentAction.delete; + commentId: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment( + params: { + type: CommentType.event; + t: CommentAction.delete; + threadId: string; + commentId: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment( + params: { + id: string | number; + type: CommentType; + t: CommentAction.add; + content: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment( + params: { + type: CommentType.event; + t: CommentAction.add; + threadId: string; + content: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment( + params: { + id: string | number; + type: CommentType; + t: CommentAction.reply; + content: string | number; + commentId: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment( + params: { + type: CommentType.event; + t: CommentAction.reply; + threadId: string; + content: string | number; + commentId: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment_album( + params: { + id: string | number; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_dj( + params: { + id: string | number; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_event( + params: { + threadId: string; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_floor( + params: { + id: string | number; + parentCommentId: string | number; + type: CommentType; + limit?: string | number; + time?: string | number; + } & RequestBaseConfig, +): Promise; + +export function comment_hot( + params: { + id: string | number; + type: CommentType; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_hotwall_list( + params: RequestBaseConfig, +): Promise; + +export function comment_like( + params: { + id: string | number; + type: CommentType; + t: SubAction; + cid: string | number; + threadId?: string; + } & RequestBaseConfig, +): Promise; + +export function comment_music( + params: { + id: string | number; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_mv( + params: { + id: string | number; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_playlist( + params: { + id: string | number; + + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function comment_video( + params: { + id: string | number; + before?: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function countries_code_list( + params: RequestBaseConfig, +): Promise; + +export const enum DailySigninType { + android = 0, + pc = 1, +} + +export function daily_signin( + params: { type?: DailySigninType } & RequestBaseConfig, +): Promise; + +export function digitalAlbum_ordering( + params: { + payment: string; + id: string | number; + quantity: string; + } & RequestBaseConfig, +): Promise; + +export function digitalAlbum_purchased( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_banner(params: RequestBaseConfig): Promise; + +export function dj_category_excludehot( + params: RequestBaseConfig, +): Promise; + +export function dj_category_recommend( + params: RequestBaseConfig, +): Promise; + +export function dj_catelist(params: RequestBaseConfig): Promise; + +export function dj_detail( + params: { rid: string | number } & RequestBaseConfig, +): Promise; + +export function dj_hot( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_paygift( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_personalize_recommend( + params: { limit?: string | number } & RequestBaseConfig, +): Promise; + +export function dj_program( + params: { + rid: string | number; + asc: 'true' | 1 | 'false' | 0; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function dj_program_detail( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function dj_program_toplist( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_program_toplist_hours( + params: { limit?: string | number } & RequestBaseConfig, +): Promise; + +export function dj_radio_hot( + params: { + cateId: string | number; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function dj_recommend(params: RequestBaseConfig): Promise; + +/* + 有声书 10001 + 知识技能 453050 + 商业财经 453051 + 人文历史 11 + 外语世界 13 + 亲子宝贝 14 + 创作|翻唱 2001 + 音乐故事 2 + 3D|电子 10002 + 相声曲艺 8 + 情感调频 3 + 美文读物 6 + 脱口秀 5 + 广播剧 7 + 二次元 3001 + 明星做主播 1 + 娱乐|影视 4 + 科技科学 453052 + 校园|教育 4001 + 旅途|城市 12 +*/ + +export function dj_recommend_type( + params: { type: number } & RequestBaseConfig, +): Promise; + +export function dj_sub( + params: { t: SubAction; rid: string | number } & RequestBaseConfig, +): Promise; + +export function dj_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_today_perfered( + params: { page?: string | number } & RequestBaseConfig, +): Promise; + +export function dj_toplist( + params: { type?: ListOrder } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_toplist_hours( + params: { limit?: string | number } & RequestBaseConfig, +): Promise; + +export function dj_toplist_newcomer( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function dj_toplist_pay( + params: { limit?: string | number } & RequestBaseConfig, +): Promise; + +export function dj_toplist_popular( + params: { limit?: string | number } & RequestBaseConfig, +): Promise; + +export function event( + params: { pagesize?: number; lasttime?: number } & RequestBaseConfig, +): Promise; + +export function event_del( + params: { evId: string | number } & RequestBaseConfig, +): Promise; + +export function event_forward( + params: { + forwords: string; + evId: string | number; + uid: string | number; + } & RequestBaseConfig, +): Promise; + +export function fm_trash( + params: { id: string | number; time?: string | number } & RequestBaseConfig, +): Promise; + +export function follow( + params: { t: SubAction; id: string | number } & RequestBaseConfig, +): Promise; + +export function history_recommend_songs( + params: RequestBaseConfig, +): Promise; + +export function history_recommend_songs_detail( + params: { date?: string } & RequestBaseConfig, +): Promise; + +export function homepage_block_page( + params: { refresh?: 'true' | 'false' | boolean } & RequestBaseConfig, +): Promise; + +export function homepage_dragon_ball( + params: RequestBaseConfig, +): Promise; + +export function hot_topic( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function like( + params: { + like?: 'true' | 'false' | boolean; + id: string | number; + alg?: string; + time?: string | number; + } & RequestBaseConfig, +): Promise; + +export function likelist( + params: { uid: string | number } & RequestBaseConfig, +): Promise; + +export function login( + params: { email: string; password: string } & RequestBaseConfig, +): Promise; + +export function login( + params: { email: string; md5_password: string } & RequestBaseConfig, +): Promise; + +export function login_cellphone( + params: { + phone: string; + countrycode?: string; + password: string; + } & RequestBaseConfig, +): Promise; + +export function login_cellphone( + params: { + phone: string; + countrycode?: string; + md5_password: string; + } & RequestBaseConfig, +): Promise; + +export function login_refresh(params: RequestBaseConfig): Promise; + +export function login_status(params: RequestBaseConfig): Promise; + +export function logout(params: RequestBaseConfig): Promise; + +export function lyric( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function msg_comments( + params: { + uid: string | number; + before?: string | number; + limit?: string | number; + } & RequestBaseConfig, +): Promise; + +export function msg_forwards( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function msg_notices( + params: { + limit?: string | number; + lasttime?: string | number; + } & RequestBaseConfig, +): Promise; + +export function msg_private( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function msg_private_history( + params: { + before?: string | number; + limit?: string | number; + uid: string | number; + } & RequestBaseConfig, +): Promise; + +export const enum MvArea { + all = '全部', + zh = '内地', + hk = '港台', + ea = '欧美', + kr = '韩国', + jp = '日本', +} + +export const enum MvType { + all = '全部', + offical = '官方版', + raw = '原生', + live = '现场版', + netease = '网易出品', +} + +export const enum MvOrder { + trend = '上升最快', + hot = '最热', + new = '最新', +} + +export function mv_all( + params: { + area?: MvArea; + type?: MvType; + order?: MvOrder; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function mv_detail( + params: { mvid?: string | number } & RequestBaseConfig, +): Promise; + +export function mv_detail_info( + params: { mvid: string | number } & RequestBaseConfig, +): Promise; + +export function mv_exclusive_rcmd( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function mv_first( + params: { area?: MvArea; limit?: string | number } & RequestBaseConfig, +): Promise; + +export function mv_sub( + params: { t: SubAction; mvid: string | number } & RequestBaseConfig, +): Promise; + +export function mv_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function mv_url( + params: { id?: string | number; r?: string | number } & RequestBaseConfig, +): Promise; + +export function personal_fm(params: RequestBaseConfig): Promise; + +export function personalized( + params: { limit?: string | number } & RequestBaseConfig, +): Promise; + +export function personalized_djprogram( + params: RequestBaseConfig, +): Promise; + +export function personalized_mv(params: RequestBaseConfig): Promise; + +export function personalized_newsong( + params: { + area?: string | number; + limit?: string | number; + } & RequestBaseConfig, +): Promise; + +export function personalized_privatecontent( + params: RequestBaseConfig, +): Promise; + +export function personalized_privatecontent_list( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function playlist_catlist(params: RequestBaseConfig): Promise; + +export function playlist_cover_update( + params: { id: string } & ImageUploadConfig & RequestBaseConfig, +): Promise; + +export function playlist_create( + params: { + name: string; + privacy: 0 | 10; + type?: PlaylistType; + } & RequestBaseConfig, +): Promise; + +export function playlist_delete( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function playlist_desc_update( + params: { id: string | number; desc: string } & RequestBaseConfig, +): Promise; + +export function playlist_detail( + params: { id: string | number; s?: string | number } & RequestBaseConfig, +): Promise; + +export function playlist_highquality_tags( + params: RequestBaseConfig, +): Promise; + +export function playlist_hot(params: RequestBaseConfig): Promise; + +export function playlist_name_update( + params: { id: string | number; name: string } & RequestBaseConfig, +): Promise; + +export function playlist_order_update( + params: { ids: string } & RequestBaseConfig, +): Promise; + +export function playlist_subscribe( + params: { t: SubAction; id: string | number } & RequestBaseConfig, +): Promise; + +export function playlist_subscribers( + params: { id?: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function playlist_tags_update( + params: { id: string | number; tags: string } & RequestBaseConfig, +): Promise; + +export function playlist_tracks( + params: { + op: 'add' | 'del'; + pid: string | number; + tracks: string; + } & RequestBaseConfig, +): Promise; + +export function playlist_update( + params: { + id: string | number; + name: string; + desc?: string; + tags?: string; + } & RequestBaseConfig, +): Promise; + +export function playmode_intelligence_list( + params: { + id: string | number; + pid: string | number; + sid?: string | number; + count?: string | number; + } & RequestBaseConfig, +): Promise; + +export function program_recommend( + params: { type: string } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function rebind( + params: { + captcha: string; + phone: string; + oldcaptcha: string; + ctcode?: string; + } & RequestBaseConfig, +): Promise; + +export function recommend_resource( + params: RequestBaseConfig, +): Promise; + +export function recommend_songs(params: RequestBaseConfig): Promise; + +export function register_cellphone( + params: { + captcha: string; + phone: string; + password: string; + nickname: string; + } & RequestBaseConfig, +): Promise; + +export function related_allvideo( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function related_playlist( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export const enum ResourceType { + mv = 1, + dj = 4, + video = 5, + event = 6, +} +type PlaylistType = 'NROMAL' | 'VIDEO'; + +export function resource_like( + params: { + t: SubAction; + type: ResourceType; + id?: string | number; + threadId?: string; + } & RequestBaseConfig, +): Promise; + +export function scrobble( + params: { + id: string | number; + sourceid: string | number; + time: string | number; + } & RequestBaseConfig, +): Promise; + +export function search( + params: { + keywords: string; + type?: SearchType; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function search_default(params: RequestBaseConfig): Promise; + +export function search_hot(params: RequestBaseConfig): Promise; + +export function search_hot_detail(params: RequestBaseConfig): Promise; + +export function search_multimatch( + params: { type?: number; keywords: string } & RequestBaseConfig, +): Promise; + +export const enum SearchSuggestType { + mobile = 'mobile', + web = 'web', +} + +export function search_suggest( + params: { keywords: string; type?: SearchSuggestType } & RequestBaseConfig, +): Promise; + +export function send_playlist( + params: { + playlist: string | number; + msg: string; + user_ids: string; + } & RequestBaseConfig, +): Promise; + +export function send_text( + params: { msg: string; user_ids: string } & RequestBaseConfig, +): Promise; + +export function setting(params: RequestBaseConfig): Promise; + +export const enum ShareResourceType { + song = 'song', + playlist = 'playlist', + mv = 'mv', + djprogram = 'djprogram', + djradio = 'djradio', +} + +export function share_resource( + params: { + type?: ShareResourceType; + msg?: string; + id?: string | number; + } & RequestBaseConfig, +): Promise; + +export function simi_artist( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function simi_mv( + params: { mvid: string | number } & RequestBaseConfig, +): Promise; + +export function simi_playlist( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function simi_song( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function simi_user( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function song_detail( + params: { ids: string } & RequestBaseConfig, +): Promise; + +export function song_order_update( + params: { pid: string | number; ids: string } & RequestBaseConfig, +): Promise; + +export function song_url( + params: { id: string | number; br?: string | number } & RequestBaseConfig, +): Promise; + +export function top_album( + params: { + area?: AlbumListArea; + type?: ListOrder; + year?: string; + mouth?: string; + } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function top_artists( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function top_list( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function top_mv( + params: { area?: MvArea } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function top_playlist( + params: { cat?: string; order?: ListOrder } & MultiPageConfig & + RequestBaseConfig, +): Promise; + +export function top_playlist_highquality( + params: { + cat?: string; + before?: string | number; + limit?: string | number; + } & RequestBaseConfig, +): Promise; + +export const enum TopSongType { + all = 0, + zh = 7, + ea = 96, + kr = 16, + ja = 8, +} + +export function top_song( + params: { type: TopSongType } & RequestBaseConfig, +): Promise; + +export function toplist(params: RequestBaseConfig): Promise; + +export const enum ToplistArtistType { + zh = 1, + ea = 2, + kr = 3, + ja = 4, +} + +export function toplist_artist( + params: { type?: ToplistArtistType } & RequestBaseConfig, +): Promise; + +export function toplist_detail(params: RequestBaseConfig): Promise; + +export function user_audio( + params: { uid: string | number } & RequestBaseConfig, +): Promise; + +export function user_cloud( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function user_cloud_del( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function user_cloud_detail( + params: { id: string | number } & RequestBaseConfig, +): Promise; + +export function user_detail( + params: { uid: string | number } & RequestBaseConfig, +): Promise; + +export function user_dj( + params: { uid: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function user_event( + params: { + lasttime?: string | number; + limit?: string | number; + uid: string | number; + } & RequestBaseConfig, +): Promise; + +export function user_followeds( + params: { + uid: string | number; + lasttime?: string | number; + limit?: string | number; + } & RequestBaseConfig, +): Promise; + +export function user_follows( + params: { uid: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export function user_level(params: RequestBaseConfig): Promise; + +export function user_playlist( + params: { uid: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise; + +export const enum UserRecordType { + all = 0, + weekly = 1, +} + +export function user_record( + params: { uid: string | number; type?: UserRecordType } & RequestBaseConfig, +): Promise; + +export function user_subcount(params: RequestBaseConfig): Promise; + +export function user_update( + params: { + birthday: string; + city: string; + gender: string; + nickname: string; + province: string; + signature: string; + } & RequestBaseConfig, +): Promise; + +export function video_category_list( + params: MultiPageConfig & RequestBaseConfig, +): Promise; + +export function video_detail( + params: { id: string } & RequestBaseConfig, +): Promise; + +export function video_detail_info( + params: { vid: string } & RequestBaseConfig, +): Promise; + +export function video_group( + params: { id: string; offset?: string | number } & RequestBaseConfig, +): Promise; + +export function video_group_list(params: RequestBaseConfig): Promise; + +export function video_sub( + params: { t?: SubAction; id: string } & RequestBaseConfig, +): Promise; + +export function video_timeline_all( + params: { offset?: string | number } & RequestBaseConfig, +): Promise; + +export function video_timeline_recommend( + params: { offset?: string | number } & RequestBaseConfig, +): Promise; + +export function video_url( + params: { id: string | number; res?: number } & RequestBaseConfig, +): Promise; + +export function weblog( + params: { data?: { [index: string]: unknown } } & RequestBaseConfig, +): Promise; + +export function playlist_mylike( + params: { + time?: number | string; + limit: number | string; + } & RequestBaseConfig, +): Promise; + +export function playlist_track_add( + params: { pid?: number | string; ids: number | string } & RequestBaseConfig, +): Promise; + +export function playlist_track_delete( + params: { pid?: number | string; ids: number | string } & RequestBaseConfig, +): Promise; + +export function comment_new( + params: { + type?: number | string; + id: number | string; + pageNo?: number | string; + pageSize?: number | string; + sortType?: number | string; + } & RequestBaseConfig, +): Promise; + +export function calendar( + params: { + startTime?: number | string; + endTime: number | string; + } & RequestBaseConfig, +): Promise; + +export function playlist_video_recent( + params: RequestBaseConfig, +): Promise; + +export function user_binding( + params: { uid?: number | string } & RequestBaseConfig, +): Promise; + +export function user_replacephone( + params: { + phone: number | string; + captcha: number | string; + oldcaptcha: number | string; + countrycode?: number | string; + } & RequestBaseConfig, +): Promise; + +export function user_safe(params: RequestBaseConfig): Promise; + +export function dj_subscriber( + params: { + id: number | string; + limit?: number | string; + time?: number | string; + } & RequestBaseConfig, +): Promise; + +export function user_account(params: RequestBaseConfig): Promise; + +export function yunbei(params: RequestBaseConfig): Promise; + +export function yunbei_info(params: RequestBaseConfig): Promise; + +export function yunbei_sign(params: RequestBaseConfig): Promise; + +export function yunbei_receipt( + params: { + limit?: number | string; + offset?: number | string; + } & RequestBaseConfig, +): Promise; + +export function yunbei_expense( + params: { + limit?: number | string; + offset?: number | string; + } & RequestBaseConfig, +): Promise; + +export function yunbei_tasks(params: RequestBaseConfig): Promise; + +export function yunbei_today(params: RequestBaseConfig): Promise; + +export function yunbei_tasks_todo(params: RequestBaseConfig): Promise; + +export function yunbei_task_finish( + params: { + userTaskId: number | string; + depositCode?: number | string; + } & RequestBaseConfig, +): Promise; diff --git a/napi/main.js b/napi/main.js new file mode 100644 index 0000000..23c9295 --- /dev/null +++ b/napi/main.js @@ -0,0 +1,26 @@ +const fs = require('fs'); +const path = require('path'); +const request = require('./util/request'); +const { cookieToJson } = require('./util/index'); + +let obj = {}; +fs.readdirSync(path.join(__dirname, 'module')) + .reverse() + .forEach((file) => { + if (!file.endsWith('.js')) return; + let fileModule = require(path.join(__dirname, 'module', file)); + obj[file.split('.').shift()] = function (data) { + if (typeof data.cookie === 'string') { + data.cookie = cookieToJson(data.cookie); + } + return fileModule( + { + ...data, + cookie: data.cookie ? data.cookie : {}, + }, + request, + ); + }; + }); + +module.exports = obj; diff --git a/napi/module/activate_init_profile.js b/napi/module/activate_init_profile.js new file mode 100644 index 0000000..fc69dcf --- /dev/null +++ b/napi/module/activate_init_profile.js @@ -0,0 +1,19 @@ +// 初始化名字 + +module.exports = (query, request) => { + const data = { + nickname: query.nickname, + }; + return request( + 'POST', + `https://music.163.com/eapi/activate/initProfile`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/activate/initProfile', + }, + ); +}; diff --git a/napi/module/album.js b/napi/module/album.js new file mode 100644 index 0000000..dd8147a --- /dev/null +++ b/napi/module/album.js @@ -0,0 +1,15 @@ +// 专辑内容 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/album/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_detail.js b/napi/module/album_detail.js new file mode 100644 index 0000000..8bdc16d --- /dev/null +++ b/napi/module/album_detail.js @@ -0,0 +1,17 @@ +// 数字专辑详情 +module.exports = (query, request) => { + const data = { + id: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_detail_dynamic.js b/napi/module/album_detail_dynamic.js new file mode 100644 index 0000000..0e30cd3 --- /dev/null +++ b/napi/module/album_detail_dynamic.js @@ -0,0 +1,17 @@ +// 专辑动态信息 +module.exports = (query, request) => { + const data = { + id: query.id, + }; + return request( + 'POST', + `https://music.163.com/api/album/detail/dynamic`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_list.js b/napi/module/album_list.js new file mode 100644 index 0000000..f7b4840 --- /dev/null +++ b/napi/module/album_list.js @@ -0,0 +1,21 @@ +// 数字专辑-新碟上架 +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + type: query.type, + }; + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_list_style.js b/napi/module/album_list_style.js new file mode 100644 index 0000000..849bf49 --- /dev/null +++ b/napi/module/album_list_style.js @@ -0,0 +1,20 @@ +// 数字专辑-语种风格馆 +module.exports = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + total: true, + area: query.area || 'Z_H', //Z_H:华语,E_A:欧美,KR:韩国,JP:日本 + }; + return request( + 'POST', + `https://music.163.com/weapi/vipmall/appalbum/album/style`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_new.js b/napi/module/album_new.js new file mode 100644 index 0000000..92dd0b9 --- /dev/null +++ b/napi/module/album_new.js @@ -0,0 +1,15 @@ +// 全部新碟 +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + }; + return request('POST', `https://music.163.com/weapi/album/new`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/album_newest.js b/napi/module/album_newest.js new file mode 100644 index 0000000..6fa6ee6 --- /dev/null +++ b/napi/module/album_newest.js @@ -0,0 +1,15 @@ +// 最新专辑 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/discovery/newAlbum`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_songsaleboard.js b/napi/module/album_songsaleboard.js new file mode 100644 index 0000000..236864f --- /dev/null +++ b/napi/module/album_songsaleboard.js @@ -0,0 +1,24 @@ +// 数字专辑&数字单曲-榜单 +module.exports = (query, request) => { + let data = { + albumType: query.albumType || 0, //0为数字专辑,1为数字单曲 + }; + const type = query.type || 'daily'; // daily,week,year,total + if (type === 'year') { + data = { + ...data, + year: query.year, + }; + } + return request( + 'POST', + `https://music.163.com/api/feealbum/songsaleboard/${type}/type`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/album_sub.js b/napi/module/album_sub.js new file mode 100644 index 0000000..3be83fb --- /dev/null +++ b/napi/module/album_sub.js @@ -0,0 +1,14 @@ +// 收藏/取消收藏专辑 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { + id: query.id, + }; + return request('POST', `https://music.163.com/api/album/${query.t}`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/album_sublist.js b/napi/module/album_sublist.js new file mode 100644 index 0000000..d71ab5b --- /dev/null +++ b/napi/module/album_sublist.js @@ -0,0 +1,15 @@ +// 已收藏专辑列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/album/sublist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/artist_album.js b/napi/module/artist_album.js new file mode 100644 index 0000000..7e37321 --- /dev/null +++ b/napi/module/artist_album.js @@ -0,0 +1,20 @@ +// 歌手专辑列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/artist/albums/${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/artist_desc.js b/napi/module/artist_desc.js new file mode 100644 index 0000000..120c592 --- /dev/null +++ b/napi/module/artist_desc.js @@ -0,0 +1,18 @@ +// 歌手介绍 + +module.exports = (query, request) => { + const data = { + id: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/artist/introduction`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/artist_list.js b/napi/module/artist_list.js new file mode 100644 index 0000000..605b376 --- /dev/null +++ b/napi/module/artist_list.js @@ -0,0 +1,37 @@ +// 歌手分类 + +/* + type 取值 + 1:男歌手 + 2:女歌手 + 3:乐队 + + area 取值 + -1:全部 + 7华语 + 96欧美 + 8:日本 + 16韩国 + 0:其他 + + initial 取值 a-z/A-Z +*/ + +module.exports = (query, request) => { + const data = { + initial: isNaN(query.initial) + ? (query.initial || '').toUpperCase().charCodeAt() || undefined + : query.initial, + offset: query.offset || 0, + limit: query.limit || 30, + total: true, + type: query.type || '1', + area: query.area, + }; + return request('POST', `https://music.163.com/api/v1/artist/list`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/artist_mv.js b/napi/module/artist_mv.js new file mode 100644 index 0000000..1195c92 --- /dev/null +++ b/napi/module/artist_mv.js @@ -0,0 +1,16 @@ +// 歌手相关MV + +module.exports = (query, request) => { + const data = { + artistId: query.id, + limit: query.limit, + offset: query.offset, + total: true, + }; + return request('POST', `https://music.163.com/weapi/artist/mvs`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/artist_songs.js b/napi/module/artist_songs.js new file mode 100644 index 0000000..4f74653 --- /dev/null +++ b/napi/module/artist_songs.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + id: query.id, + private_cloud: 'true', + work_type: 1, + order: query.order || 'hot', //hot,time + offset: query.offset || 0, + limit: query.limit || 100, + }; + return request('POST', `https://music.163.com/api/v1/artist/songs`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/artist_sub.js b/napi/module/artist_sub.js new file mode 100644 index 0000000..abe238b --- /dev/null +++ b/napi/module/artist_sub.js @@ -0,0 +1,20 @@ +// 收藏与取消收藏歌手 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { + artistId: query.id, + artistIds: '[' + query.id + ']', + }; + return request( + 'POST', + `https://music.163.com/weapi/artist/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/artist_sublist.js b/napi/module/artist_sublist.js new file mode 100644 index 0000000..f1a8b31 --- /dev/null +++ b/napi/module/artist_sublist.js @@ -0,0 +1,15 @@ +// 关注歌手列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/artist/sublist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/artist_top_song.js b/napi/module/artist_top_song.js new file mode 100644 index 0000000..79698a7 --- /dev/null +++ b/napi/module/artist_top_song.js @@ -0,0 +1,12 @@ +// 歌手热门 50 首歌曲 +module.exports = (query, request) => { + const data = { + id: query.id, + }; + return request('POST', `https://music.163.com/api/artist/top/song`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/artists.js b/napi/module/artists.js new file mode 100644 index 0000000..0ab1d87 --- /dev/null +++ b/napi/module/artists.js @@ -0,0 +1,15 @@ +// 歌手单曲 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/artist/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/audio_match.js b/napi/module/audio_match.js new file mode 100644 index 0000000..53b5c20 --- /dev/null +++ b/napi/module/audio_match.js @@ -0,0 +1,19 @@ +const realData = + 'eJx10mtIU2EcBvDtnCwNMfO2klUSmSQ5ZugKW/v/0TIjJVdhDStbXpqXrhY5Kwhtrcwiut9VSqMUMxX6IFqsD92sD1YgWGHRBcowKrpnPa/v+drg4flt572ds2PQ6XQut7MwJ940w2TOyS0pzF+/BV/MJrNO+3TVLOHUzKx5iw3/H5uZ7yxegct3tTl7Cr6QEa0gZ/dZOFsvfe5YHe1D+yFZxpncqEj/cCdwoirdVxHNnZrX3xygU5g7Eh6I9uOx8Ch4y9FQjlKkDz1pYrFXIJLUOovFGcYivqJgXqaXDqu7Rzc0XzmZxG81B/fF8wRVusn2jN5rDnwca8tFhyAJP4L4qiI9vX8cWzEmVKzT/46qxNpIdZOZz2HNcHhSkZ3D4AjYFpfGFkX6+dB+FvcSBe/SWbkLPVnEOJ1DFelXxVVci/Wj4TsBLhrQ/LGoaU4HxsTA28L76Cc8Dfau/U6F6FgkyBDDJar0g8tesmOvOHioWeXXmme6l3MLbIIre6wciU5E2t/k8WVxHfHvuUWXsH4SPCv1NW1Cz0aivgYO34vw1AEvi3MlIw0xHl6JNVPEGW41UJsqPaXYYTuEnotMdHwYfv7CFR/i+aXmrY5wrlSkEwr+0EJ0GvLmdw4/RS9Amj93UAbGZMIF40ezE3PtcG/yBWrT3L6oh66hFyMXK4xsUKT7aufzapxnFTwiNc3Wis5Bdm+OYCvmOuHj/ZeoQPOI00PUrUjXpG+kMFU61tFFDvQaZOn5DH4mzoLw4Hsaj14rzu/K4jF66fSWTnJinW3wBvcveqjZN3iFjKp0qKuF1mi21keST3NtTcbwu1eG3Dussr9eemljLIco0tVH7HwA493wOr+FlIjfy+GvkR4uwfjt4v/6G8K3NX8K38lt6B1ISa+Bv2O8Fy69foZOovci2S4Lr1aku4P9OEWVTt9wgMQ7exgJ8JXyI0W694WFyuBjcH75XyrEXsfhg+ZSvqZIf/Lct8Wp0md2tJN4PifEfjcm8gu02Ptbj459eum8eg8bFWlLXTb/A+uo9bM='; +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + algorithmCode: 'shazam_v2', + times: 1, + sessionId: 'C999431ACDC84EDBB984763654E6F8D7', + duration: 3.3066249999999995, + from: 'recognize-song', + rawdata: realData, + }; + return request('POST', `https://music.163.com/api/music/audio/match`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/avatar_upload.js b/napi/module/avatar_upload.js new file mode 100644 index 0000000..a09e65e --- /dev/null +++ b/napi/module/avatar_upload.js @@ -0,0 +1,27 @@ +const uploadPlugin = require('../plugins/upload'); +module.exports = async (query, request) => { + const uploadInfo = await uploadPlugin(query, request); + const res = await request( + 'POST', + `https://music.163.com/weapi/user/avatar/upload/v1`, + { + imgid: uploadInfo.imgId, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + return { + status: 200, + body: { + code: 200, + data: { + ...uploadInfo, + ...res.body, + }, + }, + }; +}; diff --git a/napi/module/banner.js b/napi/module/banner.js new file mode 100644 index 0000000..c2fb384 --- /dev/null +++ b/napi/module/banner.js @@ -0,0 +1,17 @@ +// 首页轮播图 + +module.exports = (query, request) => { + const type = + { + 0: 'pc', + 1: 'android', + 2: 'iphone', + 3: 'ipad', + }[query.type || 0] || 'pc'; + return request( + 'POST', + `https://music.163.com/api/v2/banner/get`, + { clientType: type }, + { crypto: 'linuxapi', proxy: query.proxy, realIP: query.realIP }, + ); +}; diff --git a/napi/module/batch.js b/napi/module/batch.js new file mode 100644 index 0000000..dd2e88e --- /dev/null +++ b/napi/module/batch.js @@ -0,0 +1,19 @@ +// 批量请求接口 + +module.exports = (query, request) => { + const data = { + e_r: true, + }; + Object.keys(query).forEach((i) => { + if (/^\/api\//.test(i)) { + data[i] = query[i]; + } + }); + return request('POST', `https://music.163.com/eapi/batch`, data, { + crypto: 'eapi', + proxy: query.proxy, + url: '/api/batch', + cookie: query.cookie, + realIP: query.realIP, + }); +}; diff --git a/napi/module/calendar.js b/napi/module/calendar.js new file mode 100644 index 0000000..2abff77 --- /dev/null +++ b/napi/module/calendar.js @@ -0,0 +1,12 @@ +module.exports = (query, request) => { + const data = { + startTime: query.startTime || Date.now(), + endTime: query.endTime || Date.now(), + }; + return request('POST', `https://music.163.com/api/mcalendar/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/captcha_sent.js b/napi/module/captcha_sent.js new file mode 100644 index 0000000..6cae966 --- /dev/null +++ b/napi/module/captcha_sent.js @@ -0,0 +1,14 @@ +// 发送验证码 + +module.exports = (query, request) => { + const data = { + ctcode: query.ctcode || '86', + cellphone: query.phone, + }; + return request('POST', `https://music.163.com/weapi/sms/captcha/sent`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/captcha_verify.js b/napi/module/captcha_verify.js new file mode 100644 index 0000000..f0edf1c --- /dev/null +++ b/napi/module/captcha_verify.js @@ -0,0 +1,20 @@ +// 校验验证码 + +module.exports = (query, request) => { + const data = { + ctcode: query.ctcode || '86', + cellphone: query.phone, + captcha: query.captcha, + }; + return request( + 'POST', + `https://music.163.com/weapi/sms/captcha/verify`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/cellphone_existence_check.js b/napi/module/cellphone_existence_check.js new file mode 100644 index 0000000..bb28316 --- /dev/null +++ b/napi/module/cellphone_existence_check.js @@ -0,0 +1,20 @@ +// 检测手机号码是否已注册 + +module.exports = (query, request) => { + const data = { + cellphone: query.phone, + countrycode: query.countrycode, + }; + return request( + 'POST', + `https://music.163.com/eapi/cellphone/existence/check`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/cellphone/existence/check', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/check_music.js b/napi/module/check_music.js new file mode 100644 index 0000000..6aed6fd --- /dev/null +++ b/napi/module/check_music.js @@ -0,0 +1,34 @@ +// 歌曲可用性 + +module.exports = (query, request) => { + const data = { + ids: '[' + parseInt(query.id) + ']', + br: parseInt(query.br || 999000), + }; + return request( + 'POST', + `https://music.163.com/weapi/song/enhance/player/url`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ).then((response) => { + let playable = false; + if (response.body.code == 200) { + if (response.body.data[0].code == 200) { + playable = true; + } + } + if (playable) { + response.body = { success: true, message: 'ok' }; + return response; + } else { + response.status = 404; + response.body = { success: false, message: '亲爱的,暂无版权' }; + return Promise.reject(response); + } + }); +}; diff --git a/napi/module/cloudsearch.js b/napi/module/cloudsearch.js new file mode 100644 index 0000000..f7bd53e --- /dev/null +++ b/napi/module/cloudsearch.js @@ -0,0 +1,21 @@ +// 搜索 + +module.exports = (query, request) => { + const data = { + s: query.keywords, + type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudsearch/get/web`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment.js b/napi/module/comment.js new file mode 100644 index 0000000..c3e0bab --- /dev/null +++ b/napi/module/comment.js @@ -0,0 +1,43 @@ +// 发送与删除评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.t = { + 1: 'add', + 0: 'delete', + 2: 'reply', + }[query.t]; + query.type = { + 0: 'R_SO_4_', // 歌曲 + 1: 'R_MV_5_', // MV + 2: 'A_PL_0_', // 歌单 + 3: 'R_AL_3_', // 专辑 + 4: 'A_DJ_1_', // 电台, + 5: 'R_VI_62_', // 视频 + 6: 'A_EV_2_', // 动态 + }[query.type]; + const data = { + threadId: query.type + query.id, + }; + + if (query.type == 'A_EV_2_') { + data.threadId = query.threadId; + } + if (query.t == 'add') data.content = query.content; + else if (query.t == 'delete') data.commentId = query.commentId; + else if (query.t == 'reply') { + data.commentId = query.commentId; + data.content = query.content; + } + return request( + 'POST', + `https://music.163.com/weapi/resource/comments/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_album.js b/napi/module/comment_album.js new file mode 100644 index 0000000..f873655 --- /dev/null +++ b/napi/module/comment_album.js @@ -0,0 +1,22 @@ +// 专辑评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_AL_3_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_dj.js b/napi/module/comment_dj.js new file mode 100644 index 0000000..27d32d1 --- /dev/null +++ b/napi/module/comment_dj.js @@ -0,0 +1,22 @@ +// 电台评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_event.js b/napi/module/comment_event.js new file mode 100644 index 0000000..cf89ade --- /dev/null +++ b/napi/module/comment_event.js @@ -0,0 +1,20 @@ +// 获取动态评论 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/${query.threadId}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_floor.js b/napi/module/comment_floor.js new file mode 100644 index 0000000..818584b --- /dev/null +++ b/napi/module/comment_floor.js @@ -0,0 +1,27 @@ +module.exports = (query, request) => { + query.type = { + 0: 'R_SO_4_', // 歌曲 + 1: 'R_MV_5_', // MV + 2: 'A_PL_0_', // 歌单 + 3: 'R_AL_3_', // 专辑 + 4: 'A_DJ_1_', // 电台, + 5: 'R_VI_62_', // 视频 + }[query.type]; + const data = { + parentCommentId: query.parentCommentId, + threadId: query.type + query.id, + time: query.time || -1, + limit: query.limit || 20, + }; + return request( + 'POST', + `https://music.163.com/api/resource/comment/floor/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_hot.js b/napi/module/comment_hot.js new file mode 100644 index 0000000..749e318 --- /dev/null +++ b/napi/module/comment_hot.js @@ -0,0 +1,30 @@ +// 热门评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.type = { + 0: 'R_SO_4_', // 歌曲 + 1: 'R_MV_5_', // MV + 2: 'A_PL_0_', // 歌单 + 3: 'R_AL_3_', // 专辑 + 4: 'A_DJ_1_', // 电台, + 5: 'R_VI_62_', // 视频 + }[query.type]; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/hotcomments/${query.type}${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_hotwall_list.js b/napi/module/comment_hotwall_list.js new file mode 100644 index 0000000..0b7e67a --- /dev/null +++ b/napi/module/comment_hotwall_list.js @@ -0,0 +1,16 @@ +// 云村热评 + +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/comment/hotwall/list/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_like.js b/napi/module/comment_like.js new file mode 100644 index 0000000..e2cfca7 --- /dev/null +++ b/napi/module/comment_like.js @@ -0,0 +1,33 @@ +// 点赞与取消点赞评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.t = query.t == 1 ? 'like' : 'unlike'; + query.type = { + 0: 'R_SO_4_', // 歌曲 + 1: 'R_MV_5_', // MV + 2: 'A_PL_0_', // 歌单 + 3: 'R_AL_3_', // 专辑 + 4: 'A_DJ_1_', // 电台, + 5: 'R_VI_62_', // 视频 + 6: 'A_EV_2_', // 动态 + }[query.type]; + const data = { + threadId: query.type + query.id, + commentId: query.cid, + }; + if (query.type == 'A_EV_2_') { + data.threadId = query.threadId; + } + return request( + 'POST', + `https://music.163.com/weapi/v1/comment/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_music.js b/napi/module/comment_music.js new file mode 100644 index 0000000..9824605 --- /dev/null +++ b/napi/module/comment_music.js @@ -0,0 +1,22 @@ +// 歌曲评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/api/v1/resource/comments/R_SO_4_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_mv.js b/napi/module/comment_mv.js new file mode 100644 index 0000000..3ce3ba9 --- /dev/null +++ b/napi/module/comment_mv.js @@ -0,0 +1,22 @@ +// MV评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_MV_5_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_new.js b/napi/module/comment_new.js new file mode 100644 index 0000000..97f51dc --- /dev/null +++ b/napi/module/comment_new.js @@ -0,0 +1,38 @@ +// 评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.type = { + 0: 'R_SO_4_', // 歌曲 + 1: 'R_MV_5_', // MV + 2: 'A_PL_0_', // 歌单 + 3: 'R_AL_3_', // 专辑 + 4: 'A_DJ_1_', // 电台, + 5: 'R_VI_62_', // 视频 + 6: 'A_EV_2_', // 动态 + }[query.type]; + const threadId = query.type + query.id; + const pageSize = query.pageSize || 20; + const pageNo = query.pageNo || 1; + const data = { + threadId: threadId, //'R_SO_4_863481066', + pageNo, + showInner: query.showInner || true, + pageSize, + cursor: + +query.sortType === 3 ? query.cursor || '0' : (pageNo - 1) * pageSize, + sortType: query.sortType || 1, //1:按推荐排序,2:按热度排序,3:按时间排序 + }; + return request( + 'POST', + `https://music.163.com/api/v2/resource/comments`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/v2/resource/comments', + }, + ); +}; diff --git a/napi/module/comment_playlist.js b/napi/module/comment_playlist.js new file mode 100644 index 0000000..37b2465 --- /dev/null +++ b/napi/module/comment_playlist.js @@ -0,0 +1,22 @@ +// 歌单评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/A_PL_0_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/comment_video.js b/napi/module/comment_video.js new file mode 100644 index 0000000..af9def1 --- /dev/null +++ b/napi/module/comment_video.js @@ -0,0 +1,22 @@ +// 视频评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_VI_62_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/countries_code_list.js b/napi/module/countries_code_list.js new file mode 100644 index 0000000..fefe732 --- /dev/null +++ b/napi/module/countries_code_list.js @@ -0,0 +1,16 @@ +// 国家编码列表 +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://interface3.music.163.com/eapi/lbs/countries/v1`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/lbs/countries/v1', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/daily_signin.js b/napi/module/daily_signin.js new file mode 100644 index 0000000..4c0d404 --- /dev/null +++ b/napi/module/daily_signin.js @@ -0,0 +1,20 @@ +// 签到 + +/* + 0为安卓端签到 3点经验, 1为网页签到,2点经验 + 签到成功 {'android': {'point': 3, 'code': 200}, 'web': {'point': 2, 'code': 200}} + 重复签到 {'android': {'code': -2, 'msg': '重复签到'}, 'web': {'code': -2, 'msg': '重复签到'}} + 未登录 {'android': {'code': 301}, 'web': {'code': 301}} +*/ + +module.exports = (query, request) => { + const data = { + type: query.type || 0, + }; + return request('POST', `https://music.163.com/weapi/point/dailyTask`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/digitalAlbum_ordering.js b/napi/module/digitalAlbum_ordering.js new file mode 100644 index 0000000..9c23a9c --- /dev/null +++ b/napi/module/digitalAlbum_ordering.js @@ -0,0 +1,27 @@ +// 购买数字专辑 + +module.exports = (query, request) => { + const data = { + business: 'Album', + paymentMethod: query.payment, + digitalResources: JSON.stringify([ + { + business: 'Album', + resourceID: query.id, + quantity: query.quantity, + }, + ]), + from: 'web', + }; + return request( + 'POST', + `https://music.163.com/api/ordering/web/digital`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/digitalAlbum_purchased.js b/napi/module/digitalAlbum_purchased.js new file mode 100644 index 0000000..ad4b43f --- /dev/null +++ b/napi/module/digitalAlbum_purchased.js @@ -0,0 +1,20 @@ +// 我的数字专辑 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/digitalAlbum/purchased`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_banner.js b/napi/module/dj_banner.js new file mode 100644 index 0000000..8bb4ffc --- /dev/null +++ b/napi/module/dj_banner.js @@ -0,0 +1,17 @@ +// 电台banner + +module.exports = (query, request) => { + const data = {}; + query.cookie.os = 'pc'; + return request( + 'POST', + `https://music.163.com/weapi/djradio/banner/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_category_excludehot.js b/napi/module/dj_category_excludehot.js new file mode 100644 index 0000000..339b727 --- /dev/null +++ b/napi/module/dj_category_excludehot.js @@ -0,0 +1,15 @@ +// 电台非热门类型 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/category/excludehot`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_category_recommend.js b/napi/module/dj_category_recommend.js new file mode 100644 index 0000000..6461e67 --- /dev/null +++ b/napi/module/dj_category_recommend.js @@ -0,0 +1,15 @@ +// 电台推荐类型 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/category/recommend`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_catelist.js b/napi/module/dj_catelist.js new file mode 100644 index 0000000..3ea33ec --- /dev/null +++ b/napi/module/dj_catelist.js @@ -0,0 +1,15 @@ +// 电台分类列表 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/category/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_detail.js b/napi/module/dj_detail.js new file mode 100644 index 0000000..de4c9f2 --- /dev/null +++ b/napi/module/dj_detail.js @@ -0,0 +1,13 @@ +// 电台详情 + +module.exports = (query, request) => { + const data = { + id: query.rid, + }; + return request('POST', `https://music.163.com/api/djradio/v2/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_hot.js b/napi/module/dj_hot.js new file mode 100644 index 0000000..74474d6 --- /dev/null +++ b/napi/module/dj_hot.js @@ -0,0 +1,14 @@ +// 热门电台 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/weapi/djradio/hot/v1`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_paygift.js b/napi/module/dj_paygift.js new file mode 100644 index 0000000..19d0f89 --- /dev/null +++ b/napi/module/dj_paygift.js @@ -0,0 +1,19 @@ +// 付费电台 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/paygift/list?_nmclfl=1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_personalize_recommend.js b/napi/module/dj_personalize_recommend.js new file mode 100644 index 0000000..2ddd0a9 --- /dev/null +++ b/napi/module/dj_personalize_recommend.js @@ -0,0 +1,17 @@ +// 电台个性推荐 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/djradio/personalize/rcmd`, + { + limit: query.limit || 6, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_program.js b/napi/module/dj_program.js new file mode 100644 index 0000000..961ef03 --- /dev/null +++ b/napi/module/dj_program.js @@ -0,0 +1,21 @@ +// 电台节目列表 +const { toBoolean } = require('../util'); +module.exports = (query, request) => { + const data = { + radioId: query.rid, + limit: query.limit || 30, + offset: query.offset || 0, + asc: toBoolean(query.asc), + }; + return request( + 'POST', + `https://music.163.com/weapi/dj/program/byradio`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_program_detail.js b/napi/module/dj_program_detail.js new file mode 100644 index 0000000..395160a --- /dev/null +++ b/napi/module/dj_program_detail.js @@ -0,0 +1,13 @@ +// 电台节目详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + }; + return request('POST', `https://music.163.com/api/dj/program/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_program_toplist.js b/napi/module/dj_program_toplist.js new file mode 100644 index 0000000..60c2b8f --- /dev/null +++ b/napi/module/dj_program_toplist.js @@ -0,0 +1,14 @@ +// 电台节目榜 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/api/program/toplist/v1`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_program_toplist_hours.js b/napi/module/dj_program_toplist_hours.js new file mode 100644 index 0000000..72cf980 --- /dev/null +++ b/napi/module/dj_program_toplist_hours.js @@ -0,0 +1,18 @@ +// 电台24小时节目榜 +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + }; + return request( + 'POST', + `https://music.163.com/api/djprogram/toplist/hours`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_radio_hot.js b/napi/module/dj_radio_hot.js new file mode 100644 index 0000000..6533b35 --- /dev/null +++ b/napi/module/dj_radio_hot.js @@ -0,0 +1,15 @@ +// 类别热门电台 + +module.exports = (query, request) => { + const data = { + cateId: query.cateId, + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/api/djradio/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_recommend.js b/napi/module/dj_recommend.js new file mode 100644 index 0000000..9c530a2 --- /dev/null +++ b/napi/module/dj_recommend.js @@ -0,0 +1,15 @@ +// 精选电台 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/recommend/v1`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_recommend_type.js b/napi/module/dj_recommend_type.js new file mode 100644 index 0000000..b864404 --- /dev/null +++ b/napi/module/dj_recommend_type.js @@ -0,0 +1,41 @@ +// 精选电台分类 + +/* + 有声书 10001 + 知识技能 453050 + 商业财经 453051 + 人文历史 11 + 外语世界 13 + 亲子宝贝 14 + 创作|翻唱 2001 + 音乐故事 2 + 3D|电子 10002 + 相声曲艺 8 + 情感调频 3 + 美文读物 6 + 脱口秀 5 + 广播剧 7 + 二次元 3001 + 明星做主播 1 + 娱乐|影视 4 + 科技科学 453052 + 校园|教育 4001 + 旅途|城市 12 +*/ + +module.exports = (query, request) => { + const data = { + cateId: query.type, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/recommend`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_sub.js b/napi/module/dj_sub.js new file mode 100644 index 0000000..5375514 --- /dev/null +++ b/napi/module/dj_sub.js @@ -0,0 +1,19 @@ +// 订阅与取消电台 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { + id: query.rid, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_sublist.js b/napi/module/dj_sublist.js new file mode 100644 index 0000000..b3a90e1 --- /dev/null +++ b/napi/module/dj_sublist.js @@ -0,0 +1,20 @@ +// 订阅电台列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/get/subed`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_subscriber.js b/napi/module/dj_subscriber.js new file mode 100644 index 0000000..129df40 --- /dev/null +++ b/napi/module/dj_subscriber.js @@ -0,0 +1,16 @@ +// 电台详情 + +module.exports = (query, request) => { + const data = { + time: query.time || '-1', + id: query.id, + limit: query.limit || '20', + total: 'true', + }; + return request('POST', `https://music.163.com/api/djradio/subscriber`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_today_perfered.js b/napi/module/dj_today_perfered.js new file mode 100644 index 0000000..0f50c69 --- /dev/null +++ b/napi/module/dj_today_perfered.js @@ -0,0 +1,18 @@ +// 电台今日优选 + +module.exports = (query, request) => { + const data = { + page: query.page || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/today/perfered`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_toplist.js b/napi/module/dj_toplist.js new file mode 100644 index 0000000..36249da --- /dev/null +++ b/napi/module/dj_toplist.js @@ -0,0 +1,18 @@ +// 新晋电台榜/热门电台榜 +const typeMap = { + new: 0, + hot: 1, +}; +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + type: typeMap[query.type || 'new'] || '0', //0为新晋,1为热门 + }; + return request('POST', `https://music.163.com/api/djradio/toplist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_toplist_hours.js b/napi/module/dj_toplist_hours.js new file mode 100644 index 0000000..193396d --- /dev/null +++ b/napi/module/dj_toplist_hours.js @@ -0,0 +1,14 @@ +// 电台24小时主播榜 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + }; + return request('POST', `https://music.163.com/api/dj/toplist/hours`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/dj_toplist_newcomer.js b/napi/module/dj_toplist_newcomer.js new file mode 100644 index 0000000..1a0ad48 --- /dev/null +++ b/napi/module/dj_toplist_newcomer.js @@ -0,0 +1,18 @@ +// 电台新人榜 +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/api/dj/toplist/newcomer`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_toplist_pay.js b/napi/module/dj_toplist_pay.js new file mode 100644 index 0000000..2b260ff --- /dev/null +++ b/napi/module/dj_toplist_pay.js @@ -0,0 +1,18 @@ +// 付费精品 +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + }; + return request( + 'POST', + `https://music.163.com/api/djradio/toplist/pay`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/dj_toplist_popular.js b/napi/module/dj_toplist_popular.js new file mode 100644 index 0000000..bb1fbe0 --- /dev/null +++ b/napi/module/dj_toplist_popular.js @@ -0,0 +1,14 @@ +// 电台最热主播榜 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + }; + return request('POST', `https://music.163.com/api/dj/toplist/popular`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/event.js b/napi/module/event.js new file mode 100644 index 0000000..2c32bc1 --- /dev/null +++ b/napi/module/event.js @@ -0,0 +1,14 @@ +// 动态 + +module.exports = (query, request) => { + const data = { + pagesize: query.pagesize || 20, + lasttime: query.lasttime || -1, + }; + return request('POST', `https://music.163.com/weapi/v1/event/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/event_del.js b/napi/module/event_del.js new file mode 100644 index 0000000..c5b245f --- /dev/null +++ b/napi/module/event_del.js @@ -0,0 +1,13 @@ +// 删除动态 + +module.exports = (query, request) => { + const data = { + id: query.evId, + }; + return request('POST', `https://music.163.com/eapi/event/delete`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/event_forward.js b/napi/module/event_forward.js new file mode 100644 index 0000000..77738b2 --- /dev/null +++ b/napi/module/event_forward.js @@ -0,0 +1,16 @@ +// 转发动态 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + forwards: query.forwards, + id: query.evId, + eventUserId: query.uid, + }; + return request('POST', `https://music.163.com/weapi/event/forward`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/fm_trash.js b/napi/module/fm_trash.js new file mode 100644 index 0000000..eabd938 --- /dev/null +++ b/napi/module/fm_trash.js @@ -0,0 +1,20 @@ +// 垃圾桶 + +module.exports = (query, request) => { + const data = { + songId: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/radio/trash/add?alg=RT&songId=${ + query.id + }&time=${query.time || 25}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/follow.js b/napi/module/follow.js new file mode 100644 index 0000000..293bd8a --- /dev/null +++ b/napi/module/follow.js @@ -0,0 +1,17 @@ +// 关注与取消关注用户 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.t = query.t == 1 ? 'follow' : 'delfollow'; + return request( + 'POST', + `https://music.163.com/weapi/user/${query.t}/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/history_recommend_songs.js b/napi/module/history_recommend_songs.js new file mode 100644 index 0000000..89cb904 --- /dev/null +++ b/napi/module/history_recommend_songs.js @@ -0,0 +1,17 @@ +// 历史每日推荐歌曲 + +module.exports = (query, request) => { + query.cookie.os = 'ios'; + const data = {}; + return request( + 'POST', + `https://music.163.com/api/discovery/recommend/songs/history/recent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/history_recommend_songs_detail.js b/napi/module/history_recommend_songs_detail.js new file mode 100644 index 0000000..c981b28 --- /dev/null +++ b/napi/module/history_recommend_songs_detail.js @@ -0,0 +1,19 @@ +// 历史每日推荐歌曲详情 + +module.exports = (query, request) => { + query.cookie.os = 'ios'; + const data = { + date: query.date || '', + }; + return request( + 'POST', + `https://music.163.com/api/discovery/recommend/songs/history/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/homepage_block_page.js b/napi/module/homepage_block_page.js new file mode 100644 index 0000000..2f49d75 --- /dev/null +++ b/napi/module/homepage_block_page.js @@ -0,0 +1,17 @@ +// 首页-发现 block page +// 这个接口为移动端接口,首页-发现页,数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L259 HomeBlockPageWrap +// query.refresh 是否刷新数据 +module.exports = (query, request) => { + const data = { refresh: query.refresh || true }; + return request( + 'POST', + `https://music.163.com/api/homepage/block/page`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/homepage_dragon_ball.js b/napi/module/homepage_dragon_ball.js new file mode 100644 index 0000000..e048ac1 --- /dev/null +++ b/napi/module/homepage_dragon_ball.js @@ -0,0 +1,19 @@ +// 首页-发现 dragon ball +// 这个接口为移动端接口,首页-发现页(每日推荐、歌单、排行榜 那些入口) +// 数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L290 HomeDragonBallWrap +// !需要登录或者匿名登录,非登录返回 [] +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/eapi/homepage/dragon/ball/static`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/homepage/dragon/ball/static', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/hot_topic.js b/napi/module/hot_topic.js new file mode 100644 index 0000000..1fdbac1 --- /dev/null +++ b/napi/module/hot_topic.js @@ -0,0 +1,14 @@ +//热门话题 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/weapi/act/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/like.js b/napi/module/like.js new file mode 100644 index 0000000..7fd3e8f --- /dev/null +++ b/napi/module/like.js @@ -0,0 +1,23 @@ +// 红心与取消红心歌曲 +const { toBoolean } = require('../util'); + +module.exports = (query, request) => { + query.like = query.like == 'false' ? false : true; + const data = { + trackId: query.id, + like: query.like, + }; + return request( + 'POST', + `https://music.163.com/weapi/radio/like?alg=${ + query.alg || 'itembased' + }&trackId=${query.id}&time=${query.time || 25}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/likelist.js b/napi/module/likelist.js new file mode 100644 index 0000000..fcffede --- /dev/null +++ b/napi/module/likelist.js @@ -0,0 +1,13 @@ +// 喜欢的歌曲(无序) + +module.exports = (query, request) => { + const data = { + uid: query.uid, + }; + return request('POST', `https://music.163.com/weapi/song/like/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/login.js b/napi/module/login.js new file mode 100644 index 0000000..72c9966 --- /dev/null +++ b/napi/module/login.js @@ -0,0 +1,47 @@ +// 邮箱登录 + +const crypto = require('crypto'); + +module.exports = async (query, request) => { + query.cookie.os = 'pc'; + const data = { + username: query.email, + password: + query.md5_password || + crypto.createHash('md5').update(query.password).digest('hex'), + rememberLogin: 'true', + }; + let result = await request( + 'POST', + `https://music.163.com/weapi/login`, + data, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + if (result.body.code === 502) { + return { + status: 200, + body: { + msg: '账号或密码错误', + code: 502, + message: '账号或密码错误', + }, + }; + } + if (result.body.code === 200) { + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + }; + } + return result; +}; diff --git a/napi/module/login_cellphone.js b/napi/module/login_cellphone.js new file mode 100644 index 0000000..7f4398c --- /dev/null +++ b/napi/module/login_cellphone.js @@ -0,0 +1,39 @@ +// 手机登录 + +const crypto = require('crypto'); + +module.exports = async (query, request) => { + query.cookie.os = 'pc'; + const data = { + phone: query.phone, + countrycode: query.countrycode || '86', + password: + query.md5_password || + crypto.createHash('md5').update(query.password).digest('hex'), + rememberLogin: 'true', + }; + let result = await request( + 'POST', + `https://music.163.com/weapi/login/cellphone`, + data, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + + if (result.body.code === 200) { + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + }; + } + return result; +}; diff --git a/napi/module/login_refresh.js b/napi/module/login_refresh.js new file mode 100644 index 0000000..5a57ed4 --- /dev/null +++ b/napi/module/login_refresh.js @@ -0,0 +1,16 @@ +// 登录刷新 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/login/token/refresh`, + {}, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/login_status.js b/napi/module/login_status.js new file mode 100644 index 0000000..9a06d68 --- /dev/null +++ b/napi/module/login_status.js @@ -0,0 +1,23 @@ +// 登录状态 + +module.exports = (query, request) => { + return request( + 'GET', + `https://music.163.com`, + {}, + { cookie: query.cookie, proxy: query.proxy, realIP: query.realIP }, + ).then((response) => { + try { + let profile = eval(`(${/GUser\s*=\s*([^;]+);/.exec(response.body)[1]})`); + let bindings = eval( + `(${/GBinds\s*=\s*([^;]+);/.exec(response.body)[1]})`, + ); + response.body = { code: 200, profile: profile, bindings: bindings }; + return response; + } catch (err) { + response.status = 301; + response.body = { code: 301 }; + return Promise.reject(response); + } + }); +}; diff --git a/napi/module/logout.js b/napi/module/logout.js new file mode 100644 index 0000000..2eb97cd --- /dev/null +++ b/napi/module/logout.js @@ -0,0 +1,16 @@ +// 退出登录 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/logout`, + {}, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/lyric.js b/napi/module/lyric.js new file mode 100644 index 0000000..c217c13 --- /dev/null +++ b/napi/module/lyric.js @@ -0,0 +1,17 @@ +// 歌词 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + id: query.id, + lv: -1, + kv: -1, + tv: -1, + }; + return request('POST', `https://music.163.com/api/song/lyric`, data, { + crypto: 'linuxapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/msg_comments.js b/napi/module/msg_comments.js new file mode 100644 index 0000000..a200eae --- /dev/null +++ b/napi/module/msg_comments.js @@ -0,0 +1,22 @@ +// 评论 + +module.exports = (query, request) => { + const data = { + beforeTime: query.before || '-1', + limit: query.limit || 30, + total: 'true', + uid: query.uid, + }; + + return request( + 'POST', + `https://music.163.com/api/v1/user/comments/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/msg_forwards.js b/napi/module/msg_forwards.js new file mode 100644 index 0000000..7b540e9 --- /dev/null +++ b/napi/module/msg_forwards.js @@ -0,0 +1,15 @@ +// @我 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + total: 'true', + }; + return request('POST', `https://music.163.com/api/forwards/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/msg_notices.js b/napi/module/msg_notices.js new file mode 100644 index 0000000..dbb82f8 --- /dev/null +++ b/napi/module/msg_notices.js @@ -0,0 +1,14 @@ +// 通知 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + time: query.lasttime || -1, + }; + return request('POST', `https://music.163.com/api/msg/notices`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/msg_private.js b/napi/module/msg_private.js new file mode 100644 index 0000000..777356c --- /dev/null +++ b/napi/module/msg_private.js @@ -0,0 +1,15 @@ +// 私信 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + total: 'true', + }; + return request('POST', `https://music.163.com/api/msg/private/users`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/msg_private_history.js b/napi/module/msg_private_history.js new file mode 100644 index 0000000..c5e8421 --- /dev/null +++ b/napi/module/msg_private_history.js @@ -0,0 +1,21 @@ +// 私信内容 + +module.exports = (query, request) => { + const data = { + userId: query.uid, + limit: query.limit || 30, + time: query.before || 0, + total: 'true', + }; + return request( + 'POST', + `https://music.163.com/api/msg/private/history`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/mv_all.js b/napi/module/mv_all.js new file mode 100644 index 0000000..93ab80c --- /dev/null +++ b/napi/module/mv_all.js @@ -0,0 +1,20 @@ +// 全部MV + +module.exports = (query, request) => { + const data = { + tags: JSON.stringify({ + 地区: query.area || '全部', + 类型: query.type || '全部', + 排序: query.order || '上升最快', + }), + offset: query.offset || 0, + total: 'true', + limit: query.limit || 30, + }; + return request('POST', `https://interface.music.163.com/api/mv/all`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/mv_detail.js b/napi/module/mv_detail.js new file mode 100644 index 0000000..f5c890c --- /dev/null +++ b/napi/module/mv_detail.js @@ -0,0 +1,13 @@ +// MV详情 + +module.exports = (query, request) => { + const data = { + id: query.mvid, + }; + return request('POST', `https://music.163.com/api/v1/mv/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/mv_detail_info.js b/napi/module/mv_detail_info.js new file mode 100644 index 0000000..5e9ee75 --- /dev/null +++ b/napi/module/mv_detail_info.js @@ -0,0 +1,19 @@ +// MV 点赞转发评论数数据 + +module.exports = (query, request) => { + const data = { + threadid: `R_MV_5_${query.mvid}`, + composeliked: true, + }; + return request( + 'POST', + `https://music.163.com/api/comment/commentthread/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/mv_exclusive_rcmd.js b/napi/module/mv_exclusive_rcmd.js new file mode 100644 index 0000000..8856357 --- /dev/null +++ b/napi/module/mv_exclusive_rcmd.js @@ -0,0 +1,19 @@ +// 网易出品 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + }; + return request( + 'POST', + `https://interface.music.163.com/api/mv/exclusive/rcmd`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/mv_first.js b/napi/module/mv_first.js new file mode 100644 index 0000000..554569d --- /dev/null +++ b/napi/module/mv_first.js @@ -0,0 +1,21 @@ +// 最新MV + +module.exports = (query, request) => { + const data = { + // 'offset': query.offset || 0, + area: query.area || '', + limit: query.limit || 30, + total: true, + }; + return request( + 'POST', + `https://interface.music.163.com/weapi/mv/first`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/mv_sub.js b/napi/module/mv_sub.js new file mode 100644 index 0000000..de9459d --- /dev/null +++ b/napi/module/mv_sub.js @@ -0,0 +1,15 @@ +// 收藏与取消收藏MV + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { + mvId: query.mvid, + mvIds: '["' + query.mvid + '"]', + }; + return request('POST', `https://music.163.com/weapi/mv/${query.t}`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/mv_sublist.js b/napi/module/mv_sublist.js new file mode 100644 index 0000000..0da033c --- /dev/null +++ b/napi/module/mv_sublist.js @@ -0,0 +1,20 @@ +// 已收藏MV列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/allvideo/sublist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/mv_url.js b/napi/module/mv_url.js new file mode 100644 index 0000000..cd5e91a --- /dev/null +++ b/napi/module/mv_url.js @@ -0,0 +1,19 @@ +// MV链接 + +module.exports = (query, request) => { + const data = { + id: query.id, + r: query.r || 1080, + }; + return request( + 'POST', + `https://music.163.com/weapi/song/enhance/play/mv/url`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personal_fm.js b/napi/module/personal_fm.js new file mode 100644 index 0000000..8197694 --- /dev/null +++ b/napi/module/personal_fm.js @@ -0,0 +1,15 @@ +// 私人FM + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/radio/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personalized.js b/napi/module/personalized.js new file mode 100644 index 0000000..45c1639 --- /dev/null +++ b/napi/module/personalized.js @@ -0,0 +1,21 @@ +// 推荐歌单 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + // offset: query.offset || 0, + total: true, + n: 1000, + }; + return request( + 'POST', + `https://music.163.com/weapi/personalized/playlist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personalized_djprogram.js b/napi/module/personalized_djprogram.js new file mode 100644 index 0000000..232fa78 --- /dev/null +++ b/napi/module/personalized_djprogram.js @@ -0,0 +1,15 @@ +// 推荐电台 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/djprogram`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personalized_mv.js b/napi/module/personalized_mv.js new file mode 100644 index 0000000..1d0e4e6 --- /dev/null +++ b/napi/module/personalized_mv.js @@ -0,0 +1,15 @@ +// 推荐MV + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/mv`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personalized_newsong.js b/napi/module/personalized_newsong.js new file mode 100644 index 0000000..de275a9 --- /dev/null +++ b/napi/module/personalized_newsong.js @@ -0,0 +1,20 @@ +// 推荐新歌 + +module.exports = (query, request) => { + const data = { + type: 'recommend', + limit: query.limit || 10, + areaId: query.areaId || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/personalized/newsong`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personalized_privatecontent.js b/napi/module/personalized_privatecontent.js new file mode 100644 index 0000000..ac2c228 --- /dev/null +++ b/napi/module/personalized_privatecontent.js @@ -0,0 +1,15 @@ +// 独家放送 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/privatecontent`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/personalized_privatecontent_list.js b/napi/module/personalized_privatecontent_list.js new file mode 100644 index 0000000..d98f409 --- /dev/null +++ b/napi/module/personalized_privatecontent_list.js @@ -0,0 +1,20 @@ +// 独家放送列表 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + total: 'true', + limit: query.limit || 60, + }; + return request( + 'POST', + `https://music.163.com/api/v2/privatecontent/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_catlist.js b/napi/module/playlist_catlist.js new file mode 100644 index 0000000..def3039 --- /dev/null +++ b/napi/module/playlist_catlist.js @@ -0,0 +1,15 @@ +// 全部歌单分类 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/playlist/catalogue`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_cover_update.js b/napi/module/playlist_cover_update.js new file mode 100644 index 0000000..4e2d412 --- /dev/null +++ b/napi/module/playlist_cover_update.js @@ -0,0 +1,28 @@ +const uploadPlugin = require('../plugins/upload'); +module.exports = async (query, request) => { + const uploadInfo = await uploadPlugin(query, request); + const res = await request( + 'POST', + `https://music.163.com/weapi/playlist/cover/update`, + { + id: query.id, + coverImgId: uploadInfo.imgId, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + return { + status: 200, + body: { + code: 200, + data: { + ...uploadInfo, + ...res.body, + }, + }, + }; +}; diff --git a/napi/module/playlist_create.js b/napi/module/playlist_create.js new file mode 100644 index 0000000..42f3e82 --- /dev/null +++ b/napi/module/playlist_create.js @@ -0,0 +1,16 @@ +// 创建歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + name: query.name, + privacy: query.privacy, //0 为普通歌单,10 为隐私歌单 + type: query.type || 'NORMAL', // NORMAL|VIDEO + }; + return request('POST', `https://music.163.com/api/playlist/create`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/playlist_delete.js b/napi/module/playlist_delete.js new file mode 100644 index 0000000..2fe9327 --- /dev/null +++ b/napi/module/playlist_delete.js @@ -0,0 +1,14 @@ +// 删除歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + ids: '[' + query.id + ']', + }; + return request('POST', `https://music.163.com/weapi/playlist/remove`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/playlist_desc_update.js b/napi/module/playlist_desc_update.js new file mode 100644 index 0000000..55fada2 --- /dev/null +++ b/napi/module/playlist_desc_update.js @@ -0,0 +1,20 @@ +// 更新歌单描述 + +module.exports = (query, request) => { + const data = { + id: query.id, + desc: query.desc, + }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/desc/update`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/desc/update', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_detail.js b/napi/module/playlist_detail.js new file mode 100644 index 0000000..ccd09b1 --- /dev/null +++ b/napi/module/playlist_detail.js @@ -0,0 +1,15 @@ +// 歌单详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + n: 100000, + s: query.s || 8, + }; + return request('POST', `https://music.163.com/api/v6/playlist/detail`, data, { + crypto: 'linuxapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/playlist_highquality_tags.js b/napi/module/playlist_highquality_tags.js new file mode 100644 index 0000000..d6be7c7 --- /dev/null +++ b/napi/module/playlist_highquality_tags.js @@ -0,0 +1,15 @@ +// 精品歌单 tags +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/playlist/highquality/tags`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_hot.js b/napi/module/playlist_hot.js new file mode 100644 index 0000000..fd588f6 --- /dev/null +++ b/napi/module/playlist_hot.js @@ -0,0 +1,15 @@ +// 热门歌单分类 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/playlist/hottags`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_mylike.js b/napi/module/playlist_mylike.js new file mode 100644 index 0000000..b96d034 --- /dev/null +++ b/napi/module/playlist_mylike.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + time: query.time || '-1', + limit: query.limit || '12', + }; + return request( + 'POST', + `https://music.163.com/api/mlog/playlist/mylike/bytime/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_name_update.js b/napi/module/playlist_name_update.js new file mode 100644 index 0000000..5f4dfbd --- /dev/null +++ b/napi/module/playlist_name_update.js @@ -0,0 +1,20 @@ +// 更新歌单名 + +module.exports = (query, request) => { + const data = { + id: query.id, + name: query.name, + }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/update/name`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/update/name', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_order_update.js b/napi/module/playlist_order_update.js new file mode 100644 index 0000000..570cd13 --- /dev/null +++ b/napi/module/playlist_order_update.js @@ -0,0 +1,19 @@ +// 编辑歌单顺序 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + ids: query.ids, + }; + return request( + 'POST', + `https://music.163.com/api/playlist/order/update`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_subscribe.js b/napi/module/playlist_subscribe.js new file mode 100644 index 0000000..31d56e9 --- /dev/null +++ b/napi/module/playlist_subscribe.js @@ -0,0 +1,19 @@ +// 收藏与取消收藏歌单 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'subscribe' : 'unsubscribe'; + const data = { + id: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/playlist/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_subscribers.js b/napi/module/playlist_subscribers.js new file mode 100644 index 0000000..0fa2764 --- /dev/null +++ b/napi/module/playlist_subscribers.js @@ -0,0 +1,20 @@ +// 歌单收藏者 + +module.exports = (query, request) => { + const data = { + id: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/playlist/subscribers`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_tags_update.js b/napi/module/playlist_tags_update.js new file mode 100644 index 0000000..fa3fb3c --- /dev/null +++ b/napi/module/playlist_tags_update.js @@ -0,0 +1,20 @@ +// 更新歌单标签 + +module.exports = (query, request) => { + const data = { + id: query.id, + tags: query.tags, + }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/tags/update`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/tags/update', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_track_add.js b/napi/module/playlist_track_add.js new file mode 100644 index 0000000..7daaa74 --- /dev/null +++ b/napi/module/playlist_track_add.js @@ -0,0 +1,20 @@ +module.exports = async (query, request) => { + query.cookie.os = 'pc'; + query.ids = query.ids || ''; + const data = { + id: query.pid, + tracks: JSON.stringify( + query.ids.split(',').map((item) => { + return { type: 3, id: item }; + }), + ), + }; + console.log(data); + + return request('POST', `https://music.163.com/api/playlist/track/add`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/playlist_track_delete.js b/napi/module/playlist_track_delete.js new file mode 100644 index 0000000..ae096e2 --- /dev/null +++ b/napi/module/playlist_track_delete.js @@ -0,0 +1,26 @@ +// 收藏单曲到歌单 从歌单删除歌曲 + +module.exports = async (query, request) => { + query.cookie.os = 'pc'; + query.ids = query.ids || ''; + const data = { + id: query.id, + tracks: JSON.stringify( + query.ids.split(',').map((item) => { + return { type: 3, id: item }; + }), + ), + }; + + return request( + 'POST', + `https://music.163.com/api/playlist/track/delete`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playlist_tracks.js b/napi/module/playlist_tracks.js new file mode 100644 index 0000000..45a0627 --- /dev/null +++ b/napi/module/playlist_tracks.js @@ -0,0 +1,51 @@ +// 收藏单曲到歌单 从歌单删除歌曲 + +module.exports = async (query, request) => { + query.cookie.os = 'pc'; + const tracks = query.tracks.split(','); + const data = { + op: query.op, // del,add + pid: query.pid, // 歌单id + trackIds: JSON.stringify(tracks), // 歌曲id + imme: 'true', + }; + + try { + const res = await request( + 'POST', + `https://music.163.com/api/playlist/manipulate/tracks`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + return { + status: 200, + body: { + ...res, + }, + }; + } catch (error) { + if (error.body.code === 512) { + return request( + 'POST', + `https://music.163.com/api/playlist/manipulate/tracks`, + { + op: query.op, // del,add + pid: query.pid, // 歌单id + trackIds: JSON.stringify([...tracks, ...tracks]), + imme: 'true', + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + } + } +}; diff --git a/napi/module/playlist_update.js b/napi/module/playlist_update.js new file mode 100644 index 0000000..e55a527 --- /dev/null +++ b/napi/module/playlist_update.js @@ -0,0 +1,18 @@ +// 编辑歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.desc = query.desc || ''; + query.tags = query.tags || ''; + const data = { + '/api/playlist/desc/update': `{"id":${query.id},"desc":"${query.desc}"}`, + '/api/playlist/tags/update': `{"id":${query.id},"tags":"${query.tags}"}`, + '/api/playlist/update/name': `{"id":${query.id},"name":"${query.name}"}`, + }; + return request('POST', `https://music.163.com/weapi/batch`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/playlist_video_recent.js b/napi/module/playlist_video_recent.js new file mode 100644 index 0000000..e29acbe --- /dev/null +++ b/napi/module/playlist_video_recent.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/playlist/video/recent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/playmode_intelligence_list.js b/napi/module/playmode_intelligence_list.js new file mode 100644 index 0000000..3a0c2fa --- /dev/null +++ b/napi/module/playmode_intelligence_list.js @@ -0,0 +1,22 @@ +// 智能播放 + +module.exports = (query, request) => { + const data = { + songId: query.id, + type: 'fromPlayOne', + playlistId: query.pid, + startMusicId: query.sid || query.id, + count: query.count || 1, + }; + return request( + 'POST', + `https://music.163.com/weapi/playmode/intelligence/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/program_recommend.js b/napi/module/program_recommend.js new file mode 100644 index 0000000..56e63e7 --- /dev/null +++ b/napi/module/program_recommend.js @@ -0,0 +1,20 @@ +// 推荐节目 + +module.exports = (query, request) => { + const data = { + cateId: query.type, + limit: query.limit || 10, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/program/recommend/v1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/rebind.js b/napi/module/rebind.js new file mode 100644 index 0000000..6d615be --- /dev/null +++ b/napi/module/rebind.js @@ -0,0 +1,21 @@ +// 更换手机 + +module.exports = (query, request) => { + const data = { + captcha: query.captcha, + phone: query.phone, + oldcaptcha: query.oldcaptcha, + ctcode: query.ctcode || '86', + }; + return request( + 'POST', + `https://music.163.com/api/user/replaceCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/recommend_resource.js b/napi/module/recommend_resource.js new file mode 100644 index 0000000..786194b --- /dev/null +++ b/napi/module/recommend_resource.js @@ -0,0 +1,15 @@ +// 每日推荐歌单 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/recommend/resource`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/recommend_songs.js b/napi/module/recommend_songs.js new file mode 100644 index 0000000..519e70c --- /dev/null +++ b/napi/module/recommend_songs.js @@ -0,0 +1,17 @@ +// 每日推荐歌曲 + +module.exports = (query, request) => { + query.cookie.os = 'ios'; + const data = {}; + return request( + 'POST', + `https://music.163.com/api/v3/discovery/recommend/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/register_cellphone.js b/napi/module/register_cellphone.js new file mode 100644 index 0000000..fb09fb4 --- /dev/null +++ b/napi/module/register_cellphone.js @@ -0,0 +1,18 @@ +// 注册账号 +const crypto = require('crypto'); + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + captcha: query.captcha, + phone: query.phone, + password: crypto.createHash('md5').update(query.password).digest('hex'), + nickname: query.nickname, + }; + return request('POST', `https://music.163.com/api/register/cellphone`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/related_allvideo.js b/napi/module/related_allvideo.js new file mode 100644 index 0000000..7655ac1 --- /dev/null +++ b/napi/module/related_allvideo.js @@ -0,0 +1,19 @@ +// 相关视频 + +module.exports = (query, request) => { + const data = { + id: query.id, + type: /^\d+$/.test(query.id) ? 0 : 1, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/v1/allvideo/rcmd`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/related_playlist.js b/napi/module/related_playlist.js new file mode 100644 index 0000000..c553837 --- /dev/null +++ b/napi/module/related_playlist.js @@ -0,0 +1,38 @@ +// 相关歌单 + +module.exports = (query, request) => { + return request( + 'GET', + `https://music.163.com/playlist?id=${query.id}`, + {}, + { + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ).then((response) => { + try { + const pattern = /
[\s\S]*?[\s\S]*?]*>([^<]+?)<\/a>[\s\S]*?]*>([^<]+?)<\/a>/g; + let result, + playlists = []; + while ((result = pattern.exec(response.body)) != null) { + playlists.push({ + creator: { + userId: result[4].slice('/user/home?id='.length), + nickname: result[5], + }, + coverImgUrl: result[1].slice(0, -'?param=50y50'.length), + name: result[3], + id: result[2].slice('/playlist?id='.length), + }); + } + response.body = { code: 200, playlists: playlists }; + return response; + } catch (err) { + response.status = 500; + response.body = { code: 500, msg: err.stack }; + return Promise.reject(response); + } + }); +}; diff --git a/napi/module/resource_like.js b/napi/module/resource_like.js new file mode 100644 index 0000000..3d289ba --- /dev/null +++ b/napi/module/resource_like.js @@ -0,0 +1,29 @@ +// 点赞与取消点赞资源 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + query.t = query.t == 1 ? 'like' : 'unlike'; + query.type = { + 1: 'R_MV_5_', // MV + 4: 'A_DJ_1_', // 电台 + 5: 'R_VI_62_', // 视频 + 6: 'A_EV_2_', + }[query.type]; + const data = { + threadId: query.type + query.id, + }; + if (query.type === 'A_EV_2_') { + data.threadId = query.threadId; + } + return request( + 'POST', + `https://music.163.com/weapi/resource/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/scrobble.js b/napi/module/scrobble.js new file mode 100644 index 0000000..5b6d3e7 --- /dev/null +++ b/napi/module/scrobble.js @@ -0,0 +1,27 @@ +// 听歌打卡 + +module.exports = (query, request) => { + const data = { + logs: JSON.stringify([ + { + action: 'play', + json: { + download: 0, + end: 'playend', + id: query.id, + sourceId: query.sourceid, + time: query.time, + type: 'song', + wifi: 0, + }, + }, + ]), + }; + + return request('POST', `https://music.163.com/weapi/feedback/weblog`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/search.js b/napi/module/search.js new file mode 100644 index 0000000..471d781 --- /dev/null +++ b/napi/module/search.js @@ -0,0 +1,16 @@ +// 搜索 + +module.exports = (query, request) => { + const data = { + s: query.keywords, + type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/weapi/search/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/search_default.js b/napi/module/search_default.js new file mode 100644 index 0000000..c231d18 --- /dev/null +++ b/napi/module/search_default.js @@ -0,0 +1,16 @@ +// 默认搜索关键词 + +module.exports = (query, request) => { + return request( + 'POST', + `https://interface3.music.163.com/eapi/search/defaultkeyword/get`, + {}, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/search/defaultkeyword/get', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/search_hot.js b/napi/module/search_hot.js new file mode 100644 index 0000000..dd6b6d4 --- /dev/null +++ b/napi/module/search_hot.js @@ -0,0 +1,14 @@ +// 热门搜索 + +module.exports = (query, request) => { + const data = { + type: 1111, + }; + return request('POST', `https://music.163.com/weapi/search/hot`, data, { + crypto: 'weapi', + ua: 'mobile', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/search_hot_detail.js b/napi/module/search_hot_detail.js new file mode 100644 index 0000000..3e869da --- /dev/null +++ b/napi/module/search_hot_detail.js @@ -0,0 +1,15 @@ +// 热搜列表 +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/weapi/hotsearchlist/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/search_multimatch.js b/napi/module/search_multimatch.js new file mode 100644 index 0000000..6777178 --- /dev/null +++ b/napi/module/search_multimatch.js @@ -0,0 +1,19 @@ +// 多类型搜索 + +module.exports = (query, request) => { + const data = { + type: query.type || 1, + s: query.keywords || '', + }; + return request( + 'POST', + `https://music.163.com/weapi/search/suggest/multimatch`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/search_suggest.js b/napi/module/search_suggest.js new file mode 100644 index 0000000..6e6b9cc --- /dev/null +++ b/napi/module/search_suggest.js @@ -0,0 +1,19 @@ +// 搜索建议 + +module.exports = (query, request) => { + const data = { + s: query.keywords || '', + }; + let type = query.type == 'mobile' ? 'keyword' : 'web'; + return request( + 'POST', + `https://music.163.com/weapi/search/suggest/` + type, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/send_playlist.js b/napi/module/send_playlist.js new file mode 100644 index 0000000..15e9238 --- /dev/null +++ b/napi/module/send_playlist.js @@ -0,0 +1,17 @@ +// 私信歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + id: query.playlist, + type: 'playlist', + msg: query.msg, + userIds: '[' + query.user_ids + ']', + }; + return request('POST', `https://music.163.com/weapi/msg/private/send`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/send_text.js b/napi/module/send_text.js new file mode 100644 index 0000000..72285d6 --- /dev/null +++ b/napi/module/send_text.js @@ -0,0 +1,16 @@ +// 私信 + +module.exports = (query, request) => { + query.cookie.os = 'pc'; + const data = { + type: 'text', + msg: query.msg, + userIds: '[' + query.user_ids + ']', + }; + return request('POST', `https://music.163.com/weapi/msg/private/send`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/setting.js b/napi/module/setting.js new file mode 100644 index 0000000..d26ced6 --- /dev/null +++ b/napi/module/setting.js @@ -0,0 +1,11 @@ +// 设置 + +module.exports = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/api/user/setting`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/share_resource.js b/napi/module/share_resource.js new file mode 100644 index 0000000..cd8a3d0 --- /dev/null +++ b/napi/module/share_resource.js @@ -0,0 +1,20 @@ +// 分享歌曲到动态 + +module.exports = (query, request) => { + const data = { + type: query.type || 'song', // song,playlist,mv,djprogram,djradio + msg: query.msg || '', + id: query.id || '', + }; + return request( + 'POST', + `https://music.163.com/weapi/share/friends/resource`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/simi_artist.js b/napi/module/simi_artist.js new file mode 100644 index 0000000..3c079a8 --- /dev/null +++ b/napi/module/simi_artist.js @@ -0,0 +1,18 @@ +// 相似歌手 + +module.exports = (query, request) => { + const data = { + artistid: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiArtist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/simi_mv.js b/napi/module/simi_mv.js new file mode 100644 index 0000000..bdf76a5 --- /dev/null +++ b/napi/module/simi_mv.js @@ -0,0 +1,13 @@ +// 相似MV + +module.exports = (query, request) => { + const data = { + mvid: query.mvid, + }; + return request('POST', `https://music.163.com/weapi/discovery/simiMV`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/simi_playlist.js b/napi/module/simi_playlist.js new file mode 100644 index 0000000..dbb6bce --- /dev/null +++ b/napi/module/simi_playlist.js @@ -0,0 +1,20 @@ +// 相似歌单 + +module.exports = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiPlaylist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/simi_song.js b/napi/module/simi_song.js new file mode 100644 index 0000000..9cc1c4a --- /dev/null +++ b/napi/module/simi_song.js @@ -0,0 +1,20 @@ +// 相似歌曲 + +module.exports = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/simiSong`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/simi_user.js b/napi/module/simi_user.js new file mode 100644 index 0000000..607277b --- /dev/null +++ b/napi/module/simi_user.js @@ -0,0 +1,20 @@ +// 相似用户 + +module.exports = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiUser`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/song_detail.js b/napi/module/song_detail.js new file mode 100644 index 0000000..92c72ef --- /dev/null +++ b/napi/module/song_detail.js @@ -0,0 +1,15 @@ +// 歌曲详情 + +module.exports = (query, request) => { + query.ids = query.ids.split(/\s*,\s*/); + const data = { + c: '[' + query.ids.map((id) => '{"id":' + id + '}').join(',') + ']', + ids: '[' + query.ids.join(',') + ']', + }; + return request('POST', `https://music.163.com/weapi/v3/song/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/song_order_update.js b/napi/module/song_order_update.js new file mode 100644 index 0000000..3fb6c8a --- /dev/null +++ b/napi/module/song_order_update.js @@ -0,0 +1,22 @@ +// 更新歌曲顺序 + +module.exports = (query, request) => { + const data = { + pid: query.pid, + trackIds: query.ids, + op: 'update', + }; + + return request( + 'POST', + `http://interface.music.163.com/api/playlist/manipulate/tracks`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/desc/update', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/song_url.js b/napi/module/song_url.js new file mode 100644 index 0000000..e2a55ae --- /dev/null +++ b/napi/module/song_url.js @@ -0,0 +1,25 @@ +// 歌曲链接 + +const crypto = require('crypto'); + +module.exports = (query, request) => { + if (!('MUSIC_U' in query.cookie)) + query.cookie._ntes_nuid = crypto.randomBytes(16).toString('hex'); + query.cookie.os = 'pc'; + const data = { + ids: '[' + query.id + ']', + br: parseInt(query.br || 999000), + }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/song/enhance/player/url`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/enhance/player/url', + }, + ); +}; diff --git a/napi/module/top_album.js b/napi/module/top_album.js new file mode 100644 index 0000000..2812f72 --- /dev/null +++ b/napi/module/top_album.js @@ -0,0 +1,27 @@ +// 新碟上架 + +module.exports = (query, request) => { + const date = new Date(); + + const data = { + area: query.area || 'ALL', // //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + limit: query.limit || 50, + offset: query.offset || 0, + type: query.type || 'new', + year: query.year || date.getFullYear(), + month: query.month || date.getMonth() + 1, + total: false, + rcmd: true, + }; + return request( + 'POST', + `https://music.163.com/api/discovery/new/albums/area`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/top_artists.js b/napi/module/top_artists.js new file mode 100644 index 0000000..bd3dbad --- /dev/null +++ b/napi/module/top_artists.js @@ -0,0 +1,15 @@ +// 热门歌手 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/artist/top`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/top_list.js b/napi/module/top_list.js new file mode 100644 index 0000000..5ab262b --- /dev/null +++ b/napi/module/top_list.js @@ -0,0 +1,30 @@ +// 排行榜 +module.exports = (query, request) => { + query.cookie.os = 'pc'; + if (query.idx) { + return Promise.resolve({ + status: 500, + body: { + code: 500, + msg: '不支持此方式调用,只支持id调用', + }, + }); + } + + const data = { + id: query.id, + n: '500', + s: '0', + }; + return request( + 'POST', + `https://interface3.music.163.com/api/playlist/v4/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/top_mv.js b/napi/module/top_mv.js new file mode 100644 index 0000000..4c77888 --- /dev/null +++ b/napi/module/top_mv.js @@ -0,0 +1,16 @@ +// MV排行榜 + +module.exports = (query, request) => { + const data = { + area: query.area || '', + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/mv/toplist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/top_playlist.js b/napi/module/top_playlist.js new file mode 100644 index 0000000..7a2e5e0 --- /dev/null +++ b/napi/module/top_playlist.js @@ -0,0 +1,17 @@ +// 分类歌单 + +module.exports = (query, request) => { + const data = { + cat: query.cat || '全部', // 全部,华语,欧美,日语,韩语,粤语,小语种,流行,摇滚,民谣,电子,舞曲,说唱,轻音乐,爵士,乡村,R&B/Soul,古典,民族,英伦,金属,朋克,蓝调,雷鬼,世界音乐,拉丁,另类/独立,New Age,古风,后摇,Bossa Nova,清晨,夜晚,学习,工作,午休,下午茶,地铁,驾车,运动,旅行,散步,酒吧,怀旧,清新,浪漫,性感,伤感,治愈,放松,孤独,感动,兴奋,快乐,安静,思念,影视原声,ACG,儿童,校园,游戏,70后,80后,90后,网络歌曲,KTV,经典,翻唱,吉他,钢琴,器乐,榜单,00后 + order: query.order || 'hot', // hot,new + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/playlist/list`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/top_playlist_highquality.js b/napi/module/top_playlist_highquality.js new file mode 100644 index 0000000..8eb5b88 --- /dev/null +++ b/napi/module/top_playlist_highquality.js @@ -0,0 +1,21 @@ +// 精品歌单 + +module.exports = (query, request) => { + const data = { + cat: query.cat || '全部', // 全部,华语,欧美,韩语,日语,粤语,小语种,运动,ACG,影视原声,流行,摇滚,后摇,古风,民谣,轻音乐,电子,器乐,说唱,古典,爵士 + limit: query.limit || 50, + lasttime: query.before || 0, // 歌单updateTime + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/playlist/highquality/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/top_song.js b/napi/module/top_song.js new file mode 100644 index 0000000..a6d7d54 --- /dev/null +++ b/napi/module/top_song.js @@ -0,0 +1,21 @@ +// 新歌速递 + +module.exports = (query, request) => { + const data = { + areaId: query.type || 0, // 全部:0 华语:7 欧美:96 日本:8 韩国:16 + // limit: query.limit || 100, + // offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/new/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/toplist.js b/napi/module/toplist.js new file mode 100644 index 0000000..9239ba4 --- /dev/null +++ b/napi/module/toplist.js @@ -0,0 +1,15 @@ +// 所有榜单介绍 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/toplist`, + {}, + { + crypto: 'linuxapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/toplist_artist.js b/napi/module/toplist_artist.js new file mode 100644 index 0000000..3a71147 --- /dev/null +++ b/napi/module/toplist_artist.js @@ -0,0 +1,16 @@ +// 歌手榜 + +module.exports = (query, request) => { + const data = { + type: query.type || 1, + limit: 100, + offset: 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/toplist/artist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/toplist_detail.js b/napi/module/toplist_detail.js new file mode 100644 index 0000000..e3e442f --- /dev/null +++ b/napi/module/toplist_detail.js @@ -0,0 +1,15 @@ +// 所有榜单内容摘要 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/toplist/detail`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_account.js b/napi/module/user_account.js new file mode 100644 index 0000000..f1bf505 --- /dev/null +++ b/napi/module/user_account.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/api/nuser/account/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/user_audio.js b/napi/module/user_audio.js new file mode 100644 index 0000000..43aa231 --- /dev/null +++ b/napi/module/user_audio.js @@ -0,0 +1,18 @@ +// 用户创建的电台 + +module.exports = (query, request) => { + const data = { + userId: query.uid, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/get/byuser`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_binding.js b/napi/module/user_binding.js new file mode 100644 index 0000000..787984f --- /dev/null +++ b/napi/module/user_binding.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/v1/user/bindings/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_cloud.js b/napi/module/user_cloud.js new file mode 100644 index 0000000..0f0aa8e --- /dev/null +++ b/napi/module/user_cloud.js @@ -0,0 +1,14 @@ +// 云盘数据 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/weapi/v1/cloud/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/user_cloud_del.js b/napi/module/user_cloud_del.js new file mode 100644 index 0000000..ab42bfe --- /dev/null +++ b/napi/module/user_cloud_del.js @@ -0,0 +1,13 @@ +// 云盘歌曲删除 + +module.exports = (query, request) => { + const data = { + songIds: [query.id], + }; + return request('POST', `https://music.163.com/weapi/cloud/del`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/user_cloud_detail.js b/napi/module/user_cloud_detail.js new file mode 100644 index 0000000..c41ff80 --- /dev/null +++ b/napi/module/user_cloud_detail.js @@ -0,0 +1,19 @@ +// 云盘数据详情 + +module.exports = (query, request) => { + const id = query.id.replace(/\s/g, '').split(','); + const data = { + songIds: id, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/cloud/get/byids`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_detail.js b/napi/module/user_detail.js new file mode 100644 index 0000000..be14276 --- /dev/null +++ b/napi/module/user_detail.js @@ -0,0 +1,15 @@ +// 用户详情 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/user/detail/${query.uid}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_dj.js b/napi/module/user_dj.js new file mode 100644 index 0000000..78f9c2a --- /dev/null +++ b/napi/module/user_dj.js @@ -0,0 +1,19 @@ +// 用户电台节目 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/dj/program/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_event.js b/napi/module/user_event.js new file mode 100644 index 0000000..35a287c --- /dev/null +++ b/napi/module/user_event.js @@ -0,0 +1,21 @@ +// 用户动态 + +module.exports = (query, request) => { + const data = { + getcounts: true, + time: query.lasttime || -1, + limit: query.limit || 30, + total: false, + }; + return request( + 'POST', + `https://music.163.com/weapi/event/get/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_followeds.js b/napi/module/user_followeds.js new file mode 100644 index 0000000..14dc835 --- /dev/null +++ b/napi/module/user_followeds.js @@ -0,0 +1,21 @@ +// 关注TA的人(粉丝) + +module.exports = (query, request) => { + const data = { + userId: query.uid, + time: query.lasttime || -1, + limit: query.limit || 30, + }; + return request( + 'POST', + `https://music.163.com/eapi/user/getfolloweds/${query.uid}`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/user/getfolloweds', + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_follows.js b/napi/module/user_follows.js new file mode 100644 index 0000000..3e12a21 --- /dev/null +++ b/napi/module/user_follows.js @@ -0,0 +1,20 @@ +// TA关注的人(关注) + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + order: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/user/getfollows/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_level.js b/napi/module/user_level.js new file mode 100644 index 0000000..9eb9694 --- /dev/null +++ b/napi/module/user_level.js @@ -0,0 +1,11 @@ +// 类别热门电台 + +module.exports = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/weapi/user/level`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/user_playlist.js b/napi/module/user_playlist.js new file mode 100644 index 0000000..cdef629 --- /dev/null +++ b/napi/module/user_playlist.js @@ -0,0 +1,16 @@ +// 用户歌单 + +module.exports = (query, request) => { + const data = { + uid: query.uid, + limit: query.limit || 30, + offset: query.offset || 0, + includeVideo: true, + }; + return request('POST', `https://music.163.com/api/user/playlist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/user_record.js b/napi/module/user_record.js new file mode 100644 index 0000000..a882701 --- /dev/null +++ b/napi/module/user_record.js @@ -0,0 +1,14 @@ +// 听歌排行 + +module.exports = (query, request) => { + const data = { + uid: query.uid, + type: query.type || 0, // 1: 最近一周, 0: 所有时间 + }; + return request('POST', `https://music.163.com/weapi/v1/play/record`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/user_replacephone.js b/napi/module/user_replacephone.js new file mode 100644 index 0000000..ee8d459 --- /dev/null +++ b/napi/module/user_replacephone.js @@ -0,0 +1,19 @@ +module.exports = (query, request) => { + const data = { + phone: query.phone, + captcha: query.captcha, + oldcaptcha: query.oldcaptcha, + countrycode: query.countrycode || '86', + }; + return request( + 'POST', + `https://music.163.com/api/user/replaceCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_subcount.js b/napi/module/user_subcount.js new file mode 100644 index 0000000..414ce01 --- /dev/null +++ b/napi/module/user_subcount.js @@ -0,0 +1,15 @@ +// 收藏计数 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/subcount`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/user_update.js b/napi/module/user_update.js new file mode 100644 index 0000000..d84281c --- /dev/null +++ b/napi/module/user_update.js @@ -0,0 +1,24 @@ +// 编辑用户信息 + +module.exports = (query, request) => { + const data = { + avatarImgId: '0', + birthday: query.birthday, + city: query.city, + gender: query.gender, + nickname: query.nickname, + province: query.province, + signature: query.signature, + }; + return request( + 'POST', + `https://music.163.com/weapi/user/profile/update`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_category_list.js b/napi/module/video_category_list.js new file mode 100644 index 0000000..40305fb --- /dev/null +++ b/napi/module/video_category_list.js @@ -0,0 +1,20 @@ +// 视频分类列表 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + total: 'true', + limit: query.limit || 99, + }; + return request( + 'POST', + `https://music.163.com/api/cloudvideo/category/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_detail.js b/napi/module/video_detail.js new file mode 100644 index 0000000..f668743 --- /dev/null +++ b/napi/module/video_detail.js @@ -0,0 +1,18 @@ +// 视频详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/v1/video/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_detail_info.js b/napi/module/video_detail_info.js new file mode 100644 index 0000000..c8ebd4b --- /dev/null +++ b/napi/module/video_detail_info.js @@ -0,0 +1,19 @@ +// 视频点赞转发评论数数据 + +module.exports = (query, request) => { + const data = { + threadid: `R_VI_62_${query.vid}`, + composeliked: true, + }; + return request( + 'POST', + `https://music.163.com/api/comment/commentthread/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_group.js b/napi/module/video_group.js new file mode 100644 index 0000000..77ae3f6 --- /dev/null +++ b/napi/module/video_group.js @@ -0,0 +1,21 @@ +// 视频标签/分类下的视频 + +module.exports = (query, request) => { + const data = { + groupId: query.id, + offset: query.offset || 0, + need_preview_url: 'true', + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/videotimeline/videogroup/otherclient/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_group_list.js b/napi/module/video_group_list.js new file mode 100644 index 0000000..babe3ab --- /dev/null +++ b/napi/module/video_group_list.js @@ -0,0 +1,16 @@ +// 视频标签列表 + +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/cloudvideo/group/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_sub.js b/napi/module/video_sub.js new file mode 100644 index 0000000..1e46591 --- /dev/null +++ b/napi/module/video_sub.js @@ -0,0 +1,19 @@ +// 收藏与取消收藏视频 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { + id: query.id, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/video/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_timeline_all.js b/napi/module/video_timeline_all.js new file mode 100644 index 0000000..9c107a6 --- /dev/null +++ b/napi/module/video_timeline_all.js @@ -0,0 +1,22 @@ +// 全部视频列表 + +module.exports = (query, request) => { + const data = { + groupId: 0, + offset: query.offset || 0, + need_preview_url: 'true', + total: true, + }; + // /api/videotimeline/otherclient/get + return request( + 'POST', + `https://music.163.com/api/videotimeline/otherclient/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/video_timeline_recommend.js b/napi/module/video_timeline_recommend.js new file mode 100644 index 0000000..a249089 --- /dev/null +++ b/napi/module/video_timeline_recommend.js @@ -0,0 +1,17 @@ +// 推荐视频 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + filterLives: '[]', + withProgramInfo: 'true', + needUrl: '1', + resolution: '480', + }; + return request('POST', `https://music.163.com/api/videotimeline/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/video_url.js b/napi/module/video_url.js new file mode 100644 index 0000000..8d2673c --- /dev/null +++ b/napi/module/video_url.js @@ -0,0 +1,19 @@ +// 视频链接 + +module.exports = (query, request) => { + const data = { + ids: '["' + query.id + '"]', + resolution: query.res || 1080, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/playurl`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/weblog.js b/napi/module/weblog.js new file mode 100644 index 0000000..2b8d0be --- /dev/null +++ b/napi/module/weblog.js @@ -0,0 +1,15 @@ +// 操作记录 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/feedback/weblog`, + query.data || {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/yunbei.js b/napi/module/yunbei.js new file mode 100644 index 0000000..367fe3e --- /dev/null +++ b/napi/module/yunbei.js @@ -0,0 +1,10 @@ +module.exports = (query, request) => { + const data = {}; + // /api/point/today/get + return request('POST', `https://music.163.com/api/point/signed/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/yunbei_expense.js b/napi/module/yunbei_expense.js new file mode 100644 index 0000000..29ab8d0 --- /dev/null +++ b/napi/module/yunbei_expense.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/store/api/point/expense`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/yunbei_info.js b/napi/module/yunbei_info.js new file mode 100644 index 0000000..7aa122a --- /dev/null +++ b/napi/module/yunbei_info.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/api/v1/user/info`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/yunbei_receipt.js b/napi/module/yunbei_receipt.js new file mode 100644 index 0000000..7b662ce --- /dev/null +++ b/napi/module/yunbei_receipt.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/store/api/point/receipt`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/yunbei_sign.js b/napi/module/yunbei_sign.js new file mode 100644 index 0000000..0f1c913 --- /dev/null +++ b/napi/module/yunbei_sign.js @@ -0,0 +1,11 @@ +module.exports = (query, request) => { + const data = { + type: '0', + }; + return request('POST', `https://music.163.com/api/point/dailyTask`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/module/yunbei_task_finish.js b/napi/module/yunbei_task_finish.js new file mode 100644 index 0000000..258c495 --- /dev/null +++ b/napi/module/yunbei_task_finish.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + userTaskId: query.userTaskId, + depositCode: query.depositCode || '0', + }; + return request( + 'POST', + `https://music.163.com/api/usertool/task/point/receive`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/yunbei_tasks.js b/napi/module/yunbei_tasks.js new file mode 100644 index 0000000..7515e00 --- /dev/null +++ b/napi/module/yunbei_tasks.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/usertool/task/list/all`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/yunbei_tasks_todo.js b/napi/module/yunbei_tasks_todo.js new file mode 100644 index 0000000..924dced --- /dev/null +++ b/napi/module/yunbei_tasks_todo.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/usertool/task/todo/query`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); +}; diff --git a/napi/module/yunbei_today.js b/napi/module/yunbei_today.js new file mode 100644 index 0000000..4f707f8 --- /dev/null +++ b/napi/module/yunbei_today.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/api/point/today/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); +}; diff --git a/napi/package-lock.json b/napi/package-lock.json new file mode 100644 index 0000000..de5e769 --- /dev/null +++ b/napi/package-lock.json @@ -0,0 +1,4096 @@ +{ + "name": "NeteaseCloudMusicApi", + "version": "3.45.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.10.4.tgz?cache=0&sync_timestamp=1593522948158&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcode-frame%2Fdownload%2F%40babel%2Fcode-frame-7.10.4.tgz", + "integrity": "sha1-Fo2ho26Q2miujUnA8bSMfGJJITo=", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npm.taobao.org/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.10.4.tgz?cache=0&sync_timestamp=1593521083613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.10.4.tgz", + "integrity": "sha1-p4x6clHgH2FlEtMbEK3PUq2l4NI=", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.10.4.tgz?cache=0&sync_timestamp=1593521095576&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhighlight%2Fdownload%2F%40babel%2Fhighlight-7.10.4.tgz", + "integrity": "sha1-fRvf1ldTU4+r5sOFls23bZrGAUM=", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1591687076871&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz", + "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@eslint/eslintrc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.0.tgz", + "integrity": "sha512-+cIGPCBdLCzqxdtwppswP+zTsH9BOIGzAeKfBIbtb4gW/giMlfMwP0HUSFfhzh20f9u8uZ8hOp62+4GPquTbwQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npm.taobao.org/@nodelib/fs.scandir/download/@nodelib/fs.scandir-2.1.3.tgz", + "integrity": "sha1-Olgr21OATGum0UZXnEblITDPSjs=", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-2.0.3.tgz", + "integrity": "sha1-NNxfTKu8cg9OYPdadH5+zWwXW9M=", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npm.taobao.org/@nodelib/fs.walk/download/@nodelib/fs.walk-1.2.4.tgz", + "integrity": "sha1-ARuSAqcKY2bkNspcBlhEUoqwSXY=", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/@tootallnate/once/download/@tootallnate/once-1.1.2.tgz", + "integrity": "sha1-zLkURTYBeaBOf+av94wA/8Hur4I=" + }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npm.taobao.org/@types/json-schema/download/@types/json-schema-7.0.6.tgz?cache=0&sync_timestamp=1598910403749&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson-schema%2Fdownload%2F%40types%2Fjson-schema-7.0.6.tgz", + "integrity": "sha1-9MfsQ+gbMZqYFRFQMXCfJph4kfA=", + "dev": true + }, + "@types/node": { + "version": "14.11.10", + "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.11.10.tgz", + "integrity": "sha1-jBAquhO/UlPzUUav+/iyYnUGm+8=", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/@types/parse-json/download/@types/parse-json-4.0.0.tgz?cache=0&sync_timestamp=1596839394119&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fparse-json%2Fdownload%2F%40types%2Fparse-json-4.0.0.tgz", + "integrity": "sha1-L4u0QUNNFjs1+4/9zNcTiSf/uMA=", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-4.4.1.tgz?cache=0&sync_timestamp=1603565073344&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-4.4.1.tgz", + "integrity": "sha1-uKzqA3O9KjiKxH30RlLwC/izaPU=", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.4.1", + "@typescript-eslint/scope-manager": "4.4.1", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/experimental-utils/download/@typescript-eslint/experimental-utils-4.4.1.tgz?cache=0&sync_timestamp=1603563239927&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-4.4.1.tgz", + "integrity": "sha1-QGE7l1f6AXDePgBDJU27B3yvrAw=", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.4.1", + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/typescript-estree": "4.4.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/parser/download/@typescript-eslint/parser-4.4.1.tgz?cache=0&sync_timestamp=1603563241160&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-4.4.1.tgz", + "integrity": "sha1-Jf3pwIBhHzA/LzPO2xRdLFmRW4A=", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.4.1", + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/typescript-estree": "4.4.1", + "debug": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/scope-manager/download/@typescript-eslint/scope-manager-4.4.1.tgz", + "integrity": "sha1-0ZRH5g2yzpxCWJjWL6A7LM6Oo/k=", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/visitor-keys": "4.4.1" + } + }, + "@typescript-eslint/types": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/types/download/@typescript-eslint/types-4.4.1.tgz", + "integrity": "sha1-xQezXPUjvHugCq5fde6bgQzau8E=", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-4.4.1.tgz?cache=0&sync_timestamp=1603563238913&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-4.4.1.tgz", + "integrity": "sha1-WY9t5IgQbCWH1HyiRixg9uJ5fLg=", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/visitor-keys": "4.4.1", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.4.1", + "resolved": "https://registry.npm.taobao.org/@typescript-eslint/visitor-keys/download/@typescript-eslint/visitor-keys-4.4.1.tgz", + "integrity": "sha1-F2ncep4tfSz9Mxi3ftgkkYeu1cM=", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.4.1", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/@ungap/promise-all-settled/download/@ungap/promise-all-settled-1.1.2.tgz", + "integrity": "sha1-qlgEJxHW4ydd033Fl+XTHowpCkQ=", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz", + "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-es7-plugin": { + "version": "1.1.7", + "resolved": "https://registry.npm.taobao.org/acorn-es7-plugin/download/acorn-es7-plugin-1.1.7.tgz", + "integrity": "sha1-8u4fMiipDurRJF+asZIusucdM2s=", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npm.taobao.org/agent-base/download/agent-base-6.0.2.tgz?cache=0&sync_timestamp=1603480100923&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fagent-base%2Fdownload%2Fagent-base-6.0.2.tgz", + "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.1.0.tgz?cache=0&sync_timestamp=1598049717562&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faggregate-error%2Fdownload%2Faggregate-error-3.1.0.tgz", + "integrity": "sha1-kmcP9Q9TWb23o+DUDQ7DDFc3aHo=", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1603561547443&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz", + "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-4.1.1.tgz", + "integrity": "sha1-y7muJWv3UK8eqzRPIpqif+lLo0g=", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-4.3.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-escapes%2Fdownload%2Fansi-escapes-4.3.1.tgz", + "integrity": "sha1-pcR8xDGB8fOP/XB2g3cA05VSKmE=", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.11.0.tgz?cache=0&sync_timestamp=1602623859603&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.11.0.tgz", + "integrity": "sha1-l6vwhyMQ/tiKXEZrJWgVdhReM/E=", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz", + "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/anymatch/download/anymatch-3.1.1.tgz", + "integrity": "sha1-xV7PAhheJGklk5kxDBc84xIzsUI=", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz?cache=0&sync_timestamp=1598649734444&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fargparse%2Fdownload%2Fargparse-1.0.10.tgz", + "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/array-filter/download/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", + "dev": true + }, + "array-find": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/array-find/download/array-find-1.0.0.tgz", + "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/array-union/download/array-union-2.1.0.tgz", + "integrity": "sha1-t5hCCtvrHego2ErNii4j0+/oXo0=", + "dev": true + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npm.taobao.org/ast-types/download/ast-types-0.13.4.tgz?cache=0&sync_timestamp=1599935985242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fast-types%2Fdownload%2Fast-types-0.13.4.tgz", + "integrity": "sha1-7g13s0MmOWXsw/ti2hbnIisrZ4I=", + "requires": { + "tslib": "^2.0.1" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz", + "integrity": "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k=", + "dev": true + }, + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.20.0.tgz", + "integrity": "sha1-BXujDwSIRpSZOozQf6OUz/EcUL0=", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-2.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbinary-extensions%2Fdownload%2Fbinary-extensions-2.1.0.tgz", + "integrity": "sha1-MPpAyef+B9vIlWeM0ocCTeokHdk=", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz", + "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1601898189928&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz", + "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npm.taobao.org/browser-stdout/download/browser-stdout-1.3.1.tgz", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", + "dev": true + }, + "busboy": { + "version": "0.3.1", + "resolved": "https://registry.npm.taobao.org/busboy/download/busboy-0.3.1.tgz", + "integrity": "sha1-FwiZJ0xb84quJ9XGK3EmjNWF/Rs=", + "requires": { + "dicer": "0.3.0" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz", + "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=" + }, + "call-matcher": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/call-matcher/download/call-matcher-1.1.0.tgz", + "integrity": "sha1-I7LBvHqDlMi+KGCdd929V4ZoBDI=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "deep-equal": "^1.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.0.0" + } + }, + "call-signature": { + "version": "0.0.2", + "resolved": "https://registry.npm.taobao.org/call-signature/download/call-signature-0.0.2.tgz", + "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz", + "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1602350083472&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz", + "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz?cache=0&sync_timestamp=1591687076871&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz", + "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611709087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz", + "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-3.4.3.tgz?cache=0&sync_timestamp=1602585381749&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.4.3.tgz", + "integrity": "sha1-wd84IxRI5FykrFiObHlXO6alfVs=", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/ci-info/download/ci-info-2.0.0.tgz", + "integrity": "sha1-Z6npZL4xpR4V5QENWObxKDQAL0Y=", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npm.taobao.org/clean-stack/download/clean-stack-2.2.0.tgz?cache=0&sync_timestamp=1592035524745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-stack%2Fdownload%2Fclean-stack-2.2.0.tgz", + "integrity": "sha1-7oRy27Ep5yezHooQpCfe6d/kAIs=", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/cli-cursor/download/cli-cursor-3.1.0.tgz", + "integrity": "sha1-JkMFp65JDR0Dvwybp8kl0XU68wc=", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/cli-truncate/download/cli-truncate-2.1.0.tgz", + "integrity": "sha1-w54ovwXtzeW+O5iZKiLe7Vork8c=", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-2.0.0.tgz", + "integrity": "sha1-SDFDxWeu7UeFdZwIZXhtx319LjE=", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1603212180491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz", + "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-3.0.0.tgz", + "integrity": "sha1-Md3BCTCht+C2ewjJbC9Jt3p4l4c=", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz", + "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/cliui/download/cliui-5.0.0.tgz?cache=0&sync_timestamp=1602861367442&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-5.0.0.tgz", + "integrity": "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U=", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-5.1.0.tgz", + "integrity": "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "6.2.0", + "resolved": "https://registry.npm.taobao.org/commander/download/commander-6.2.0.tgz?cache=0&sync_timestamp=1603599636161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-6.2.0.tgz", + "integrity": "sha1-uZC/uKwDCu3G0RvATRSI/+9W23U=", + "dev": true + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npm.taobao.org/compare-versions/download/compare-versions-3.6.0.tgz", + "integrity": "sha1-GlaJkTaF5ah2N7jT/8p1UU7EHWI=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz", + "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz", + "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz?cache=0&sync_timestamp=1573003637425&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.7.0.tgz", + "integrity": "sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz?cache=0&sync_timestamp=1587525865178&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.0.tgz", + "integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-2.6.11.tgz?cache=0&sync_timestamp=1586450269267&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-2.6.11.tgz", + "integrity": "sha1-OIMUafmSK97Y7iHJ3EaYXgOZMIw=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-6.0.0.tgz?cache=0&sync_timestamp=1596310819353&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-6.0.0.tgz", + "integrity": "sha1-2k/uhTxS9rHmk19BwaL8UL1KmYI=", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz", + "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/d/download/d-1.0.1.tgz", + "integrity": "sha1-hpgJU3LVjb7jRv/Qxwk/mfj561o=", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npm.taobao.org/data-uri-to-buffer/download/data-uri-to-buffer-3.0.1.tgz?cache=0&sync_timestamp=1590800007667&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdata-uri-to-buffer%2Fdownload%2Fdata-uri-to-buffer-3.0.1.tgz", + "integrity": "sha1-WUuJc5OMW8LDMEZTV4U0GrxPNjY=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npm.taobao.org/dedent/download/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz", + "integrity": "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o=", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz", + "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "degenerator": { + "version": "2.2.0", + "resolved": "https://registry.npm.taobao.org/degenerator/download/degenerator-2.2.0.tgz", + "integrity": "sha1-SemMEfoCk8Wybt+7UvFXKa/NslQ=", + "requires": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dicer": { + "version": "0.3.0", + "resolved": "https://registry.npm.taobao.org/dicer/download/dicer-0.3.0.tgz", + "integrity": "sha1-6s2Ys7+/kuirXC/bcaqsRLsGuHI=", + "requires": { + "streamsearch": "0.1.2" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz?cache=0&sync_timestamp=1578890967183&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz", + "integrity": "sha1-YPOuy4nV+uUgwRqhnvwruYKq3n0=", + "dev": true + }, + "diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npm.taobao.org/diff-match-patch/download/diff-match-patch-1.0.5.tgz", + "integrity": "sha1-q7WE1fEM0Rlt/FWqA3AVkq4/ezc=", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-3.0.1.tgz", + "integrity": "sha1-Vtv3PZkqSpO6FYT0U0Bj/S5BcX8=", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/doctrine/download/doctrine-3.0.0.tgz", + "integrity": "sha1-rd6+rXKmV023g2OdyHoSF3OXOWE=", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/dom-serializer/download/dom-serializer-1.1.0.tgz", + "integrity": "sha1-X3yCjxv8RIh9wqMVq1xFaR1US1g=", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.0.2", + "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-2.0.2.tgz?cache=0&sync_timestamp=1600028495728&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomelementtype%2Fdownload%2Fdomelementtype-2.0.2.tgz", + "integrity": "sha1-87blSSAeRvWItZRj3XcYcTH+aXE=", + "dev": true + }, + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npm.taobao.org/domhandler/download/domhandler-3.3.0.tgz", + "integrity": "sha1-bbfqRuRhfrFc+HXfaLK4UkzgA3o=", + "dev": true, + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.4.2", + "resolved": "https://registry.npm.taobao.org/domutils/download/domutils-2.4.2.tgz", + "integrity": "sha1-fuW+JhlE4a1IfZqgYWcgAQEjkis=", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.0.1", + "domhandler": "^3.3.0" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npm.taobao.org/eastasianwidth/download/eastasianwidth-0.2.0.tgz", + "integrity": "sha1-aWzi7Aqg5uqTo5f/zySqeEDIJ8s=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz?cache=0&sync_timestamp=1603212180491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-7.0.3.tgz", + "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=", + "dev": true + }, + "empower": { + "version": "1.3.1", + "resolved": "https://registry.npm.taobao.org/empower/download/empower-1.3.1.tgz", + "integrity": "sha1-dol5y7s21x2PXtqrZj3qy52rkWw=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "empower-core": "^1.2.0" + } + }, + "empower-assert": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/empower-assert/download/empower-assert-1.1.0.tgz", + "integrity": "sha1-jTJ/vmmoivkN2pjRv8mCnSok/WI=", + "dev": true, + "requires": { + "estraverse": "^4.2.0" + } + }, + "empower-core": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/empower-core/download/empower-core-1.2.0.tgz", + "integrity": "sha1-zj+ySE1Rh/opwj+6g0Swsv31YBw=", + "dev": true, + "requires": { + "call-signature": "0.0.2", + "core-js": "^2.0.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz", + "integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npm.taobao.org/enquirer/download/enquirer-2.3.6.tgz?cache=0&sync_timestamp=1593693291943&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fenquirer%2Fdownload%2Fenquirer-2.3.6.tgz", + "integrity": "sha1-Kn/l3WNKHkElqXXsmU/1RW3Dc00=", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/entities/download/entities-2.1.0.tgz?cache=0&sync_timestamp=1602897029273&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fentities%2Fdownload%2Fentities-2.1.0.tgz", + "integrity": "sha1-mS0xKc999ocLlsV4WMJJoSD4uLU=", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npm.taobao.org/error-ex/download/error-ex-1.3.2.tgz", + "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.18.0-next.1.tgz?cache=0&sync_timestamp=1601502719982&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.18.0-next.1.tgz", + "integrity": "sha1-bjoKS9pxflAjqzuOkL7DYQjSLGg=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz", + "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo=", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npm.taobao.org/es5-ext/download/es5-ext-0.10.53.tgz", + "integrity": "sha1-k8WjrP2+8nUiCtcmRK0C7hg2jeE=", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/es6-iterator/download/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npm.taobao.org/es6-map/download/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npm.taobao.org/es6-set/download/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/es6-symbol/download/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npm.taobao.org/es6-symbol/download/es6-symbol-3.1.3.tgz", + "integrity": "sha1-utXTwbzawoJp9MszHkMceKxwXRg=", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/es6-weak-map/download/es6-weak-map-2.0.3.tgz", + "integrity": "sha1-ttofFswswNm+Q+a9v8Xn383zHVM=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escallmatch": { + "version": "1.5.0", + "resolved": "https://registry.npm.taobao.org/escallmatch/download/escallmatch-1.5.0.tgz", + "integrity": "sha1-UAmdhugJGwkt+N37w/mm+wWgJNA=", + "dev": true, + "requires": { + "call-matcher": "^1.0.0", + "esprima": "^2.0.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + } + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npm.taobao.org/escodegen/download/escodegen-1.14.3.tgz?cache=0&sync_timestamp=1596669832613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescodegen%2Fdownload%2Fescodegen-1.14.3.tgz", + "integrity": "sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM=", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npm.taobao.org/escope/download/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.0.tgz", + "integrity": "sha512-n5pEU27DRxCSlOhJ2rO57GDLcNsxO0LPpAbpFdh7xmcDmjmlGUfoyrsB3I7yYdQXO5N3gkSTiDrPSPNFiiirXA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz?cache=0&sync_timestamp=1590809289115&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fignore%2Fdownload%2Fignore-4.0.6.tgz", + "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.4.1.tgz", + "integrity": "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npm.taobao.org/optionator/download/optionator-0.9.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.9.1.tgz", + "integrity": "sha1-TyNqY3Pa4FZqbUPhMmZ09QwpFJk=", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.2.1.tgz", + "integrity": "sha1-3rxkidem5rDnYRiIzsiAM30xY5Y=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.4.0.tgz", + "integrity": "sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE=", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "eslint-config-prettier": { + "version": "6.13.0", + "resolved": "https://registry.npm.taobao.org/eslint-config-prettier/download/eslint-config-prettier-6.13.0.tgz?cache=0&sync_timestamp=1603294035236&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.13.0.tgz", + "integrity": "sha1-IH2IeWtWJOW7gVu738WJHOuev/o=", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-plugin-html": { + "version": "6.0.3", + "resolved": "https://registry.npm.taobao.org/eslint-plugin-html/download/eslint-plugin-html-6.0.3.tgz?cache=0&sync_timestamp=1599391535931&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-html%2Fdownload%2Feslint-plugin-html-6.0.3.tgz", + "integrity": "sha1-jZ0sGH0aSO142E9F4pgg8QJCXlE=", + "dev": true, + "requires": { + "htmlparser2": "^4.1.0" + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npm.taobao.org/eslint-plugin-prettier/download/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha1-Foq0MVTi6lfbmSos0JfIKBcfdcI=", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-5.1.1.tgz?cache=0&sync_timestamp=1599933651660&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-scope%2Fdownload%2Feslint-scope-5.1.1.tgz", + "integrity": "sha1-54blmmbLkrP2wfsNUIqrF0hI9Iw=", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/eslint-utils/download/eslint-utils-2.1.0.tgz?cache=0&sync_timestamp=1592222145079&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-utils%2Fdownload%2Feslint-utils-2.1.0.tgz", + "integrity": "sha1-0t5eA0JOcH3BDHQGjd7a5wh0Gyc=", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz?cache=0&sync_timestamp=1597435068105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz", + "integrity": "sha1-MOvR73wv3/AcOk8VEESvJfqwUj4=", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-2.0.0.tgz?cache=0&sync_timestamp=1597435068105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-2.0.0.tgz", + "integrity": "sha1-If3I+82ceVzAMh8FY3AglXUVEag=", + "dev": true + }, + "espower": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/espower/download/espower-2.1.2.tgz", + "integrity": "sha1-gk+IeI+f7fTPD5KPXhG7kHzpuRg=", + "dev": true, + "requires": { + "array-find": "^1.0.0", + "escallmatch": "^1.5.0", + "escodegen": "^1.7.0", + "escope": "^3.3.0", + "espower-location-detector": "^1.0.0", + "espurify": "^1.3.0", + "estraverse": "^4.1.0", + "source-map": "^0.5.0", + "type-name": "^2.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "espower-loader": { + "version": "1.2.2", + "resolved": "https://registry.npm.taobao.org/espower-loader/download/espower-loader-1.2.2.tgz", + "integrity": "sha1-7bRsPFmga6yOpzppXIblxaC8gto=", + "dev": true, + "requires": { + "convert-source-map": "^1.1.0", + "espower-source": "^2.0.0", + "minimatch": "^3.0.0", + "source-map-support": "^0.4.0", + "xtend": "^4.0.0" + } + }, + "espower-location-detector": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/espower-location-detector/download/espower-location-detector-1.0.0.tgz", + "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", + "dev": true, + "requires": { + "is-url": "^1.2.1", + "path-is-absolute": "^1.0.0", + "source-map": "^0.5.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "espower-source": { + "version": "2.3.0", + "resolved": "https://registry.npm.taobao.org/espower-source/download/espower-source-2.3.0.tgz", + "integrity": "sha1-Q+k7LBivUAGL2xvqehJx9KHBJfQ=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "acorn-es7-plugin": "^1.0.10", + "convert-source-map": "^1.1.1", + "empower-assert": "^1.0.0", + "escodegen": "^1.10.0", + "espower": "^2.1.1", + "estraverse": "^4.0.0", + "merge-estraverse-visitors": "^1.0.0", + "multi-stage-sourcemap": "^0.2.1", + "path-is-absolute": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-5.7.4.tgz", + "integrity": "sha1-Po2KmUfQWZoXltECJddDL0pKz14=", + "dev": true + } + } + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz", + "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=" + }, + "espurify": { + "version": "1.8.1", + "resolved": "https://registry.npm.taobao.org/espurify/download/espurify-1.8.1.tgz", + "integrity": "sha1-V0bGwatC0wLeEL0dW/fw6MBRUFY=", + "dev": true, + "requires": { + "core-js": "^2.0.0" + } + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npm.taobao.org/esquery/download/esquery-1.3.1.tgz?cache=0&sync_timestamp=1587061286348&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fesquery%2Fdownload%2Fesquery-1.3.1.tgz", + "integrity": "sha1-t4tYKKqOIU4p+3TE1bdS4cAz2lc=", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-5.2.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-5.2.0.tgz", + "integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.3.0.tgz?cache=0&sync_timestamp=1598898255610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fesrecurse%2Fdownload%2Fesrecurse-4.3.0.tgz", + "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-5.2.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-5.2.0.tgz", + "integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz", + "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz", + "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npm.taobao.org/event-emitter/download/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://registry.npm.taobao.org/execa/download/execa-4.0.3.tgz?cache=0&sync_timestamp=1594145085955&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-4.0.3.tgz", + "integrity": "sha1-CjTau61tZhAL1vLFdshmlAPzF/I=", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexpress%2Fdownload%2Fexpress-4.17.1.tgz", + "integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "express-fileupload": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/express-fileupload/download/express-fileupload-1.2.0.tgz", + "integrity": "sha1-NWxN/WRb5xq5+y9ObYTusA0keXk=", + "requires": { + "busboy": "^0.3.1" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/ext/download/ext-1.4.0.tgz", + "integrity": "sha1-ia56BxWPedNVF4gpBDJAd+Q3kkQ=", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/type/download/type-2.1.0.tgz?cache=0&sync_timestamp=1598016585110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype%2Fdownload%2Ftype-2.1.0.tgz", + "integrity": "sha1-m9wixkjPjPht0j0yM2pBz7ZHXj8=", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz?cache=0&sync_timestamp=1591599697571&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-deep-equal%2Fdownload%2Ffast-deep-equal-3.1.3.tgz", + "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/fast-diff/download/fast-diff-1.2.0.tgz", + "integrity": "sha1-c+4RmC2Gyq95WYKNUZz+kn+sXwM=", + "dev": true + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-3.2.4.tgz?cache=0&sync_timestamp=1592291968616&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-3.2.4.tgz", + "integrity": "sha1-0grvv5lXk4Pn88xmUpFYybmFVNM=", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz?cache=0&sync_timestamp=1576340291001&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-json-stable-stringify%2Fdownload%2Ffast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npm.taobao.org/fastq/download/fastq-1.8.0.tgz?cache=0&sync_timestamp=1589280329638&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffastq%2Fdownload%2Ffastq-1.8.0.tgz", + "integrity": "sha1-VQ4fn1m7xl/hhctqm02VNXEH9IE=", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npm.taobao.org/figures/download/figures-3.2.0.tgz?cache=0&sync_timestamp=1581865349068&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffigures%2Fdownload%2Ffigures-3.2.0.tgz", + "integrity": "sha1-YlwYvSk8YE3EqN2y/r8MiDQXRq8=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-5.0.1.tgz", + "integrity": "sha1-yg9u+m3T1WEzP7FFFQZcL6/fQ5w=", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-2.0.0.tgz", + "integrity": "sha1-e0Fa66In1XWFHgpbDGQNdlZAP7o=" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz", + "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz", + "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169842138&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz", + "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npm.taobao.org/find-versions/download/find-versions-3.2.0.tgz", + "integrity": "sha1-ECl/mAMKeGgpaBaQVF72We0dJU4=", + "dev": true, + "requires": { + "semver-regex": "^2.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npm.taobao.org/flat/download/flat-5.0.2.tgz?cache=0&sync_timestamp=1602723468701&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fflat%2Fdownload%2Fflat-5.0.2.tgz", + "integrity": "sha1-jKb+MyBp/6nTJMMnGYxZglnOskE=", + "dev": true + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz", + "integrity": "sha1-XSltbwS9pEpGMKMBQTvbwuwIXsA=", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npm.taobao.org/flatted/download/flatted-2.0.2.tgz", + "integrity": "sha1-RXWyHivO50NKqb5mL0t7X5wrUTg=", + "dev": true + }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.0.tgz?cache=0&sync_timestamp=1597057976909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.13.0.tgz", + "integrity": "sha1-tC6Nk6Kn7qXtiGM2dtZZe8jjhNs=" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-8.1.0.tgz", + "integrity": "sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npm.taobao.org/fsevents/download/fsevents-2.1.3.tgz?cache=0&sync_timestamp=1588787369955&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffsevents%2Fdownload%2Ffsevents-2.1.3.tgz", + "integrity": "sha1-+3OHA66NL5/pAMM4Nt3r7ouX8j4=", + "dev": true, + "optional": true + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npm.taobao.org/ftp/download/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz", + "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", + "dev": true + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npm.taobao.org/get-own-enumerable-property-symbols/download/get-own-enumerable-property-symbols-3.0.2.tgz?cache=0&sync_timestamp=1575993334275&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-own-enumerable-property-symbols%2Fdownload%2Fget-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha1-tf3nfyLL4185C04ImSLFC85u9mQ=", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz", + "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-5.2.0.tgz?cache=0&sync_timestamp=1597056502934&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-5.2.0.tgz", + "integrity": "sha1-SWaheV7lrOZecGxLe+txJX1uItM=", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npm.taobao.org/get-uri/download/get-uri-3.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-uri%2Fdownload%2Fget-uri-3.0.2.tgz", + "integrity": "sha1-8O8TVvqrxw4flAT6O2ayupv8clw=", + "requires": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1573078121947&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npm.taobao.org/glob-parent/download/glob-parent-5.1.1.tgz", + "integrity": "sha1-tsHvQXxOVmPqSY8cRa+saRa7wik=", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npm.taobao.org/globby/download/globby-11.0.1.tgz?cache=0&sync_timestamp=1591083783605&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobby%2Fdownload%2Fglobby-11.0.1.tgz", + "integrity": "sha1-mivxB6Bo8//qvEmtcCx57ejP01c=", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.4.tgz", + "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npm.taobao.org/growl/download/growl-1.10.5.tgz", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/has-symbols/download/has-symbols-1.0.1.tgz", + "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "dev": true + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-4.1.0.tgz?cache=0&sync_timestamp=1601761730691&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-4.1.0.tgz", + "integrity": "sha1-mk7xYfLkYl6/ffvmwKL1LRilnng=", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1593407858306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz", + "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npm.taobao.org/http-proxy-agent/download/http-proxy-agent-4.0.1.tgz", + "integrity": "sha1-ioyO9/WTLM+VPClsqCkblap0qjo=", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-5.0.0.tgz?cache=0&sync_timestamp=1581106803611&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttps-proxy-agent%2Fdownload%2Fhttps-proxy-agent-5.0.0.tgz", + "integrity": "sha1-4qkFQqu2inYuCghQ9sntrf2FBrI=", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz?cache=0&sync_timestamp=1584198662293&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhuman-signals%2Fdownload%2Fhuman-signals-1.1.1.tgz", + "integrity": "sha1-xbHNFPUK6uCatsWf5jujOV/k36M=", + "dev": true + }, + "husky": { + "version": "4.2.5", + "resolved": "https://registry.npm.taobao.org/husky/download/husky-4.2.5.tgz?cache=0&sync_timestamp=1602813564105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhusky%2Fdownload%2Fhusky-4.2.5.tgz", + "integrity": "sha1-K092Imc6cVefkB2Yhe1Eg5S1+jY=", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^6.0.0", + "find-versions": "^3.2.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184264130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz", + "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-5.1.8.tgz?cache=0&sync_timestamp=1590809289115&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fignore%2Fdownload%2Fignore-5.1.8.tgz", + "integrity": "sha1-8VCotQo0KJsz4i9YiavU2AFvDlc=", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz", + "integrity": "sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY=", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/indent-string/download/indent-string-4.0.0.tgz", + "integrity": "sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npm.taobao.org/indexof/download/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "intelli-espower-loader": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/intelli-espower-loader/download/intelli-espower-loader-1.0.1.tgz", + "integrity": "sha1-LHsDFGvB1GvyENCgOXxckatMorA=", + "dev": true, + "requires": { + "espower-loader": "^1.0.0" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npm.taobao.org/ip/download/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz", + "integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM=" + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz", + "integrity": "sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-2.1.0.tgz", + "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npm.taobao.org/is-callable/download/is-callable-1.2.2.tgz?cache=0&sync_timestamp=1600719276620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-callable%2Fdownload%2Fis-callable-1.2.2.tgz", + "integrity": "sha1-x8ZxXNItTdtI0+GZcCI6zquwgNk=", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/is-date-object/download/is-date-object-1.0.2.tgz?cache=0&sync_timestamp=1576729165697&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-date-object%2Fdownload%2Fis-date-object-1.0.2.tgz", + "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz", + "integrity": "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-2.1.0.tgz?cache=0&sync_timestamp=1602541451286&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-plain-obj%2Fdownload%2Fis-plain-obj-2.1.0.tgz", + "integrity": "sha1-ReQuN/zPH0Dajl927iFRWEDAkoc=", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/is-regex/download/is-regex-1.1.1.tgz?cache=0&sync_timestamp=1596555762356&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-regex%2Fdownload%2Fis-regex-1.1.1.tgz", + "integrity": "sha1-xvmKrMVG9s7FRooHt7FTq1ZKV7k=", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/is-regexp/download/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/is-stream/download/is-stream-2.0.0.tgz", + "integrity": "sha1-venDJoDW+uBBKdasnZIc54FfeOM=", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/is-symbol/download/is-symbol-1.0.3.tgz", + "integrity": "sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc=", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npm.taobao.org/is-url/download/is-url-1.2.4.tgz", + "integrity": "sha1-BKTfRtKMTP89c9Af8Gq+sxihqlI=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1586796260005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz", + "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.14.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-yaml%2Fdownload%2Fjs-yaml-3.14.0.tgz", + "integrity": "sha1-p6NBcPJqIbsWJCTYray0ETpp5II=", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npm.taobao.org/json-parse-even-better-errors/download/json-parse-even-better-errors-2.3.1.tgz?cache=0&sync_timestamp=1599064788298&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-parse-even-better-errors%2Fdownload%2Fjson-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha1-fEeAWpQxmSjgV3dAXcEuH3pO4C0=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz?cache=0&sync_timestamp=1599333856086&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema-traverse%2Fdownload%2Fjson-schema-traverse-0.4.1.tgz", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/json-stable-stringify-without-jsonify/download/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "10.4.0", + "resolved": "https://registry.npm.taobao.org/lint-staged/download/lint-staged-10.4.0.tgz?cache=0&sync_timestamp=1602914408937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flint-staged%2Fdownload%2Flint-staged-10.4.0.tgz", + "integrity": "sha1-0YYo9zcyjgu7+H0YP0Agkw6amE4=", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.0.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.1.1", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.0.3", + "listr2": "^2.6.0", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-7.0.0.tgz?cache=0&sync_timestamp=1596310819353&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-7.0.0.tgz", + "integrity": "sha1-75tE13OVnK5j3ezRIt4jhTtg+NM=", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "listr2": { + "version": "2.6.2", + "resolved": "https://registry.npm.taobao.org/listr2/download/listr2-2.6.2.tgz", + "integrity": "sha1-SRLrAeHi3XLsN/OJWla/JiLW82o=", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.2", + "through": "^2.3.8" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz", + "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz?cache=0&sync_timestamp=1597335994883&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", + "dev": true + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/log-symbols/download/log-symbols-4.0.0.tgz?cache=0&sync_timestamp=1587898912367&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flog-symbols%2Fdownload%2Flog-symbols-4.0.0.tgz", + "integrity": "sha1-abPMRtIPRI7M23XqH6cz2eghySA=", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/log-update/download/log-update-4.0.0.tgz?cache=0&sync_timestamp=1582186170811&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flog-update%2Fdownload%2Flog-update-4.0.0.tgz", + "integrity": "sha1-WJ7NNSRx8qHAxXAodUOmTf0g4KE=", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-2.0.0.tgz", + "integrity": "sha1-SDFDxWeu7UeFdZwIZXhtx319LjE=", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-4.0.0.tgz", + "integrity": "sha1-UA6N0P1VsFgVCGJVsxla3ypF/ms=", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-estraverse-visitors": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/merge-estraverse-visitors/download/merge-estraverse-visitors-1.0.0.tgz", + "integrity": "sha1-65aDOLXe1c7tgs7AMH3sui2OqZQ=", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz", + "integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npm.taobao.org/merge2/download/merge2-1.4.1.tgz?cache=0&sync_timestamp=1591170027156&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmerge2%2Fdownload%2Fmerge2-1.4.1.tgz", + "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz", + "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1590596706367&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.44.0.tgz?cache=0&sync_timestamp=1600831210195&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.44.0.tgz", + "integrity": "sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I=" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.27.tgz", + "integrity": "sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8=", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-2.1.0.tgz?cache=0&sync_timestamp=1596095644798&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmimic-fn%2Fdownload%2Fmimic-fn-2.1.0.tgz", + "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.5.tgz?cache=0&sync_timestamp=1587535418745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.5.tgz", + "integrity": "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8=", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "8.2.0", + "resolved": "https://registry.npm.taobao.org/mocha/download/mocha-8.2.0.tgz?cache=0&sync_timestamp=1602881142408&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmocha%2Fdownload%2Fmocha-8.2.0.tgz", + "integrity": "sha1-+Kp5EQtLWmWAxl1N2Ag8QlKCYk4=", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-4.0.0.tgz", + "integrity": "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-5.0.0.tgz?cache=0&sync_timestamp=1597169842138&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-5.0.0.tgz", + "integrity": "sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz", + "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-6.0.0.tgz", + "integrity": "sha1-VTIeswn+u8WcSAHZMackUqaB0oY=", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-3.0.2.tgz?cache=0&sync_timestamp=1594559734248&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-3.0.2.tgz", + "integrity": "sha1-FmTgEK88rcaBuq/T4qQ3vnsPtf4=", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-5.0.0.tgz", + "integrity": "sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611709087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz", + "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multi-stage-sourcemap": { + "version": "0.2.1", + "resolved": "https://registry.npm.taobao.org/multi-stage-sourcemap/download/multi-stage-sourcemap-0.2.1.tgz", + "integrity": "sha1-sJ/IWG6qF/gdV1xK0C4Pej9rEQU=", + "dev": true, + "requires": { + "source-map": "^0.1.34" + }, + "dependencies": { + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.1.43.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npm.taobao.org/nanoid/download/nanoid-3.1.12.tgz?cache=0&sync_timestamp=1603419433040&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnanoid%2Fdownload%2Fnanoid-3.1.12.tgz", + "integrity": "sha1-b3c2xi6NOUIWAeSgx3YjqX6mllQ=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz", + "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=" + }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npm.taobao.org/netmask/download/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/next-tick/download/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz", + "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz", + "integrity": "sha1-t+zR5e1T2o43pV4cImnguX7XSOo=", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npm.taobao.org/object-inspect/download/object-inspect-1.8.0.tgz?cache=0&sync_timestamp=1592545231350&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-inspect%2Fdownload%2Fobject-inspect-1.8.0.tgz", + "integrity": "sha1-34B+Xs9TpgnMa/6T6sPMe+WzqdA=", + "dev": true + }, + "object-is": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/object-is/download/object-is-1.1.3.tgz?cache=0&sync_timestamp=1601502788762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-is%2Fdownload%2Fobject-is-1.1.3.tgz", + "integrity": "sha1-LjueZVYBN0Ve471irsTZCi6hzIE=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz", + "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", + "dev": true + }, + "object.assign": { + "version": "4.1.1", + "resolved": "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.1.tgz?cache=0&sync_timestamp=1599844927493&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.assign%2Fdownload%2Fobject.assign-4.1.1.tgz", + "integrity": "sha1-MDhnpmbN1Bk27N7fsfjz4ypHjN0=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz?cache=0&sync_timestamp=1597005345612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fonetime%2Fdownload%2Fonetime-5.1.2.tgz", + "integrity": "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/opencollective-postinstall/download/opencollective-postinstall-2.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopencollective-postinstall%2Fdownload%2Fopencollective-postinstall-2.0.3.tgz", + "integrity": "sha1-eg//l49tv6TQBiOPusmO1BmMMlk=", + "dev": true + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.8.3.tgz", + "integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz?cache=0&sync_timestamp=1594559734248&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-2.3.0.tgz", + "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz", + "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/p-map/download/p-map-4.0.0.tgz", + "integrity": "sha1-uy+Vpe2i7BaOySdOBqdHw+KQTSs=", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz", + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", + "dev": true + }, + "pac-proxy-agent": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/pac-proxy-agent/download/pac-proxy-agent-4.1.0.tgz", + "integrity": "sha1-Zog+6rrckV/F6VRXMkyw8Kx43vs=", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^4.1.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "pac-resolver": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/pac-resolver/download/pac-resolver-4.1.0.tgz?cache=0&sync_timestamp=1581134452130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpac-resolver%2Fdownload%2Fpac-resolver-4.1.0.tgz", + "integrity": "sha1-SxLn0JayVaO4TlP2gx8y6cfl/pU=", + "requires": { + "degenerator": "^2.2.0", + "ip": "^1.1.5", + "netmask": "^1.0.6" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/parent-module/download/parent-module-1.0.1.tgz", + "integrity": "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI=", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-5.1.0.tgz?cache=0&sync_timestamp=1598129182781&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-5.1.0.tgz", + "integrity": "sha1-+WCIzfJKj6qa6poAny2dlCyZlkY=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz", + "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz", + "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz", + "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz", + "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npm.taobao.org/picomatch/download/picomatch-2.2.2.tgz?cache=0&sync_timestamp=1584790434095&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpicomatch%2Fdownload%2Fpicomatch-2.2.2.tgz", + "integrity": "sha1-IfMz6ba46v8CRo9RRupAbTRfTa0=", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz?cache=0&sync_timestamp=1602859045787&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-4.2.0.tgz", + "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npm.taobao.org/please-upgrade-node/download/please-upgrade-node-3.2.0.tgz", + "integrity": "sha1-rt3T+ZTJM+StmLmdmlVu+g4v6UI=", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "power-assert": { + "version": "1.6.1", + "resolved": "https://registry.npm.taobao.org/power-assert/download/power-assert-1.6.1.tgz", + "integrity": "sha1-soy8Aq6Aiv0UMdDNUJOjmsWlsf4=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "empower": "^1.3.1", + "power-assert-formatter": "^1.4.1", + "universal-deep-strict-equal": "^1.2.1", + "xtend": "^4.0.0" + } + }, + "power-assert-context-formatter": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-context-formatter/download/power-assert-context-formatter-1.2.0.tgz", + "integrity": "sha1-j75yaSKI7FpyA83yFci4OKYGHSo=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "power-assert-context-traversal": "^1.2.0" + } + }, + "power-assert-context-reducer-ast": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-context-reducer-ast/download/power-assert-context-reducer-ast-1.2.0.tgz", + "integrity": "sha1-x8ocnjmm+3F/esX+nnbhkr9SXfM=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "acorn-es7-plugin": "^1.0.12", + "core-js": "^2.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.2.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-5.7.4.tgz", + "integrity": "sha1-Po2KmUfQWZoXltECJddDL0pKz14=", + "dev": true + } + } + }, + "power-assert-context-traversal": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-context-traversal/download/power-assert-context-traversal-1.2.0.tgz", + "integrity": "sha1-9ucUVLr2QN5cHJwnA0n1yasLLpQ=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "estraverse": "^4.1.0" + } + }, + "power-assert-formatter": { + "version": "1.4.1", + "resolved": "https://registry.npm.taobao.org/power-assert-formatter/download/power-assert-formatter-1.4.1.tgz", + "integrity": "sha1-XcEl7VCj37HdomwZNH879Y7CiEo=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "power-assert-context-formatter": "^1.0.7", + "power-assert-context-reducer-ast": "^1.0.7", + "power-assert-renderer-assertion": "^1.0.7", + "power-assert-renderer-comparison": "^1.0.7", + "power-assert-renderer-diagram": "^1.0.7", + "power-assert-renderer-file": "^1.0.7" + } + }, + "power-assert-renderer-assertion": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-assertion/download/power-assert-renderer-assertion-1.2.0.tgz", + "integrity": "sha1-Pbb/zaEGs3vB4GQyrQ10imgrFHo=", + "dev": true, + "requires": { + "power-assert-renderer-base": "^1.1.1", + "power-assert-util-string-width": "^1.2.0" + } + }, + "power-assert-renderer-base": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-base/download/power-assert-renderer-base-1.1.1.tgz", + "integrity": "sha1-lqZQxv0F7hvB9mtUrWFELIs/Y+s=", + "dev": true + }, + "power-assert-renderer-comparison": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-comparison/download/power-assert-renderer-comparison-1.2.0.tgz", + "integrity": "sha1-5PiBEyJaab6KpYbq0FrvmUYsBJU=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "diff-match-patch": "^1.0.0", + "power-assert-renderer-base": "^1.1.1", + "stringifier": "^1.3.0", + "type-name": "^2.0.1" + } + }, + "power-assert-renderer-diagram": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-diagram/download/power-assert-renderer-diagram-1.2.0.tgz", + "integrity": "sha1-N/ZuhULlZ3xbWObXKwHA2aMOIhk=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "power-assert-renderer-base": "^1.1.1", + "power-assert-util-string-width": "^1.2.0", + "stringifier": "^1.3.0" + } + }, + "power-assert-renderer-file": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-file/download/power-assert-renderer-file-1.2.0.tgz", + "integrity": "sha1-P0vr2eFFXXXPKsVB57tRWofUzks=", + "dev": true, + "requires": { + "power-assert-renderer-base": "^1.1.1" + } + }, + "power-assert-util-string-width": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-util-string-width/download/power-assert-util-string-width-1.2.0.tgz", + "integrity": "sha1-bgbV41gbuHbF03fFMQn/+pW9kaA=", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prettier": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/prettier/download/prettier-2.1.2.tgz?cache=0&sync_timestamp=1600215482255&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.2.tgz", + "integrity": "sha1-MFBwDa4uTItnxMP2Zs24r0BeHOU=", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/prettier-linter-helpers/download/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha1-0j1B/hN1ZG3i0BBNNFSjAIgCz3s=", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz", + "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.6.tgz", + "integrity": "sha1-/cIzZQVEfT8vLGOO0nLK9hS7sr8=", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/pump/download/pump-3.0.0.tgz", + "integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz", + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz", + "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz", + "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz", + "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz", + "integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-1.1.14.tgz?cache=0&sync_timestamp=1581624324274&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npm.taobao.org/readdirp/download/readdirp-3.5.0.tgz?cache=0&sync_timestamp=1602584331621&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freaddirp%2Fdownload%2Freaddirp-3.5.0.tgz", + "integrity": "sha1-m6dMAZsV02UnjS6Ru4xI17TULJ4=", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npm.taobao.org/regexp.prototype.flags/download/regexp.prototype.flags-1.3.0.tgz?cache=0&sync_timestamp=1576388141321&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexp.prototype.flags%2Fdownload%2Fregexp.prototype.flags-1.3.0.tgz", + "integrity": "sha1-erqJs8E6ZFCdq888qNn7ub31y3U=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.17.7.tgz?cache=0&sync_timestamp=1601502719982&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.7.tgz", + "integrity": "sha1-pN5hsvZpifx0IWdsHLl4dXOs5Uw=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/regexpp/download/regexpp-3.1.0.tgz", + "integrity": "sha1-IG0K0KVkjP+9uK5GQ489xRyfeOI=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-2.0.0.tgz", + "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz", + "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/restore-cursor/download/restore-cursor-3.1.0.tgz", + "integrity": "sha1-OfZ8VLOnpYzqUjbZXPADQjljH34=", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/reusify/download/reusify-1.0.4.tgz", + "integrity": "sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY=", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.6.3.tgz", + "integrity": "sha1-stEE/g2Psnz54KHNqCYt04M8bKs=", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npm.taobao.org/run-parallel/download/run-parallel-1.1.9.tgz", + "integrity": "sha1-yd06fPn0ssS2JE4XOm7YZuYd1nk=", + "dev": true + }, + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npm.taobao.org/rxjs/download/rxjs-6.6.3.tgz?cache=0&sync_timestamp=1602770834162&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.3.tgz", + "integrity": "sha1-jKhGNcTaqQDA05Z6buesYCce5VI=", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=", + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npm.taobao.org/semver/download/semver-7.3.2.tgz", + "integrity": "sha1-YElisFK4HtB4aq6EOJ/7pw/9OTg=", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/semver-compare/download/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/semver-regex/download/semver-regex-2.0.0.tgz", + "integrity": "sha1-qTwsWERTmncCMzeRB7OMe0rJ0zg=", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz", + "integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz", + "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=" + } + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-5.0.1.tgz?cache=0&sync_timestamp=1599740650381&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-5.0.1.tgz", + "integrity": "sha1-eIbshIBJpGJGepfT2Rjrsqr5NPQ=", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz", + "integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz", + "integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM=" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz", + "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz", + "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz", + "integrity": "sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz", + "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz", + "integrity": "sha1-ys12k0YaY3pXiNkqfdT7oGjoFjY=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/smart-buffer/download/smart-buffer-4.1.0.tgz", + "integrity": "sha1-kWBcJdkWUvRmHqacz0XxszHKIbo=" + }, + "socks": { + "version": "2.4.4", + "resolved": "https://registry.npm.taobao.org/socks/download/socks-2.4.4.tgz?cache=0&sync_timestamp=1599605506578&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocks%2Fdownload%2Fsocks-2.4.4.tgz", + "integrity": "sha1-8aM4LngUrijJe7gqOLwawkshzKI=", + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/socks-proxy-agent/download/socks-proxy-agent-5.0.0.tgz?cache=0&sync_timestamp=1580845554635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocks-proxy-agent%2Fdownload%2Fsocks-proxy-agent-5.0.0.tgz", + "integrity": "sha1-fA82Tnsc9KekN+cSU77XLpAEvmA=", + "requires": { + "agent-base": "6", + "debug": "4", + "socks": "^2.3.3" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "optional": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.4.18.tgz?cache=0&sync_timestamp=1587719289626&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.4.18.tgz", + "integrity": "sha1-Aoam3ovkJkEzhZTpfM6nXwosWF8=", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz?cache=0&sync_timestamp=1587327902535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstatuses%2Fdownload%2Fstatuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npm.taobao.org/streamsearch/download/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npm.taobao.org/string-argv/download/string-argv-0.3.1.tgz", + "integrity": "sha1-leL77AQnrhkYSTX4FtdKqkxcGdo=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/string.prototype.trimend/download/string.prototype.trimend-1.0.2.tgz?cache=0&sync_timestamp=1603219618123&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimend%2Fdownload%2Fstring.prototype.trimend-1.0.2.tgz", + "integrity": "sha1-bd2ah5a8cUtImjriIkaiCPN7+kY=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/string.prototype.trimstart/download/string.prototype.trimstart-1.0.2.tgz?cache=0&sync_timestamp=1603219618047&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimstart%2Fdownload%2Fstring.prototype.trimstart-1.0.2.tgz", + "integrity": "sha1-ItRdqBAVMJzQzdeXh+iRn8XGE+c=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringifier": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/stringifier/download/stringifier-1.4.0.tgz", + "integrity": "sha1-1wRYFWf0UmJl0A7Y7LNUoCw/7Cg=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "traverse": "^0.6.6", + "type-name": "^2.0.1" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npm.taobao.org/stringify-object/download/stringify-object-3.3.0.tgz", + "integrity": "sha1-cDBlrvyhkwDTzoivT1s5VtdVZik=", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.0.tgz", + "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/strip-comments/download/strip-comments-2.0.1.tgz", + "integrity": "sha1-StEcP7ysF3pnpArCJMoznKHBups=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/strip-final-newline/download/strip-final-newline-2.0.0.tgz", + "integrity": "sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-3.1.1.tgz?cache=0&sync_timestamp=1594567532500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-json-comments%2Fdownload%2Fstrip-json-comments-3.1.1.tgz", + "integrity": "sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611709087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npm.taobao.org/table/download/table-5.4.6.tgz", + "integrity": "sha1-EpLRlQDOP4YFOwXw6Ofko7shB54=", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz", + "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=" + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npm.taobao.org/traverse/download/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-2.0.3.tgz", + "integrity": "sha1-jgdBrEX8DCJuWKF7/D5kubxsphw=" + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npm.taobao.org/tsutils/download/tsutils-3.17.1.tgz", + "integrity": "sha1-7XGZF/EcoN7lhicrKsSeAVot11k=", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=", + "dev": true + } + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npm.taobao.org/tunnel/download/tunnel-0.0.6.tgz", + "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/type/download/type-1.2.0.tgz?cache=0&sync_timestamp=1598016585110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype%2Fdownload%2Ftype-1.2.0.tgz", + "integrity": "sha1-hI3XaY2vo+VKbEeedZxLw/GIR6A=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz", + "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "type-name": { + "version": "2.0.2", + "resolved": "https://registry.npm.taobao.org/type-name/download/type-name-2.0.2.tgz", + "integrity": "sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q=", + "dev": true + }, + "typescript": { + "version": "4.0.3", + "resolved": "https://registry.npm.taobao.org/typescript/download/typescript-4.0.3.tgz?cache=0&sync_timestamp=1603608626888&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-4.0.3.tgz", + "integrity": "sha1-FTu9Ro7wdyXB35x36LRT+NNqu6U=", + "dev": true + }, + "universal-deep-strict-equal": { + "version": "1.2.2", + "resolved": "https://registry.npm.taobao.org/universal-deep-strict-equal/download/universal-deep-strict-equal-1.2.2.tgz", + "integrity": "sha1-DaSsL3PP95JMgfpN4BjKViyisKc=", + "dev": true, + "requires": { + "array-filter": "^1.0.0", + "indexof": "0.0.1", + "object-keys": "^1.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz?cache=0&sync_timestamp=1603179967633&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npm.taobao.org/uri-js/download/uri-js-4.4.0.tgz?cache=0&sync_timestamp=1598814377097&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furi-js%2Fdownload%2Furi-js-4.4.0.tgz", + "integrity": "sha1-qnFCYd55PoqCNHp7zJznTobyhgI=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.1.1.tgz", + "integrity": "sha1-VLw83UMxe8qR413K8wWxpyN950U=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz", + "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/which-pm-runs/download/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/wide-align/download/wide-align-1.1.3.tgz", + "integrity": "sha1-rgdOa9wMFKQx6ATmJFScYzsABFc=", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-2.1.1.tgz", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz", + "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=" + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npm.taobao.org/workerpool/download/workerpool-6.0.2.tgz", + "integrity": "sha1-4kG0PY0DPxvrUseFEGlFYDnR1Dg=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-6.2.0.tgz", + "integrity": "sha1-6Tk7oHEC5skaOyIUePAlfNKFblM=", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1603212180491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz", + "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz", + "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/write/download/write-1.0.3.tgz", + "integrity": "sha1-CADhRSO5I6OH5BUSPIZWFqrg9cM=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/xregexp/download/xregexp-2.0.0.tgz?cache=0&sync_timestamp=1581429204252&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxregexp%2Fdownload%2Fxregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz", + "integrity": "sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/y18n/download/y18n-4.0.0.tgz", + "integrity": "sha1-le+U+F7MgdAHwmThkKEg8KPIVms=", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npm.taobao.org/yaml/download/yaml-1.10.0.tgz", + "integrity": "sha1-O1k63ZRIdgd9TWg/7gEIG9n/8x4=", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npm.taobao.org/yargs/download/yargs-13.3.2.tgz?cache=0&sync_timestamp=1602805561021&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-13.3.2.tgz", + "integrity": "sha1-rX/+/sGqWVZayRX4Lcyzipwxot0=", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz?cache=0&sync_timestamp=1597169842138&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz", + "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz", + "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz", + "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-13.1.2.tgz?cache=0&sync_timestamp=1602861397132&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-13.1.2.tgz", + "integrity": "sha1-Ew8JcC667vJlDVTObj5XBvek+zg=", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/yargs-unparser/download/yargs-unparser-2.0.0.tgz", + "integrity": "sha1-8TH5ImkRrl2a04xDL+gJNmwjJes=", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.1.0", + "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-6.1.0.tgz?cache=0&sync_timestamp=1602350083472&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-6.1.0.tgz", + "integrity": "sha1-J9wXYXNyX7Ct+KSLZH9NeHGUTXg=", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/decamelize/download/decamelize-4.0.0.tgz", + "integrity": "sha1-qkcte/Zg6xXzSU79UxyrfypwmDc=", + "dev": true + } + } + } + } +} diff --git a/napi/package.json b/napi/package.json new file mode 100644 index 0000000..997c80b --- /dev/null +++ b/napi/package.json @@ -0,0 +1,67 @@ +{ + "name": "NeteaseCloudMusicApi", + "version": "3.45.2", + "description": "网易云音乐 NodeJS 版 API", + "scripts": { + "start": "node app.js", + "test": "mocha -r intelli-espower-loader -t 20000 app.test.js --exit", + "lint": "eslint **/*.{js,ts}", + "lint-fix": "eslint --fix **/*.{js,ts}" + }, + "keywords": [ + "网易云音乐", + "网易云", + "音乐", + "网易云音乐nodejs" + ], + "main": "main.js", + "types": "./interface.d.ts", + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "engines": { + "node": ">=12" + }, + "lint-staged": { + "*.js": [ + "eslint --fix", + "git add" + ] + }, + "author": "binaryify", + "license": "MIT", + "files": [ + "module", + "util", + "plugins", + "main.d.ts", + "interface.d.ts", + "module_types" + ], + "dependencies": { + "axios": "^0.20.0", + "express": "^4.17.1", + "express-fileupload": "^1.1.9", + "pac-proxy-agent": "^4.0.0", + "strip-comments": "^2.0.1", + "tunnel": "^0.0.6" + }, + "devDependencies": { + "@types/node": "14.11.10", + "@typescript-eslint/eslint-plugin": "4.4.1", + "@typescript-eslint/parser": "4.4.1", + "eslint": "7.12.0", + "eslint-config-prettier": "6.13.0", + "eslint-plugin-html": "6.0.3", + "eslint-plugin-prettier": "3.1.4", + "husky": "4.2.5", + "intelli-espower-loader": "1.0.1", + "lint-staged": "10.4.0", + "mocha": "8.2.0", + "power-assert": "1.6.1", + "prettier": "2.1.2", + "typescript": "4.0.3" + } +} diff --git a/napi/plugins/upload.js b/napi/plugins/upload.js new file mode 100644 index 0000000..f572759 --- /dev/null +++ b/napi/plugins/upload.js @@ -0,0 +1,48 @@ +const axios = require('axios'); +module.exports = async (query, request) => { + const data = { + bucket: 'yyimgs', + ext: 'jpg', + filename: query.imgFile.name, + local: false, + nos_product: 0, + return_body: `{"code":200,"size":"$(ObjectSize)"}`, + type: 'other', + }; + // 获取key和token + const res = await request( + 'POST', + `https://music.163.com/weapi/nos/token/alloc`, + data, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ); + // 上传图片 + const res2 = await axios({ + method: 'post', + url: `https://nosup-hz1.127.net/yyimgs/${res.body.result.objectKey}?offset=0&complete=true&version=1.0`, + headers: { + 'x-nos-token': res.body.result.token, + 'Content-Type': 'image/jpeg', + }, + data: query.imgFile.data, + }); + // 获取裁剪后图片的id + const imgSize = query.imgSize || 300; + const imgX = query.imgX || 0; + const imgY = query.imgY || 0; + const res3 = await request( + 'POST', + `https://music.163.com/upload/img/op?id=${res.body.result.docId}&op=${imgX}y${imgY}y${imgSize}y${imgSize}`, + {}, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ); + + return { + // ...res.body.result, + // ...res2.data, + // ...res3.body, + url_pre: 'https://p1.music.126.net/' + res.body.result.objectKey, + url: res3.body.url, + imgId: res3.body.id, + }; +}; diff --git a/napi/public/avatar_update.html b/napi/public/avatar_update.html new file mode 100644 index 0000000..41dd8e9 --- /dev/null +++ b/napi/public/avatar_update.html @@ -0,0 +1,82 @@ + + + + + + 更新头像 + + + + + + + + + diff --git a/napi/public/index.html b/napi/public/index.html new file mode 100644 index 0000000..21c33b6 --- /dev/null +++ b/napi/public/index.html @@ -0,0 +1,56 @@ + + + + + + + 网易云音乐 API + + + +

网易云音乐 API

+ 当你看到这个页面时,这个服务已经成功跑起来了~ +
查看文档 +

例子:

+ + + + diff --git a/napi/public/playlist_cover_update.html b/napi/public/playlist_cover_update.html new file mode 100644 index 0000000..d09be2c --- /dev/null +++ b/napi/public/playlist_cover_update.html @@ -0,0 +1,91 @@ + + + + + + 歌单封面上传 + + + + + + + + + diff --git a/napi/public/test.html b/napi/public/test.html new file mode 100644 index 0000000..64da33f --- /dev/null +++ b/napi/public/test.html @@ -0,0 +1,61 @@ + + + + + + + test + + + +

请在控制台看结果

+ + + + + diff --git a/napi/renovate.json b/napi/renovate.json new file mode 100644 index 0000000..4f39080 --- /dev/null +++ b/napi/renovate.json @@ -0,0 +1,3 @@ +{ + "extends": ["config:base"] +} diff --git a/napi/routes.js b/napi/routes.js new file mode 100644 index 0000000..ede337b --- /dev/null +++ b/napi/routes.js @@ -0,0 +1,8810 @@ +const { cookieToJson } = require('./util/index'); +const request = require('./util/request'); +module.exports = { + '/yunbei/today': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_today = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/point/today/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_today(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/tasks/todo': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_tasks_todo = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/usertool/task/todo/query`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_tasks_todo(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/tasks': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_tasks = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/usertool/task/list/all`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_tasks(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/task/finish': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_task_finish = (query, request) => { + const data = { + userTaskId: query.userTaskId, + depositCode: query.depositCode || '0', + }; + return request( + 'POST', + `https://music.163.com/api/usertool/task/point/receive`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_task_finish(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/sign': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_sign = (query, request) => { + const data = { type: '0' }; + return request( + 'POST', + `https://music.163.com/api/point/dailyTask`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_sign(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/receipt': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_receipt = (query, request) => { + const data = { limit: query.limit || 10, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/store/api/point/receipt`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_receipt(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/info': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_info = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/api/v1/user/info`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + yunbei_info(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei/expense': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei_expense = (query, request) => { + const data = { limit: query.limit || 10, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/store/api/point/expense`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei_expense(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/yunbei': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const yunbei = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/point/signed/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + yunbei(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/weblog': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const weblog = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/feedback/weblog`, + query.data || {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + weblog(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/url': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_url = (query, request) => { + const data = { + ids: '["' + query.id + '"]', + resolution: query.res || 1080, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/playurl`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_url(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/timeline/recommend': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_timeline_recommend = (query, request) => { + const data = { + offset: query.offset || 0, + filterLives: '[]', + withProgramInfo: 'true', + needUrl: '1', + resolution: '480', + }; + return request( + 'POST', + `https://music.163.com/api/videotimeline/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_timeline_recommend(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/timeline/all': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_timeline_all = (query, request) => { + const data = { + groupId: 0, + offset: query.offset || 0, + need_preview_url: 'true', + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/videotimeline/otherclient/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_timeline_all(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/sub': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_sub = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/video/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_sub(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/group/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_group_list = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/cloudvideo/group/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_group_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/group': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_group = (query, request) => { + const data = { + groupId: query.id, + offset: query.offset || 0, + need_preview_url: 'true', + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/videotimeline/videogroup/otherclient/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_group(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/detail/info': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_detail_info = (query, request) => { + const data = { threadid: `R_VI_62_${query.vid}`, composeliked: true }; + return request( + 'POST', + `https://music.163.com/api/comment/commentthread/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_detail_info(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_detail = (query, request) => { + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/v1/video/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/video/category/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const video_category_list = (query, request) => { + const data = { + offset: query.offset || 0, + total: 'true', + limit: query.limit || 99, + }; + return request( + 'POST', + `https://music.163.com/api/cloudvideo/category/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + video_category_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_update = (query, request) => { + const data = { + avatarImgId: '0', + birthday: query.birthday, + city: query.city, + gender: query.gender, + nickname: query.nickname, + province: query.province, + signature: query.signature, + }; + return request( + 'POST', + `https://music.163.com/weapi/user/profile/update`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/subcount': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_subcount = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/subcount`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_subcount(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/replacephone': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_replacephone = (query, request) => { + const data = { + phone: query.phone, + captcha: query.captcha, + oldcaptcha: query.oldcaptcha, + countrycode: query.countrycode || '86', + }; + return request( + 'POST', + `https://music.163.com/api/user/replaceCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_replacephone(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/record': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_record = (query, request) => { + const data = { uid: query.uid, type: query.type || 0 }; + return request( + 'POST', + `https://music.163.com/weapi/v1/play/record`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_record(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/playlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_playlist = (query, request) => { + const data = { + uid: query.uid, + limit: query.limit || 30, + offset: query.offset || 0, + includeVideo: true, + }; + return request('POST', `https://music.163.com/api/user/playlist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + user_playlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/level': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_level = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/weapi/user/level`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + user_level(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/follows': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_follows = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + order: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/user/getfollows/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_follows(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/followeds': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_followeds = (query, request) => { + const data = { + userId: query.uid, + time: query.lasttime || -1, + limit: query.limit || 30, + }; + return request( + 'POST', + `https://music.163.com/eapi/user/getfolloweds/${query.uid}`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/user/getfolloweds', + realIP: query.realIP, + }, + ); + }; + user_followeds(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/event': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_event = (query, request) => { + const data = { + getcounts: true, + time: query.lasttime || -1, + limit: query.limit || 30, + total: false, + }; + return request( + 'POST', + `https://music.163.com/weapi/event/get/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_event(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/dj': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_dj = (query, request) => { + const data = { limit: query.limit || 30, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/weapi/dj/program/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_dj(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_detail = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/user/detail/${query.uid}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/cloud/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_cloud_detail = (query, request) => { + const id = query.id.replace(/\s/g, '').split(','); + const data = { songIds: id }; + return request( + 'POST', + `https://music.163.com/weapi/v1/cloud/get/byids`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_cloud_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/cloud/del': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_cloud_del = (query, request) => { + const data = { songIds: [query.id] }; + return request('POST', `https://music.163.com/weapi/cloud/del`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + user_cloud_del(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/cloud': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_cloud = (query, request) => { + const data = { limit: query.limit || 30, offset: query.offset || 0 }; + return request('POST', `https://music.163.com/weapi/v1/cloud/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + user_cloud(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/binding': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_binding = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/v1/user/bindings/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_binding(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/audio': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_audio = (query, request) => { + const data = { userId: query.uid }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/get/byuser`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_audio(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/user/account': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const user_account = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/nuser/account/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + user_account(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/toplist/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const toplist_detail = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/toplist/detail`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + toplist_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/toplist/artist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const toplist_artist = (query, request) => { + const data = { + type: query.type || 1, + limit: 100, + offset: 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/toplist/artist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + toplist_artist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/toplist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const toplist = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/toplist`, + {}, + { + crypto: 'linuxapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + toplist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/song': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_song = (query, request) => { + const data = { areaId: query.type || 0, total: true }; + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/new/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + top_song(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/playlist/highquality': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_playlist_highquality = (query, request) => { + const data = { + cat: query.cat || '全部', + limit: query.limit || 50, + lasttime: query.before || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/playlist/highquality/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + top_playlist_highquality(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/playlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_playlist = (query, request) => { + const data = { + cat: query.cat || '全部', + order: query.order || 'hot', + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/playlist/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + top_playlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/mv': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_mv = (query, request) => { + const data = { + area: query.area || '', + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/mv/toplist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + top_mv(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_list = (query, request) => { + query.cookie.os = 'pc'; + if (query.idx) { + return Promise.resolve({ + status: 500, + body: { code: 500, msg: '不支持此方式调用,只支持id调用' }, + }); + } + const data = { id: query.id, n: '500', s: '0' }; + return request( + 'POST', + `https://interface3.music.163.com/api/playlist/v4/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + top_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/artists': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_artists = (query, request) => { + const data = { + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + }; + return request('POST', `https://music.163.com/weapi/artist/top`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + top_artists(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/top/album': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const top_album = (query, request) => { + const date = new Date(); + const data = { + area: query.area || 'ALL', + limit: query.limit || 50, + offset: query.offset || 0, + type: query.type || 'new', + year: query.year || date.getFullYear(), + month: query.month || date.getMonth() + 1, + total: false, + rcmd: true, + }; + return request( + 'POST', + `https://music.163.com/api/discovery/new/albums/area`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + top_album(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/song/url': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const song_url = (query, request) => { + if (!('MUSIC_U' in query.cookie)) + query.cookie._ntes_nuid = crypto.randomBytes(16).toString('hex'); + query.cookie.os = 'pc'; + const data = { + ids: '[' + query.id + ']', + br: parseInt(query.br || 999000), + }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/song/enhance/player/url`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/enhance/player/url', + }, + ); + }; + song_url(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/song/order/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const song_order_update = (query, request) => { + const data = { pid: query.pid, trackIds: query.ids, op: 'update' }; + return request( + 'POST', + `http://interface.music.163.com/api/playlist/manipulate/tracks`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/desc/update', + realIP: query.realIP, + }, + ); + }; + song_order_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/song/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const song_detail = (query, request) => { + query.ids = query.ids.split(/\s*,\s*/); + const data = { + c: '[' + query.ids.map((id) => '{"id":' + id + '}').join(',') + ']', + ids: '[' + query.ids.join(',') + ']', + }; + return request( + 'POST', + `https://music.163.com/weapi/v3/song/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + song_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/simi/user': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const simi_user = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiUser`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + simi_user(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/simi/song': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const simi_song = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/simiSong`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + simi_song(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/simi/playlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const simi_playlist = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiPlaylist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + simi_playlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/simi/mv': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const simi_mv = (query, request) => { + const data = { mvid: query.mvid }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiMV`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + simi_mv(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/simi/artist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const simi_artist = (query, request) => { + const data = { artistid: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiArtist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + simi_artist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/share/resource': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const share_resource = (query, request) => { + const data = { + type: query.type || 'song', + msg: query.msg || '', + id: query.id || '', + }; + return request( + 'POST', + `https://music.163.com/weapi/share/friends/resource`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + share_resource(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/setting': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const setting = (query, request) => { + const data = {}; + return request('POST', `https://music.163.com/api/user/setting`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + setting(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/send/text': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const send_text = (query, request) => { + query.cookie.os = 'pc'; + const data = { + type: 'text', + msg: query.msg, + userIds: '[' + query.user_ids + ']', + }; + return request( + 'POST', + `https://music.163.com/weapi/msg/private/send`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + send_text(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/send/playlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const send_playlist = (query, request) => { + query.cookie.os = 'pc'; + const data = { + id: query.playlist, + type: 'playlist', + msg: query.msg, + userIds: '[' + query.user_ids + ']', + }; + return request( + 'POST', + `https://music.163.com/weapi/msg/private/send`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + send_playlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/search/suggest': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const search_suggest = (query, request) => { + const data = { s: query.keywords || '' }; + let type = query.type == 'mobile' ? 'keyword' : 'web'; + return request( + 'POST', + `https://music.163.com/weapi/search/suggest/` + type, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + search_suggest(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/search/multimatch': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const search_multimatch = (query, request) => { + const data = { type: query.type || 1, s: query.keywords || '' }; + return request( + 'POST', + `https://music.163.com/weapi/search/suggest/multimatch`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + search_multimatch(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/search/hot/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const search_hot_detail = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/weapi/hotsearchlist/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + search_hot_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/search/hot': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const search_hot = (query, request) => { + const data = { type: 1111 }; + return request('POST', `https://music.163.com/weapi/search/hot`, data, { + crypto: 'weapi', + ua: 'mobile', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + search_hot(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/search/default': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const search_default = (query, request) => { + return request( + 'POST', + `https://interface3.music.163.com/eapi/search/defaultkeyword/get`, + {}, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/search/defaultkeyword/get', + realIP: query.realIP, + }, + ); + }; + search_default(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/search': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const search = (query, request) => { + const data = { + s: query.keywords, + type: query.type || 1, + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/weapi/search/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + search(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/scrobble': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const scrobble = (query, request) => { + const data = { + logs: JSON.stringify([ + { + action: 'play', + json: { + download: 0, + end: 'playend', + id: query.id, + sourceId: query.sourceid, + time: query.time, + type: 'song', + wifi: 0, + }, + }, + ]), + }; + return request( + 'POST', + `https://music.163.com/weapi/feedback/weblog`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + scrobble(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/resource/like': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const resource_like = (query, request) => { + query.cookie.os = 'pc'; + query.t = query.t == 1 ? 'like' : 'unlike'; + query.type = { 1: 'R_MV_5_', 4: 'A_DJ_1_', 5: 'R_VI_62_', 6: 'A_EV_2_' }[ + query.type + ]; + const data = { threadId: query.type + query.id }; + if (query.type === 'A_EV_2_') { + data.threadId = query.threadId; + } + return request( + 'POST', + `https://music.163.com/weapi/resource/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + resource_like(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/related/allvideo': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const related_allvideo = (query, request) => { + const data = { id: query.id, type: /^\\d+$/.test(query.id) ? 0 : 1 }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/v1/allvideo/rcmd`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + related_allvideo(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/register/cellphone': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const register_cellphone = (query, request) => { + query.cookie.os = 'pc'; + const data = { + captcha: query.captcha, + phone: query.phone, + password: crypto.createHash('md5').update(query.password).digest('hex'), + nickname: query.nickname, + }; + return request( + 'POST', + `https://music.163.com/api/register/cellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + register_cellphone(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/recommend/songs': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const recommend_songs = (query, request) => { + query.cookie.os = 'ios'; + const data = {}; + return request( + 'POST', + `https://music.163.com/api/v3/discovery/recommend/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + recommend_songs(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/recommend/resource': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const recommend_resource = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/recommend/resource`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + recommend_resource(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/rebind': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const rebind = (query, request) => { + const data = { + captcha: query.captcha, + phone: query.phone, + oldcaptcha: query.oldcaptcha, + ctcode: query.ctcode || '86', + }; + return request( + 'POST', + `https://music.163.com/api/user/replaceCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + rebind(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/program/recommend': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const program_recommend = (query, request) => { + const data = { + cateId: query.type, + limit: query.limit || 10, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/program/recommend/v1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + program_recommend(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playmode/intelligence/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playmode_intelligence_list = (query, request) => { + const data = { + songId: query.id, + type: 'fromPlayOne', + playlistId: query.pid, + startMusicId: query.sid || query.id, + count: query.count || 1, + }; + return request( + 'POST', + `https://music.163.com/weapi/playmode/intelligence/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playmode_intelligence_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/video/recent': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_video_recent = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/playlist/video/recent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_video_recent(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_update = (query, request) => { + query.cookie.os = 'pc'; + query.desc = query.desc || ''; + query.tags = query.tags || ''; + const data = { + '/api/playlist/desc/update': `{\"id\":${query.id},\"desc\":\"${query.desc}\"}`, + '/api/playlist/tags/update': `{\"id\":${query.id},\"tags\":\"${query.tags}\"}`, + '/api/playlist/update/name': `{\"id\":${query.id},\"name\":\"${query.name}\"}`, + }; + return request('POST', `https://music.163.com/weapi/batch`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + playlist_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/tracks': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_tracks = async (query, request) => { + query.cookie.os = 'pc'; + const tracks = query.tracks.split(','); + const data = { + op: query.op, + pid: query.pid, + trackIds: JSON.stringify(tracks), + imme: 'true', + }; + try { + const res = await request( + 'POST', + `https://music.163.com/api/playlist/manipulate/tracks`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + return { status: 200, body: { ...res } }; + } catch (error) { + if (error.body.code === 512) { + return request( + 'POST', + `https://music.163.com/api/playlist/manipulate/tracks`, + { + op: query.op, + pid: query.pid, + trackIds: JSON.stringify([...tracks, ...tracks]), + imme: 'true', + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + } + } + }; + playlist_tracks(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/track/delete': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_track_delete = async (query, request) => { + query.cookie.os = 'pc'; + query.ids = query.ids || ''; + const data = { + id: query.id, + tracks: JSON.stringify( + query.ids.split(',').map((item) => { + return { type: 3, id: item }; + }), + ), + }; + return request( + 'POST', + `https://music.163.com/api/playlist/track/delete`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_track_delete(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/track/add': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_track_add = async (query, request) => { + query.cookie.os = 'pc'; + query.ids = query.ids || ''; + const data = { + id: query.pid, + tracks: JSON.stringify( + query.ids.split(',').map((item) => { + return { type: 3, id: item }; + }), + ), + }; + console.log(data); + return request( + 'POST', + `https://music.163.com/api/playlist/track/add`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_track_add(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/tags/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_tags_update = (query, request) => { + const data = { id: query.id, tags: query.tags }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/tags/update`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/tags/update', + realIP: query.realIP, + }, + ); + }; + playlist_tags_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/subscribers': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_subscribers = (query, request) => { + const data = { + id: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/playlist/subscribers`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_subscribers(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/subscribe': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_subscribe = (query, request) => { + query.t = query.t == 1 ? 'subscribe' : 'unsubscribe'; + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/playlist/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_subscribe(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/order/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_order_update = (query, request) => { + query.cookie.os = 'pc'; + const data = { ids: query.ids }; + return request( + 'POST', + `https://music.163.com/api/playlist/order/update`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_order_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/name/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_name_update = (query, request) => { + const data = { id: query.id, name: query.name }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/update/name`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/update/name', + realIP: query.realIP, + }, + ); + }; + playlist_name_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/mylike': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_mylike = (query, request) => { + const data = { time: query.time || '-1', limit: query.limit || '12' }; + return request( + 'POST', + `https://music.163.com/api/mlog/playlist/mylike/bytime/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_mylike(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/hot': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_hot = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/playlist/hottags`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_hot(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/highquality/tags': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_highquality_tags = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/playlist/highquality/tags`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_highquality_tags(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_detail = (query, request) => { + const data = { id: query.id, n: 100000, s: query.s || 8 }; + return request( + 'POST', + `https://music.163.com/api/v6/playlist/detail`, + data, + { + crypto: 'linuxapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/desc/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_desc_update = (query, request) => { + const data = { id: query.id, desc: query.desc }; + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/desc/update`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/desc/update', + realIP: query.realIP, + }, + ); + }; + playlist_desc_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/delete': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_delete = (query, request) => { + query.cookie.os = 'pc'; + const data = { ids: '[' + query.id + ']' }; + return request( + 'POST', + `https://music.163.com/weapi/playlist/remove`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_delete(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/create': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_create = (query, request) => { + query.cookie.os = 'pc'; + const data = { + name: query.name, + privacy: query.privacy, + type: query.type || 'NORMAL', + }; + return request( + 'POST', + `https://music.163.com/api/playlist/create`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_create(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/cover/update': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_cover_update = async (query, request) => { + const uploadInfo = await uploadPlugin(query, request); + const res = await request( + 'POST', + `https://music.163.com/weapi/playlist/cover/update`, + { id: query.id, coverImgId: uploadInfo.imgId }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + return { + status: 200, + body: { code: 200, data: { ...uploadInfo, ...res.body } }, + }; + }; + playlist_cover_update(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/playlist/catlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const playlist_catlist = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/playlist/catalogue`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + playlist_catlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personalized/privatecontent/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personalized_privatecontent_list = (query, request) => { + const data = { + offset: query.offset || 0, + total: 'true', + limit: query.limit || 60, + }; + return request( + 'POST', + `https://music.163.com/api/v2/privatecontent/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personalized_privatecontent_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personalized/privatecontent': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personalized_privatecontent = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/privatecontent`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personalized_privatecontent(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personalized/newsong': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personalized_newsong = (query, request) => { + const data = { + type: 'recommend', + limit: query.limit || 10, + areaId: query.areaId || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/personalized/newsong`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personalized_newsong(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personalized/mv': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personalized_mv = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/mv`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personalized_mv(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personalized/djprogram': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personalized_djprogram = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/djprogram`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personalized_djprogram(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personalized': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personalized = (query, request) => { + const data = { limit: query.limit || 30, total: true, n: 1000 }; + return request( + 'POST', + `https://music.163.com/weapi/personalized/playlist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personalized(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/personal_fm': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const personal_fm = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/radio/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + personal_fm(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/url': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_url = (query, request) => { + const data = { id: query.id, r: query.r || 1080 }; + return request( + 'POST', + `https://music.163.com/weapi/song/enhance/play/mv/url`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_url(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/sublist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_sublist = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/allvideo/sublist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_sublist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/sub': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_sub = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { mvId: query.mvid, mvIds: '["' + query.mvid + '"]' }; + return request( + 'POST', + `https://music.163.com/weapi/mv/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_sub(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/first': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_first = (query, request) => { + const data = { + area: query.area || '', + limit: query.limit || 30, + total: true, + }; + return request( + 'POST', + `https://interface.music.163.com/weapi/mv/first`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_first(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/exclusive/rcmd': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_exclusive_rcmd = (query, request) => { + const data = { offset: query.offset || 0, limit: query.limit || 30 }; + return request( + 'POST', + `https://interface.music.163.com/api/mv/exclusive/rcmd`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_exclusive_rcmd(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/detail/info': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_detail_info = (query, request) => { + const data = { threadid: `R_MV_5_${query.mvid}`, composeliked: true }; + return request( + 'POST', + `https://music.163.com/api/comment/commentthread/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_detail_info(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_detail = (query, request) => { + const data = { id: query.mvid }; + return request('POST', `https://music.163.com/api/v1/mv/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + mv_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/mv/all': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const mv_all = (query, request) => { + const data = { + tags: JSON.stringify({ + 地区: query.area || '全部', + 类型: query.type || '全部', + 排序: query.order || '上升最快', + }), + offset: query.offset || 0, + total: 'true', + limit: query.limit || 30, + }; + return request( + 'POST', + `https://interface.music.163.com/api/mv/all`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + mv_all(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/msg/private/history': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const msg_private_history = (query, request) => { + const data = { + userId: query.uid, + limit: query.limit || 30, + time: query.before || 0, + total: 'true', + }; + return request( + 'POST', + `https://music.163.com/api/msg/private/history`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + msg_private_history(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/msg/private': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const msg_private = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + total: 'true', + }; + return request( + 'POST', + `https://music.163.com/api/msg/private/users`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + msg_private(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/msg/notices': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const msg_notices = (query, request) => { + const data = { limit: query.limit || 30, time: query.lasttime || -1 }; + return request('POST', `https://music.163.com/api/msg/notices`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + msg_notices(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/msg/forwards': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const msg_forwards = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + total: 'true', + }; + return request('POST', `https://music.163.com/api/forwards/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + msg_forwards(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/msg/comments': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const msg_comments = (query, request) => { + const data = { + beforeTime: query.before || '-1', + limit: query.limit || 30, + total: 'true', + uid: query.uid, + }; + return request( + 'POST', + `https://music.163.com/api/v1/user/comments/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + msg_comments(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/lyric': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const lyric = (query, request) => { + query.cookie.os = 'pc'; + const data = { id: query.id, lv: -1, kv: -1, tv: -1 }; + return request('POST', `https://music.163.com/api/song/lyric`, data, { + crypto: 'linuxapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + lyric(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/logout': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const logout = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/logout`, + {}, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + logout(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/login/status': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const login_status = (query, request) => { + return request( + 'GET', + `https://music.163.com`, + {}, + { cookie: query.cookie, proxy: query.proxy, realIP: query.realIP }, + ).then((response) => { + try { + let profile = eval( + `(${/GUser\\s*=\\s*([^;]+);/.exec(response.body)[1]})`, + ); + let bindings = eval( + `(${/GBinds\\s*=\\s*([^;]+);/.exec(response.body)[1]})`, + ); + response.body = { code: 200, profile: profile, bindings: bindings }; + return response; + } catch (err) { + response.status = 301; + response.body = { code: 301 }; + return Promise.reject(response); + } + }); + }; + login_status(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/login/refresh': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const login_refresh = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/login/token/refresh`, + {}, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + login_refresh(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/login/cellphone': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const login_cellphone = async (query, request) => { + query.cookie.os = 'pc'; + const data = { + phone: query.phone, + countrycode: query.countrycode || '86', + password: + query.md5_password || + crypto.createHash('md5').update(query.password).digest('hex'), + rememberLogin: 'true', + }; + let result = await request( + 'POST', + `https://music.163.com/weapi/login/cellphone`, + data, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + if (result.body.code === 200) { + result = { + status: 200, + body: { ...result.body, cookie: result.cookie.join(';') }, + cookie: result.cookie, + }; + } + return result; + }; + login_cellphone(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/login': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const login = async (query, request) => { + query.cookie.os = 'pc'; + const data = { + username: query.email, + password: + query.md5_password || + crypto.createHash('md5').update(query.password).digest('hex'), + rememberLogin: 'true', + }; + let result = await request( + 'POST', + `https://music.163.com/weapi/login`, + data, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + if (result.body.code === 502) { + return { + status: 200, + body: { msg: '账号或密码错误', code: 502, message: '账号或密码错误' }, + }; + } + if (result.body.code === 200) { + result = { + status: 200, + body: { ...result.body, cookie: result.cookie.join(';') }, + cookie: result.cookie, + }; + } + return result; + }; + login(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/likelist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const likelist = (query, request) => { + const data = { uid: query.uid }; + return request( + 'POST', + `https://music.163.com/weapi/song/like/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + likelist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/like': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const like = (query, request) => { + query.like = query.like == 'false' ? false : true; + const data = { trackId: query.id, like: query.like }; + return request( + 'POST', + `https://music.163.com/weapi/radio/like?alg=${ + query.alg || 'itembased' + }&trackId=${query.id}&time=${query.time || 25}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + like(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/hot/topic': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const hot_topic = (query, request) => { + const data = { limit: query.limit || 20, offset: query.offset || 0 }; + return request('POST', `https://music.163.com/weapi/act/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + hot_topic(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/homepage/dragon/ball': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const homepage_dragon_ball = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/eapi/homepage/dragon/ball/static`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/homepage/dragon/ball/static', + realIP: query.realIP, + }, + ); + }; + homepage_dragon_ball(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/homepage/block/page': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const homepage_block_page = (query, request) => { + const data = { refresh: query.refresh || true }; + return request( + 'POST', + `https://music.163.com/api/homepage/block/page`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + homepage_block_page(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/history/recommend/songs/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const history_recommend_songs_detail = (query, request) => { + query.cookie.os = 'ios'; + const data = { date: query.date || '' }; + return request( + 'POST', + `https://music.163.com/api/discovery/recommend/songs/history/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + history_recommend_songs_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/history/recommend/songs': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const history_recommend_songs = (query, request) => { + query.cookie.os = 'ios'; + const data = {}; + return request( + 'POST', + `https://music.163.com/api/discovery/recommend/songs/history/recent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + history_recommend_songs(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/follow': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const follow = (query, request) => { + query.cookie.os = 'pc'; + query.t = query.t == 1 ? 'follow' : 'delfollow'; + return request( + 'POST', + `https://music.163.com/weapi/user/${query.t}/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + follow(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/fm_trash': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const fm_trash = (query, request) => { + const data = { songId: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/radio/trash/add?alg=RT&songId=${ + query.id + }&time=${query.time || 25}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + fm_trash(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/event/forward': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const event_forward = (query, request) => { + query.cookie.os = 'pc'; + const data = { + forwards: query.forwards, + id: query.evId, + eventUserId: query.uid, + }; + return request( + 'POST', + `https://music.163.com/weapi/event/forward`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + event_forward(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/event/del': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const event_del = (query, request) => { + const data = { id: query.evId }; + return request('POST', `https://music.163.com/eapi/event/delete`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + event_del(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/event': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const event = (query, request) => { + const data = { + pagesize: query.pagesize || 20, + lasttime: query.lasttime || -1, + }; + return request('POST', `https://music.163.com/weapi/v1/event/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + event(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/toplist/popular': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_toplist_popular = (query, request) => { + const data = { limit: query.limit || 100 }; + return request( + 'POST', + `https://music.163.com/api/dj/toplist/popular`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_toplist_popular(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/toplist/pay': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_toplist_pay = (query, request) => { + const data = { limit: query.limit || 100 }; + return request( + 'POST', + `https://music.163.com/api/djradio/toplist/pay`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_toplist_pay(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/toplist/newcomer': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_toplist_newcomer = (query, request) => { + const data = { limit: query.limit || 100, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/api/dj/toplist/newcomer`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_toplist_newcomer(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/toplist/hours': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_toplist_hours = (query, request) => { + const data = { limit: query.limit || 100 }; + return request( + 'POST', + `https://music.163.com/api/dj/toplist/hours`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_toplist_hours(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/toplist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_toplist = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + type: typeMap[query.type || 'new'] || '0', + }; + return request( + 'POST', + `https://music.163.com/api/djradio/toplist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_toplist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/today/perfered': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_today_perfered = (query, request) => { + const data = { page: query.page || 0 }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/today/perfered`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_today_perfered(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/subscriber': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_subscriber = (query, request) => { + const data = { + time: query.time || '-1', + id: query.id, + limit: query.limit || '20', + total: 'true', + }; + return request( + 'POST', + `https://music.163.com/api/djradio/subscriber`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_subscriber(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/sublist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_sublist = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/get/subed`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_sublist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/sub': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_sub = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { id: query.rid }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_sub(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/recommend/type': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_recommend_type = (query, request) => { + const data = { cateId: query.type }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/recommend`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_recommend_type(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/recommend': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_recommend = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/recommend/v1`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_recommend(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/radio/hot': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_radio_hot = (query, request) => { + const data = { + cateId: query.cateId, + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request('POST', `https://music.163.com/api/djradio/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + dj_radio_hot(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/program/toplist/hours': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_program_toplist_hours = (query, request) => { + const data = { limit: query.limit || 100 }; + return request( + 'POST', + `https://music.163.com/api/djprogram/toplist/hours`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_program_toplist_hours(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/program/toplist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_program_toplist = (query, request) => { + const data = { limit: query.limit || 100, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/api/program/toplist/v1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_program_toplist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/program/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_program_detail = (query, request) => { + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/api/dj/program/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_program_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/program': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_program = (query, request) => { + const data = { + radioId: query.rid, + limit: query.limit || 30, + offset: query.offset || 0, + asc: toBoolean(query.asc), + }; + return request( + 'POST', + `https://music.163.com/weapi/dj/program/byradio`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_program(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/personalize/recommend': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_personalize_recommend = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/djradio/personalize/rcmd`, + { limit: query.limit || 6 }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_personalize_recommend(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/paygift': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_paygift = (query, request) => { + const data = { limit: query.limit || 30, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/paygift/list?_nmclfl=1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_paygift(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/hot': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_hot = (query, request) => { + const data = { limit: query.limit || 30, offset: query.offset || 0 }; + return request( + 'POST', + `https://music.163.com/weapi/djradio/hot/v1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_hot(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_detail = (query, request) => { + const data = { id: query.rid }; + return request('POST', `https://music.163.com/api/djradio/v2/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + dj_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/catelist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_catelist = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/category/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_catelist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/category/recommend': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_category_recommend = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/category/recommend`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_category_recommend(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/category/excludehot': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_category_excludehot = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/category/excludehot`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_category_excludehot(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/dj/banner': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const dj_banner = (query, request) => { + const data = {}; + query.cookie.os = 'pc'; + return request( + 'POST', + `https://music.163.com/weapi/djradio/banner/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + dj_banner(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/digitalAlbum/purchased': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const digitalAlbum_purchased = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/api/digitalAlbum/purchased`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + digitalAlbum_purchased(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/digitalAlbum/ordering': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const digitalAlbum_ordering = (query, request) => { + const data = { + business: 'Album', + paymentMethod: query.payment, + digitalResources: JSON.stringify([ + { business: 'Album', resourceID: query.id, quantity: query.quantity }, + ]), + from: 'web', + }; + return request( + 'POST', + `https://music.163.com/api/ordering/web/digital`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + digitalAlbum_ordering(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/daily_signin': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const daily_signin = (query, request) => { + const data = { type: query.type || 0 }; + return request( + 'POST', + `https://music.163.com/weapi/point/dailyTask`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + daily_signin(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/countries/code/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const countries_code_list = (query, request) => { + const data = {}; + return request( + 'POST', + `https://interface3.music.163.com/eapi/lbs/countries/v1`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/lbs/countries/v1', + realIP: query.realIP, + }, + ); + }; + countries_code_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/video': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_video = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_VI_62_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_video(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/playlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_playlist = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/A_PL_0_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_playlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/new': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_new = (query, request) => { + query.cookie.os = 'pc'; + query.type = { + 0: 'R_SO_4_', + 1: 'R_MV_5_', + 2: 'A_PL_0_', + 3: 'R_AL_3_', + 4: 'A_DJ_1_', + 5: 'R_VI_62_', + 6: 'A_EV_2_', + }[query.type]; + const threadId = query.type + query.id; + const pageSize = query.pageSize || 20; + const pageNo = query.pageNo || 1; + const data = { + threadId: threadId, + pageNo, + showInner: query.showInner || true, + pageSize, + cursor: + +query.sortType === 3 ? query.cursor || '0' : (pageNo - 1) * pageSize, + sortType: query.sortType || 1, + }; + return request( + 'POST', + `https://music.163.com/api/v2/resource/comments`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/v2/resource/comments', + }, + ); + }; + comment_new(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/mv': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_mv = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_MV_5_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_mv(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/music': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_music = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/api/v1/resource/comments/R_SO_4_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_music(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/like': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_like = (query, request) => { + query.cookie.os = 'pc'; + query.t = query.t == 1 ? 'like' : 'unlike'; + query.type = { + 0: 'R_SO_4_', + 1: 'R_MV_5_', + 2: 'A_PL_0_', + 3: 'R_AL_3_', + 4: 'A_DJ_1_', + 5: 'R_VI_62_', + 6: 'A_EV_2_', + }[query.type]; + const data = { threadId: query.type + query.id, commentId: query.cid }; + if (query.type == 'A_EV_2_') { + data.threadId = query.threadId; + } + return request( + 'POST', + `https://music.163.com/weapi/v1/comment/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_like(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/hotwall/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_hotwall_list = (query, request) => { + const data = {}; + return request( + 'POST', + `https://music.163.com/api/comment/hotwall/list/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_hotwall_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/hot': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_hot = (query, request) => { + query.cookie.os = 'pc'; + query.type = { + 0: 'R_SO_4_', + 1: 'R_MV_5_', + 2: 'A_PL_0_', + 3: 'R_AL_3_', + 4: 'A_DJ_1_', + 5: 'R_VI_62_', + }[query.type]; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/hotcomments/${query.type}${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_hot(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/floor': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_floor = (query, request) => { + query.type = { + 0: 'R_SO_4_', + 1: 'R_MV_5_', + 2: 'A_PL_0_', + 3: 'R_AL_3_', + 4: 'A_DJ_1_', + 5: 'R_VI_62_', + }[query.type]; + const data = { + parentCommentId: query.parentCommentId, + threadId: query.type + query.id, + time: query.time || -1, + limit: query.limit || 20, + }; + return request( + 'POST', + `https://music.163.com/api/resource/comment/floor/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_floor(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/event': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_event = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/${query.threadId}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_event(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/dj': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_dj = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_dj(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment/album': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment_album = (query, request) => { + query.cookie.os = 'pc'; + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_AL_3_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment_album(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/comment': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const comment = (query, request) => { + query.cookie.os = 'pc'; + query.t = { 1: 'add', 0: 'delete', 2: 'reply' }[query.t]; + query.type = { + 0: 'R_SO_4_', + 1: 'R_MV_5_', + 2: 'A_PL_0_', + 3: 'R_AL_3_', + 4: 'A_DJ_1_', + 5: 'R_VI_62_', + 6: 'A_EV_2_', + }[query.type]; + const data = { threadId: query.type + query.id }; + if (query.type == 'A_EV_2_') { + data.threadId = query.threadId; + } + if (query.t == 'add') data.content = query.content; + else if (query.t == 'delete') data.commentId = query.commentId; + else if (query.t == 'reply') { + data.commentId = query.commentId; + data.content = query.content; + } + return request( + 'POST', + `https://music.163.com/weapi/resource/comments/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + comment(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/cloudsearch': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const cloudsearch = (query, request) => { + const data = { + s: query.keywords, + type: query.type || 1, + limit: query.limit || 30, + offset: query.offset || 0, + }; + return request( + 'POST', + `https://music.163.com/weapi/cloudsearch/get/web`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + cloudsearch(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/check/music': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const check_music = (query, request) => { + const data = { + ids: '[' + parseInt(query.id) + ']', + br: parseInt(query.br || 999000), + }; + return request( + 'POST', + `https://music.163.com/weapi/song/enhance/player/url`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ).then((response) => { + let playable = false; + if (response.body.code == 200) { + if (response.body.data[0].code == 200) { + playable = true; + } + } + if (playable) { + response.body = { success: true, message: 'ok' }; + return response; + } else { + response.status = 404; + response.body = { success: false, message: '亲爱的,暂无版权' }; + return Promise.reject(response); + } + }); + }; + check_music(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/cellphone/existence/check': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const cellphone_existence_check = (query, request) => { + const data = { cellphone: query.phone, countrycode: query.countrycode }; + return request( + 'POST', + `https://music.163.com/eapi/cellphone/existence/check`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/cellphone/existence/check', + realIP: query.realIP, + }, + ); + }; + cellphone_existence_check(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/captcha/verify': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const captcha_verify = (query, request) => { + const data = { + ctcode: query.ctcode || '86', + cellphone: query.phone, + captcha: query.captcha, + }; + return request( + 'POST', + `https://music.163.com/weapi/sms/captcha/verify`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + captcha_verify(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/captcha/sent': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const captcha_sent = (query, request) => { + const data = { ctcode: query.ctcode || '86', cellphone: query.phone }; + return request( + 'POST', + `https://music.163.com/weapi/sms/captcha/sent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + captcha_sent(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/calendar': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const calendar = (query, request) => { + const data = { + startTime: query.startTime || Date.now(), + endTime: query.endTime || Date.now(), + }; + return request( + 'POST', + `https://music.163.com/api/mcalendar/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + calendar(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/banner': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const banner = (query, request) => { + const type = + { 0: 'pc', 1: 'android', 2: 'iphone', 3: 'ipad' }[query.type || 0] || + 'pc'; + return request( + 'POST', + `https://music.163.com/api/v2/banner/get`, + { clientType: type }, + { crypto: 'linuxapi', proxy: query.proxy, realIP: query.realIP }, + ); + }; + banner(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/avatar/upload': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const avatar_upload = async (query, request) => { + const uploadInfo = await uploadPlugin(query, request); + const res = await request( + 'POST', + `https://music.163.com/weapi/user/avatar/upload/v1`, + { imgid: uploadInfo.imgId }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + return { + status: 200, + body: { code: 200, data: { ...uploadInfo, ...res.body } }, + }; + }; + avatar_upload(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/audio/match': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const audio_match = (query, request) => { + query.cookie.os = 'pc'; + const data = { + algorithmCode: 'shazam_v2', + times: 1, + sessionId: 'C999431ACDC84EDBB984763654E6F8D7', + duration: 3.3066249999999995, + from: 'recognize-song', + rawdata: realData, + }; + return request( + 'POST', + `https://music.163.com/api/music/audio/match`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + audio_match(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artists': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artists = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/artist/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artists(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/top/song': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_top_song = (query, request) => { + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/api/artist/top/song`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artist_top_song(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/sublist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_sublist = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/artist/sublist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artist_sublist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/sub': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_sub = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { artistId: query.id, artistIds: '[' + query.id + ']' }; + return request( + 'POST', + `https://music.163.com/weapi/artist/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artist_sub(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/songs': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_songs = (query, request) => { + query.cookie.os = 'pc'; + const data = { + id: query.id, + private_cloud: 'true', + work_type: 1, + order: query.order || 'hot', + offset: query.offset || 0, + limit: query.limit || 100, + }; + return request( + 'POST', + `https://music.163.com/api/v1/artist/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artist_songs(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/mv': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_mv = (query, request) => { + const data = { + artistId: query.id, + limit: query.limit, + offset: query.offset, + total: true, + }; + return request('POST', `https://music.163.com/weapi/artist/mvs`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + artist_mv(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_list = (query, request) => { + const data = { + initial: isNaN(query.initial) + ? (query.initial || '').toUpperCase().charCodeAt() || undefined + : query.initial, + offset: query.offset || 0, + limit: query.limit || 30, + total: true, + type: query.type || '1', + area: query.area, + }; + return request('POST', `https://music.163.com/api/v1/artist/list`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + artist_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/desc': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_desc = (query, request) => { + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/artist/introduction`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artist_desc(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/artist/album': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const artist_album = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/artist/albums/${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + artist_album(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/sublist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_sublist = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + }; + return request( + 'POST', + `https://music.163.com/weapi/album/sublist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_sublist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/sub': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_sub = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub'; + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/api/album/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_sub(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/songsaleboard': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_songsaleboard = (query, request) => { + let data = { albumType: query.albumType || 0 }; + const type = query.type || 'daily'; + if (type === 'year') { + data = { ...data, year: query.year }; + } + return request( + 'POST', + `https://music.163.com/api/feealbum/songsaleboard/${type}/type`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_songsaleboard(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/newest': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_newest = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/discovery/newAlbum`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_newest(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/new': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_new = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + area: query.area || 'ALL', + }; + return request('POST', `https://music.163.com/weapi/album/new`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }); + }; + album_new(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/list/style': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_list_style = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + total: true, + area: query.area || 'Z_H', + }; + return request( + 'POST', + `https://music.163.com/weapi/vipmall/appalbum/album/style`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_list_style(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/list': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_list = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + area: query.area || 'ALL', + type: query.type, + }; + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_list(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/detail/dynamic': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_detail_dynamic = (query, request) => { + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/api/album/detail/dynamic`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_detail_dynamic(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album/detail': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album_detail = (query, request) => { + const data = { id: query.id }; + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album_detail(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/album': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const album = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/album/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ); + }; + album(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/activate/init/profile': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const activate_init_profile = (query, request) => { + const data = { nickname: query.nickname }; + return request( + 'POST', + `https://music.163.com/eapi/activate/initProfile`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/activate/initProfile', + }, + ); + }; + activate_init_profile(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + '/related/playlist': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const related_playlist = (query, request) => { + return request( + 'GET', + `https://music.163.com/playlist?id=${query.id}`, + {}, + { + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ).then((response) => { + try { + const pattern = /
[\s\S]*?[\s\S]*?]*>([^<]+?)<\/a>[\s\S]*?]*>([^<]+?)<\/a>/g; + let result, + playlists = []; + while ((result = pattern.exec(response.body)) != null) { + playlists.push({ + creator: { + userId: result[4].slice('/user/home?id='.length), + nickname: result[5], + }, + coverImgUrl: result[1].slice(0, -'?param=50y50'.length), + name: result[3], + id: result[2].slice('/playlist?id='.length), + }); + } + response.body = { code: 200, playlists: playlists }; + return response; + } catch (err) { + response.status = 500; + response.body = { code: 500, msg: err.stack }; + return Promise.reject(response); + } + }); + }; + related_playlist(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, + + '/batch': (req, res) => { + if (typeof req.query.cookie === 'string') { + req.query.cookie = cookieToJson(req.query.cookie); + } + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ); + const batch = (query, request) => { + const data = { + e_r: true, + }; + Object.keys(query).forEach((i) => { + if (/^\/api\//.test(i)) { + data[i] = query[i]; + } + }); + return request('POST', `https://music.163.com/eapi/batch`, data, { + crypto: 'eapi', + proxy: query.proxy, + url: '/api/batch', + cookie: query.cookie, + realIP: query.realIP, + }); + }; + batch(query, request) + .then((answer) => { + console.log('[OK]', decodeURIComponent(req.originalUrl)); + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }) + .catch((answer) => { + console.log('[ERR]', decodeURIComponent(req.originalUrl), { + status: answer.status, + body: answer.body, + }); + if (answer.body.code == '301') answer.body.msg = '需要登录'; + res.append('Set-Cookie', answer.cookie); + res.status(answer.status).send(answer.body); + }); + }, +}; diff --git a/napi/tsconfig.json b/napi/tsconfig.json new file mode 100644 index 0000000..248536d --- /dev/null +++ b/napi/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2015", + "module": "commonjs", + "experimentalDecorators": true, + "moduleResolution": "node", + "lib": ["esnext", "esnext.asynciterable", "dom"], + "esModuleInterop": true, + "allowJs": true, + "sourceMap": true, + "strict": true, + "noEmit": true, + "baseUrl": ".", + "paths": { + "~/*": ["./*"], + "@/*": ["./*"] + } + }, + "exclude": ["node_modules"] +} diff --git a/napi/util/apicache.js b/napi/util/apicache.js new file mode 100644 index 0000000..1b267ed --- /dev/null +++ b/napi/util/apicache.js @@ -0,0 +1,830 @@ +var url = require('url'); +var MemoryCache = require('./memory-cache'); + +var t = { + ms: 1, + second: 1000, + minute: 60000, + hour: 3600000, + day: 3600000 * 24, + week: 3600000 * 24 * 7, + month: 3600000 * 24 * 30, +}; + +var instances = []; + +var matches = function (a) { + return function (b) { + return a === b; + }; +}; + +var doesntMatch = function (a) { + return function (b) { + return !matches(a)(b); + }; +}; + +var logDuration = function (d, prefix) { + var str = d > 1000 ? (d / 1000).toFixed(2) + 'sec' : d + 'ms'; + return '\x1b[33m- ' + (prefix ? prefix + ' ' : '') + str + '\x1b[0m'; +}; + +function getSafeHeaders(res) { + return res.getHeaders ? res.getHeaders() : res._headers; +} + +function ApiCache() { + var memCache = new MemoryCache(); + + var globalOptions = { + debug: false, + defaultDuration: 3600000, + enabled: true, + appendKey: [], + jsonp: false, + redisClient: false, + headerBlacklist: [], + statusCodes: { + include: [], + exclude: [], + }, + events: { + expire: undefined, + }, + headers: { + // 'cache-control': 'no-cache' // example of header overwrite + }, + trackPerformance: false, + }; + + var middlewareOptions = []; + var instance = this; + var index = null; + var timers = {}; + var performanceArray = []; // for tracking cache hit rate + + instances.push(this); + this.id = instances.length; + + function debug(a, b, c, d) { + var arr = ['\x1b[36m[apicache]\x1b[0m', a, b, c, d].filter(function (arg) { + return arg !== undefined; + }); + var debugEnv = + process.env.DEBUG && + process.env.DEBUG.split(',').indexOf('apicache') !== -1; + + return (globalOptions.debug || debugEnv) && console.log.apply(null, arr); + } + + function shouldCacheResponse(request, response, toggle) { + var opt = globalOptions; + var codes = opt.statusCodes; + + if (!response) return false; + + if (toggle && !toggle(request, response)) { + return false; + } + + if ( + codes.exclude && + codes.exclude.length && + codes.exclude.indexOf(response.statusCode) !== -1 + ) + return false; + if ( + codes.include && + codes.include.length && + codes.include.indexOf(response.statusCode) === -1 + ) + return false; + + return true; + } + + function addIndexEntries(key, req) { + var groupName = req.apicacheGroup; + + if (groupName) { + debug('group detected "' + groupName + '"'); + var group = (index.groups[groupName] = index.groups[groupName] || []); + group.unshift(key); + } + + index.all.unshift(key); + } + + function filterBlacklistedHeaders(headers) { + return Object.keys(headers) + .filter(function (key) { + return globalOptions.headerBlacklist.indexOf(key) === -1; + }) + .reduce(function (acc, header) { + acc[header] = headers[header]; + return acc; + }, {}); + } + + function createCacheObject(status, headers, data, encoding) { + return { + status: status, + headers: filterBlacklistedHeaders(headers), + data: data, + encoding: encoding, + timestamp: new Date().getTime() / 1000, // seconds since epoch. This is used to properly decrement max-age headers in cached responses. + }; + } + + function cacheResponse(key, value, duration) { + var redis = globalOptions.redisClient; + var expireCallback = globalOptions.events.expire; + + if (redis && redis.connected) { + try { + redis.hset(key, 'response', JSON.stringify(value)); + redis.hset(key, 'duration', duration); + redis.expire(key, duration / 1000, expireCallback || function () {}); + } catch (err) { + debug('[apicache] error in redis.hset()'); + } + } else { + memCache.add(key, value, duration, expireCallback); + } + + // add automatic cache clearing from duration, includes max limit on setTimeout + timers[key] = setTimeout(function () { + instance.clear(key, true); + }, Math.min(duration, 2147483647)); + } + + function accumulateContent(res, content) { + if (content) { + if (typeof content == 'string') { + res._apicache.content = (res._apicache.content || '') + content; + } else if (Buffer.isBuffer(content)) { + var oldContent = res._apicache.content; + + if (typeof oldContent === 'string') { + oldContent = !Buffer.from + ? new Buffer(oldContent) + : Buffer.from(oldContent); + } + + if (!oldContent) { + oldContent = !Buffer.alloc ? new Buffer(0) : Buffer.alloc(0); + } + + res._apicache.content = Buffer.concat( + [oldContent, content], + oldContent.length + content.length, + ); + } else { + res._apicache.content = content; + } + } + } + + function makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + toggle, + ) { + // monkeypatch res.end to create cache object + res._apicache = { + write: res.write, + writeHead: res.writeHead, + end: res.end, + cacheable: true, + content: undefined, + }; + + // append header overwrites if applicable + Object.keys(globalOptions.headers).forEach(function (name) { + res.setHeader(name, globalOptions.headers[name]); + }); + + res.writeHead = function () { + // add cache control headers + if (!globalOptions.headers['cache-control']) { + if (shouldCacheResponse(req, res, toggle)) { + res.setHeader( + 'cache-control', + 'max-age=' + (duration / 1000).toFixed(0), + ); + } else { + res.setHeader('cache-control', 'no-cache, no-store, must-revalidate'); + } + } + + res._apicache.headers = Object.assign({}, getSafeHeaders(res)); + return res._apicache.writeHead.apply(this, arguments); + }; + + // patch res.write + res.write = function (content) { + accumulateContent(res, content); + return res._apicache.write.apply(this, arguments); + }; + + // patch res.end + res.end = function (content, encoding) { + if (shouldCacheResponse(req, res, toggle)) { + accumulateContent(res, content); + + if (res._apicache.cacheable && res._apicache.content) { + addIndexEntries(key, req); + var headers = res._apicache.headers || getSafeHeaders(res); + var cacheObject = createCacheObject( + res.statusCode, + headers, + res._apicache.content, + encoding, + ); + cacheResponse(key, cacheObject, duration); + + // display log entry + var elapsed = new Date() - req.apicacheTimer; + debug( + 'adding cache entry for "' + key + '" @ ' + strDuration, + logDuration(elapsed), + ); + debug('_apicache.headers: ', res._apicache.headers); + debug('res.getHeaders(): ', getSafeHeaders(res)); + debug('cacheObject: ', cacheObject); + } + } + + return res._apicache.end.apply(this, arguments); + }; + + next(); + } + + function sendCachedResponse( + request, + response, + cacheObject, + toggle, + next, + duration, + ) { + if (toggle && !toggle(request, response)) { + return next(); + } + + var headers = getSafeHeaders(response); + + Object.assign( + headers, + filterBlacklistedHeaders(cacheObject.headers || {}), + { + // set properly-decremented max-age header. This ensures that max-age is in sync with the cache expiration. + 'cache-control': + 'max-age=' + + Math.max( + 0, + ( + duration / 1000 - + (new Date().getTime() / 1000 - cacheObject.timestamp) + ).toFixed(0), + ), + }, + ); + + // only embed apicache headers when not in production environment + + // unstringify buffers + var data = cacheObject.data; + if (data && data.type === 'Buffer') { + data = + typeof data.data === 'number' + ? new Buffer.alloc(data.data) + : new Buffer.from(data.data); + } + + // test Etag against If-None-Match for 304 + var cachedEtag = cacheObject.headers.etag; + var requestEtag = request.headers['if-none-match']; + + if (requestEtag && cachedEtag === requestEtag) { + response.writeHead(304, headers); + return response.end(); + } + + response.writeHead(cacheObject.status || 200, headers); + + return response.end(data, cacheObject.encoding); + } + + function syncOptions() { + for (var i in middlewareOptions) { + Object.assign( + middlewareOptions[i].options, + globalOptions, + middlewareOptions[i].localOptions, + ); + } + } + + this.clear = function (target, isAutomatic) { + var group = index.groups[target]; + var redis = globalOptions.redisClient; + + if (group) { + debug('clearing group "' + target + '"'); + + group.forEach(function (key) { + debug('clearing cached entry for "' + key + '"'); + clearTimeout(timers[key]); + delete timers[key]; + if (!globalOptions.redisClient) { + memCache.delete(key); + } else { + try { + redis.del(key); + } catch (err) { + console.log('[apicache] error in redis.del("' + key + '")'); + } + } + index.all = index.all.filter(doesntMatch(key)); + }); + + delete index.groups[target]; + } else if (target) { + debug( + 'clearing ' + + (isAutomatic ? 'expired' : 'cached') + + ' entry for "' + + target + + '"', + ); + clearTimeout(timers[target]); + delete timers[target]; + // clear actual cached entry + if (!redis) { + memCache.delete(target); + } else { + try { + redis.del(target); + } catch (err) { + console.log('[apicache] error in redis.del("' + target + '")'); + } + } + + // remove from global index + index.all = index.all.filter(doesntMatch(target)); + + // remove target from each group that it may exist in + Object.keys(index.groups).forEach(function (groupName) { + index.groups[groupName] = index.groups[groupName].filter( + doesntMatch(target), + ); + + // delete group if now empty + if (!index.groups[groupName].length) { + delete index.groups[groupName]; + } + }); + } else { + debug('clearing entire index'); + + if (!redis) { + memCache.clear(); + } else { + // clear redis keys one by one from internal index to prevent clearing non-apicache entries + index.all.forEach(function (key) { + clearTimeout(timers[key]); + delete timers[key]; + try { + redis.del(key); + } catch (err) { + console.log('[apicache] error in redis.del("' + key + '")'); + } + }); + } + this.resetIndex(); + } + + return this.getIndex(); + }; + + function parseDuration(duration, defaultDuration) { + if (typeof duration === 'number') return duration; + + if (typeof duration === 'string') { + var split = duration.match(/^([\d\.,]+)\s?(\w+)$/); + + if (split.length === 3) { + var len = parseFloat(split[1]); + var unit = split[2].replace(/s$/i, '').toLowerCase(); + if (unit === 'm') { + unit = 'ms'; + } + + return (len || 1) * (t[unit] || 0); + } + } + + return defaultDuration; + } + + this.getDuration = function (duration) { + return parseDuration(duration, globalOptions.defaultDuration); + }; + + /** + * Return cache performance statistics (hit rate). Suitable for putting into a route: + * + * app.get('/api/cache/performance', (req, res) => { + * res.json(apicache.getPerformance()) + * }) + * + */ + this.getPerformance = function () { + return performanceArray.map(function (p) { + return p.report(); + }); + }; + + this.getIndex = function (group) { + if (group) { + return index.groups[group]; + } else { + return index; + } + }; + + this.middleware = function cache( + strDuration, + middlewareToggle, + localOptions, + ) { + var duration = instance.getDuration(strDuration); + var opt = {}; + + middlewareOptions.push({ + options: opt, + }); + + var options = function (localOptions) { + if (localOptions) { + middlewareOptions.find(function (middleware) { + return middleware.options === opt; + }).localOptions = localOptions; + } + + syncOptions(); + + return opt; + }; + + options(localOptions); + + /** + * A Function for non tracking performance + */ + function NOOPCachePerformance() { + this.report = this.hit = this.miss = function () {}; // noop; + } + + /** + * A function for tracking and reporting hit rate. These statistics are returned by the getPerformance() call above. + */ + function CachePerformance() { + /** + * Tracks the hit rate for the last 100 requests. + * If there have been fewer than 100 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast100 = new Uint8Array(100 / 4); // each hit is 2 bits + + /** + * Tracks the hit rate for the last 1000 requests. + * If there have been fewer than 1000 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast1000 = new Uint8Array(1000 / 4); // each hit is 2 bits + + /** + * Tracks the hit rate for the last 10000 requests. + * If there have been fewer than 10000 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast10000 = new Uint8Array(10000 / 4); // each hit is 2 bits + + /** + * Tracks the hit rate for the last 100000 requests. + * If there have been fewer than 100000 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast100000 = new Uint8Array(100000 / 4); // each hit is 2 bits + + /** + * The number of calls that have passed through the middleware since the server started. + */ + this.callCount = 0; + + /** + * The total number of hits since the server started + */ + this.hitCount = 0; + + /** + * The key from the last cache hit. This is useful in identifying which route these statistics apply to. + */ + this.lastCacheHit = null; + + /** + * The key from the last cache miss. This is useful in identifying which route these statistics apply to. + */ + this.lastCacheMiss = null; + + /** + * Return performance statistics + */ + this.report = function () { + return { + lastCacheHit: this.lastCacheHit, + lastCacheMiss: this.lastCacheMiss, + callCount: this.callCount, + hitCount: this.hitCount, + missCount: this.callCount - this.hitCount, + hitRate: this.callCount == 0 ? null : this.hitCount / this.callCount, + hitRateLast100: this.hitRate(this.hitsLast100), + hitRateLast1000: this.hitRate(this.hitsLast1000), + hitRateLast10000: this.hitRate(this.hitsLast10000), + hitRateLast100000: this.hitRate(this.hitsLast100000), + }; + }; + + /** + * Computes a cache hit rate from an array of hits and misses. + * @param {Uint8Array} array An array representing hits and misses. + * @returns a number between 0 and 1, or null if the array has no hits or misses + */ + this.hitRate = function (array) { + var hits = 0; + var misses = 0; + for (var i = 0; i < array.length; i++) { + var n8 = array[i]; + for (j = 0; j < 4; j++) { + switch (n8 & 3) { + case 1: + hits++; + break; + case 2: + misses++; + break; + } + n8 >>= 2; + } + } + var total = hits + misses; + if (total == 0) return null; + return hits / total; + }; + + /** + * Record a hit or miss in the given array. It will be recorded at a position determined + * by the current value of the callCount variable. + * @param {Uint8Array} array An array representing hits and misses. + * @param {boolean} hit true for a hit, false for a miss + * Each element in the array is 8 bits, and encodes 4 hit/miss records. + * Each hit or miss is encoded as to bits as follows: + * 00 means no hit or miss has been recorded in these bits + * 01 encodes a hit + * 10 encodes a miss + */ + this.recordHitInArray = function (array, hit) { + var arrayIndex = ~~(this.callCount / 4) % array.length; + var bitOffset = (this.callCount % 4) * 2; // 2 bits per record, 4 records per uint8 array element + var clearMask = ~(3 << bitOffset); + var record = (hit ? 1 : 2) << bitOffset; + array[arrayIndex] = (array[arrayIndex] & clearMask) | record; + }; + + /** + * Records the hit or miss in the tracking arrays and increments the call count. + * @param {boolean} hit true records a hit, false records a miss + */ + this.recordHit = function (hit) { + this.recordHitInArray(this.hitsLast100, hit); + this.recordHitInArray(this.hitsLast1000, hit); + this.recordHitInArray(this.hitsLast10000, hit); + this.recordHitInArray(this.hitsLast100000, hit); + if (hit) this.hitCount++; + this.callCount++; + }; + + /** + * Records a hit event, setting lastCacheMiss to the given key + * @param {string} key The key that had the cache hit + */ + this.hit = function (key) { + this.recordHit(true); + this.lastCacheHit = key; + }; + + /** + * Records a miss event, setting lastCacheMiss to the given key + * @param {string} key The key that had the cache miss + */ + this.miss = function (key) { + this.recordHit(false); + this.lastCacheMiss = key; + }; + } + + var perf = globalOptions.trackPerformance + ? new CachePerformance() + : new NOOPCachePerformance(); + + performanceArray.push(perf); + + var cache = function (req, res, next) { + function bypass() { + debug('bypass detected, skipping cache.'); + return next(); + } + + // initial bypass chances + if (!opt.enabled) return bypass(); + if ( + req.headers['x-apicache-bypass'] || + req.headers['x-apicache-force-fetch'] + ) + return bypass(); + + // REMOVED IN 0.11.1 TO CORRECT MIDDLEWARE TOGGLE EXECUTE ORDER + // if (typeof middlewareToggle === 'function') { + // if (!middlewareToggle(req, res)) return bypass() + // } else if (middlewareToggle !== undefined && !middlewareToggle) { + // return bypass() + // } + + // embed timer + req.apicacheTimer = new Date(); + + // In Express 4.x the url is ambigious based on where a router is mounted. originalUrl will give the full Url + var key = req.originalUrl || req.url; + + // Remove querystring from key if jsonp option is enabled + if (opt.jsonp) { + key = url.parse(key).pathname; + } + + // add appendKey (either custom function or response path) + if (typeof opt.appendKey === 'function') { + key += '$$appendKey=' + opt.appendKey(req, res); + } else if (opt.appendKey.length > 0) { + var appendKey = req; + + for (var i = 0; i < opt.appendKey.length; i++) { + appendKey = appendKey[opt.appendKey[i]]; + } + key += '$$appendKey=' + appendKey; + } + + // attempt cache hit + var redis = opt.redisClient; + var cached = !redis ? memCache.getValue(key) : null; + + // send if cache hit from memory-cache + if (cached) { + var elapsed = new Date() - req.apicacheTimer; + debug( + 'sending cached (memory-cache) version of', + key, + logDuration(elapsed), + ); + + perf.hit(key); + return sendCachedResponse( + req, + res, + cached, + middlewareToggle, + next, + duration, + ); + } + + // send if cache hit from redis + if (redis && redis.connected) { + try { + redis.hgetall(key, function (err, obj) { + if (!err && obj && obj.response) { + var elapsed = new Date() - req.apicacheTimer; + debug( + 'sending cached (redis) version of', + key, + logDuration(elapsed), + ); + + perf.hit(key); + return sendCachedResponse( + req, + res, + JSON.parse(obj.response), + middlewareToggle, + next, + duration, + ); + } else { + perf.miss(key); + return makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + middlewareToggle, + ); + } + }); + } catch (err) { + // bypass redis on error + perf.miss(key); + return makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + middlewareToggle, + ); + } + } else { + perf.miss(key); + return makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + middlewareToggle, + ); + } + }; + + cache.options = options; + + return cache; + }; + + this.options = function (options) { + if (options) { + Object.assign(globalOptions, options); + syncOptions(); + + if ('defaultDuration' in options) { + // Convert the default duration to a number in milliseconds (if needed) + globalOptions.defaultDuration = parseDuration( + globalOptions.defaultDuration, + 3600000, + ); + } + + if (globalOptions.trackPerformance) { + debug( + 'WARNING: using trackPerformance flag can cause high memory usage!', + ); + } + + return this; + } else { + return globalOptions; + } + }; + + this.resetIndex = function () { + index = { + all: [], + groups: {}, + }; + }; + + this.newInstance = function (config) { + var instance = new ApiCache(); + + if (config) { + instance.options(config); + } + + return instance; + }; + + this.clone = function () { + return this.newInstance(this.options()); + }; + + // initialize index + this.resetIndex(); +} + +module.exports = new ApiCache(); diff --git a/napi/util/crypto.js b/napi/util/crypto.js new file mode 100644 index 0000000..de80e15 --- /dev/null +++ b/napi/util/crypto.js @@ -0,0 +1,67 @@ +const crypto = require('crypto'); +const iv = Buffer.from('0102030405060708'); +const presetKey = Buffer.from('0CoJUm6Qyw8W8jud'); +const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q'); +const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; +const publicKey = + '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----'; +const eapiKey = 'e82ckenh8dichen8'; + +const aesEncrypt = (buffer, mode, key, iv) => { + const cipher = crypto.createCipheriv('aes-128-' + mode, key, iv); + return Buffer.concat([cipher.update(buffer), cipher.final()]); +}; + +const rsaEncrypt = (buffer, key) => { + buffer = Buffer.concat([Buffer.alloc(128 - buffer.length), buffer]); + return crypto.publicEncrypt( + { key: key, padding: crypto.constants.RSA_NO_PADDING }, + buffer, + ); +}; + +const weapi = (object) => { + const text = JSON.stringify(object); + const secretKey = crypto + .randomBytes(16) + .map((n) => base62.charAt(n % 62).charCodeAt()); + return { + params: aesEncrypt( + Buffer.from( + aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64'), + ), + 'cbc', + secretKey, + iv, + ).toString('base64'), + encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex'), + }; +}; + +const linuxapi = (object) => { + const text = JSON.stringify(object); + return { + eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '') + .toString('hex') + .toUpperCase(), + }; +}; + +const eapi = (url, object) => { + const text = typeof object === 'object' ? JSON.stringify(object) : object; + const message = `nobody${url}use${text}md5forencrypt`; + const digest = crypto.createHash('md5').update(message).digest('hex'); + const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}`; + return { + params: aesEncrypt(Buffer.from(data), 'ecb', eapiKey, '') + .toString('hex') + .toUpperCase(), + }; +}; + +const decrypt = (cipherBuffer) => { + const decipher = crypto.createDecipheriv('aes-128-ecb', eapiKey, ''); + return Buffer.concat([decipher.update(cipherBuffer), decipher.final()]); +}; + +module.exports = { weapi, linuxapi, eapi, decrypt }; diff --git a/napi/util/index.js b/napi/util/index.js new file mode 100644 index 0000000..6241c2c --- /dev/null +++ b/napi/util/index.js @@ -0,0 +1,17 @@ +module.exports = { + toBoolean(val) { + if (typeof val === 'boolean') return val; + if (val === '') return val; + return val === 'true' || val == '1'; + }, + cookieToJson(cookie) { + if (!cookie) return {}; + let cookieArr = cookie.split(';'); + let obj = {}; + cookieArr.forEach((i) => { + let arr = i.split('='); + obj[arr[0]] = arr[1]; + }); + return obj; + }, +}; diff --git a/napi/util/memory-cache.js b/napi/util/memory-cache.js new file mode 100644 index 0000000..02e735a --- /dev/null +++ b/napi/util/memory-cache.js @@ -0,0 +1,63 @@ +function MemoryCache() { + this.cache = {}; + this.size = 0; +} + +MemoryCache.prototype.add = function (key, value, time, timeoutCallback) { + var old = this.cache[key]; + var instance = this; + + var entry = { + value: value, + expire: time + Date.now(), + timeout: setTimeout(function () { + instance.delete(key); + return ( + timeoutCallback && + typeof timeoutCallback === 'function' && + timeoutCallback(value, key) + ); + }, time), + }; + + this.cache[key] = entry; + this.size = Object.keys(this.cache).length; + + return entry; +}; + +MemoryCache.prototype.delete = function (key) { + var entry = this.cache[key]; + + if (entry) { + clearTimeout(entry.timeout); + } + + delete this.cache[key]; + + this.size = Object.keys(this.cache).length; + + return null; +}; + +MemoryCache.prototype.get = function (key) { + var entry = this.cache[key]; + + return entry; +}; + +MemoryCache.prototype.getValue = function (key) { + var entry = this.get(key); + + return entry && entry.value; +}; + +MemoryCache.prototype.clear = function () { + Object.keys(this.cache).forEach(function (key) { + this.delete(key); + }, this); + + return true; +}; + +module.exports = MemoryCache; diff --git a/napi/util/request.js b/napi/util/request.js new file mode 100644 index 0000000..84d448d --- /dev/null +++ b/napi/util/request.js @@ -0,0 +1,177 @@ +const encrypt = require('./crypto'); +const axios = require('axios'); +const queryString = require('querystring'); +const PacProxyAgent = require('pac-proxy-agent'); +const http = require('http'); +const https = require('https'); +const tunnel = require('tunnel'); +const qs = require('url'); +// request.debug = true // 开启可看到更详细信息 + +const chooseUserAgent = (ua = false) => { + const userAgentList = { + mobile: [ + // iOS 13.5.1 14.0 beta with safari + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.', + // iOS with qq micromsg + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML like Gecko) Mobile/14A456 QQ/6.5.7.408 V1_IPH_SQ_6.5.7_1_APP_A Pixel/750 Core/UIWebView NetType/4G Mem/103', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.15(0x17000f27) NetType/WIFI Language/zh', + // Android -> Huawei Xiaomi + 'Mozilla/5.0 (Linux; Android 9; PCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.311 Mobile Safari/537.36', + 'Mozilla/5.0 (Linux; U; Android 9; zh-cn; Redmi Note 8 Build/PKQ1.190616.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.141 Mobile Safari/537.36 XiaoMi/MiuiBrowser/12.5.22', + // Android + qq micromsg + 'Mozilla/5.0 (Linux; Android 10; YAL-AL00 Build/HUAWEIYAL-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2581 MMWEBSDK/200801 Mobile Safari/537.36 MMWEBID/3027 MicroMessenger/7.0.18.1740(0x27001235) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64', + 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BKK-AL10 Build/HONORBKK-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.6 Mobile Safari/537.36', + ], + pc: [ + // macOS 10.15.6 Firefox / Chrome / Safari + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15', + // Windows 10 Firefox / Chrome / Edge + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586', + // Linux 就算了 + ], + }; + let realUserAgentList = + userAgentList[ua] || userAgentList.mobile.concat(userAgentList.pc); + return ['mobile', 'pc', false].indexOf(ua) > -1 + ? realUserAgentList[Math.floor(Math.random() * realUserAgentList.length)] + : ua; +}; +const createRequest = (method, url, data, options) => { + return new Promise((resolve, reject) => { + let headers = { 'User-Agent': chooseUserAgent(options.ua) }; + if (method.toUpperCase() === 'POST') + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + if (url.includes('music.163.com')) + headers['Referer'] = 'https://music.163.com'; + if (options.realIP) headers['X-Real-IP'] = options.realIP; + // headers['X-Real-IP'] = '118.88.88.88' + if (typeof options.cookie === 'object') + headers['Cookie'] = Object.keys(options.cookie) + .map( + (key) => + encodeURIComponent(key) + + '=' + + encodeURIComponent(options.cookie[key]), + ) + .join('; '); + else if (options.cookie) headers['Cookie'] = options.cookie; + + if (!headers['Cookie']) { + headers['Cookie'] = options.token || ''; + } + if (options.crypto === 'weapi') { + let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/); + data.csrf_token = csrfToken ? csrfToken[1] : ''; + data = encrypt.weapi(data); + url = url.replace(/\w*api/, 'weapi'); + } else if (options.crypto === 'linuxapi') { + data = encrypt.linuxapi({ + method: method, + url: url.replace(/\w*api/, 'api'), + params: data, + }); + headers['User-Agent'] = + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36'; + url = 'https://music.163.com/api/linux/forward'; + } else if (options.crypto === 'eapi') { + const cookie = options.cookie || {}; + const csrfToken = cookie['__csrf'] || ''; + const header = { + osver: cookie.osver, //系统版本 + deviceId: cookie.deviceId, //encrypt.base64.encode(imei + '\t02:00:00:00:00:00\t5106025eb79a5247\t70ffbaac7') + appver: cookie.appver || '6.1.1', // app版本 + versioncode: cookie.versioncode || '140', //版本号 + mobilename: cookie.mobilename, //设备model + buildver: cookie.buildver || Date.now().toString().substr(0, 10), + resolution: cookie.resolution || '1920x1080', //设备分辨率 + __csrf: csrfToken, + os: cookie.os || 'android', + channel: cookie.channel, + requestId: `${Date.now()}_${Math.floor(Math.random() * 1000) + .toString() + .padStart(4, '0')}`, + }; + if (cookie.MUSIC_U) header['MUSIC_U'] = cookie.MUSIC_U; + if (cookie.MUSIC_A) header['MUSIC_A'] = cookie.MUSIC_A; + headers['Cookie'] = Object.keys(header) + .map( + (key) => + encodeURIComponent(key) + '=' + encodeURIComponent(header[key]), + ) + .join('; '); + data.header = header; + data = encrypt.eapi(options.url, data); + url = url.replace(/\w*api/, 'eapi'); + } + + const answer = { status: 500, body: {}, cookie: [] }; + const settings = { + method: method, + url: url, + headers: headers, + data: queryString.stringify(data), + httpAgent: new http.Agent({ keepAlive: true }), + httpsAgent: new https.Agent({ keepAlive: true }), + }; + + if (options.crypto === 'eapi') settings.encoding = null; + + if (options.proxy) { + if (options.proxy.indexOf('pac') > -1) { + settings.httpAgent = new PacProxyAgent(options.proxy); + settings.httpsAgent = new PacProxyAgent(options.proxy); + } else { + var purl = qs.parse(options.proxy); + if (purl.hostname) { + const agent = tunnel.httpsOverHttp({ + proxy: { + host: purl.hostname, + port: purl.port || 80, + }, + }); + settings.httpsAgent = agent; + settings.httpAgent = agent; + settings.proxy = false; + } else { + console.error('代理配置无效,不使用代理'); + } + } + } + + axios(settings) + .then((res) => { + const body = res.data; + answer.cookie = (res.headers['set-cookie'] || []).map((x) => + x.replace(/\s*Domain=[^(;|$)]+;*/, ''), + ); + try { + answer.body = body; + answer.status = answer.body.code || res.status; + if (answer.body.code === 502) { + answer.status = 200; + } + } catch (e) { + answer.body = body; + answer.status = res.status; + } + + answer.status = + 100 < answer.status && answer.status < 600 ? answer.status : 400; + if (answer.status == 200) resolve(answer); + else reject(answer); + }) + .catch((err) => { + answer.status = 502; + answer.body = { code: 502, msg: err }; + reject(answer); + }); + }); +}; + +module.exports = createRequest; diff --git a/package.json b/package.json index ef94503..b3539b2 100644 --- a/package.json +++ b/package.json @@ -13,31 +13,38 @@ "postinstall": "electron-builder install-app-deps", "postuninstall": "electron-builder install-app-deps", "prettier": "npx prettier --write ./src ./script", - "napi:run": "cd ./NeteaseCloudMusicApi-master && npm run start", + "napi:run": "cd ./napi && npm run start", "napi:pull": "node script/pull.js", - "napi:install": "cd ./NeteaseCloudMusicApi-master && npm install", + "napi:install": "cd ./napi && npm install", "napi:setup": "npm run napi:pull && npm run napi:install" }, "main": "background.js", "dependencies": { - "@sentry/browser": "^5.27.0", - "@sentry/integrations": "^5.27.0", - "@sentry/tracing": "^5.27.0", - "axios": "^0.20.0", + "apicache": "^1.5.3", + "axios": "^0.21.0", + "big-integer": "^1.6.48", "core-js": "^3.6.5", "crypto-js": "^4.0.0", "dayjs": "^1.8.36", + "electron": "^10.1.4", + "electron-debug": "^3.1.0", + "electron-devtools-installer": "^3.1.1", + "electron-context-menu": "^2.3.0", "electron-is-dev": "^1.2.0", "electron-log": "^4.2.4", "electron-updater": "^4.3.5", + "express": "^4.17.1", + "express-fileupload": "^1.2.0", "extract-zip": "^2.0.1", "howler": "^2.2.0", "js-cookie": "^2.2.1", "nprogress": "^0.2.0", + "pac-proxy-agent": "^4.1.0", "plyr": "^3.6.2", "prettier": "2.1.2", "register-service-worker": "^1.7.1", "svg-sprite-loader": "^5.0.0", + "tunnel": "^0.0.6", "vue": "^2.6.11", "vue-analytics": "^5.22.1", "vue-electron": "^1.0.6", @@ -49,15 +56,15 @@ "vuex-electron": "^1.0.3" }, "devDependencies": { + "@sentry/browser": "^5.27.0", + "@sentry/integrations": "^5.27.0", + "@sentry/tracing": "^5.27.0", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-pwa": "~4.5.0", "@vue/cli-plugin-vuex": "~4.5.0", "@vue/cli-service": "~4.5.0", "babel-eslint": "^10.1.0", - "electron": "^10.1.4", - "electron-debug": "^3.1.0", - "electron-devtools-installer": "^3.1.1", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", "husky": "^4.3.0", diff --git a/public/img/icons/android-chrome-maskable-192x192.png b/public/img/icons/android-chrome-maskable-192x192.png deleted file mode 100644 index 791e9c8c2c69ddb7be30cef2517dd6050b079cf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6401 zcmch6^;Z=OELgQf)k6?%11&2Ui# z(!qcB$^CLg%2H*5K!$FB;&=%a;N9W~KNbwXf!{>kz)6qVmvGx@0bc9FfvoPf*RrD+ zt!t%kcYNpDVeUoh3e|0wD0kcBPtGR#Bf8Dnl(iUlB-OI?@VT;6?n{*VYd(d$Dzr2o z}GjBL6tp)Ts`WdsOd#28IXEO->cnr~wS~O)^t!X@=c&X*Mi$wh93fX`A0g4y%9W z&8@6kX)^tG=#NY`^vxbkxhI@$*e7i_-geUqVM(1oJ_(jn*w+ zkP*kA=^Y!V*2mIJ`n7B0tyDRUQC{!$Ezf}3>+p9U0X0RB&Z1r?rEtrt4!^t}n$Xlz zX65YHHnGi}kQ2?SjB#s2!7hmSYWCmHG+hHBhCL?CI=8X}hE~w$+_5spSX-S7&y8=L zwi#x6cHZZg1Iy*MQUUmnDcNDyZCO7JFa7OW2;gemef_IlKQva9d@YV=k!6>zPF=eP zQA%X&F@`M1dY-`#p^NIVUVKHQyIuvRGZo~{TjYM6UQQUMfRp+ezKPlTS++BMJOB|) z$s`nPGVM@LDAvzAq+_U1-qD!A>aD!c!CEca)9j+NS0uhy$){5)|4H!gbb%R4CAiN) zFbDTEGN`@X-ZHx+&XDj>+*@j<)GCojm$YWd&@b%A zf~-_|%@GYhxNp;V(Uc`Hmopi1omT}Mt7JY;&*TCw-%IC?o<-9=wQbbn>)uwQ9{rF^DT6d1HT0;eV zZ~;+Hj`+GTMS_5=%i7{}YE;)+80`UbTk9p4gJ{tRE|eRvm{e!i=kPhkc)MxgfDEh^}0#%0w+PO32*NwIB3qkbAun@ ziq2JY6`#NdI@&ZXna&H!H?bbUKn`$Ma<{D`LVQ)a{dNR(d}QCb(a6fqm&5aF2SHr7 zlIyIvEhk<}?%0H$NRNcHNAwa^mombU!SJ+8&h$xKPmJn({UQ}Quj%V+zbSk& z;9g6bWRi@g4s|fg?VCckTj|1VQF#p_u=OPGwpWW%+CIB+1w{nNnjmEe0;+I9bQB|R zeVsVQK238o5W&d;tBiZH15uva#YA zt}N^nGkt_!Q?W>Ky@0M)7JoteS={z?-XZ?89}2oj^S^|%GkAX57&8A9GmOEc3gy~= zaVf>G{DA1-7Plh+o+y@E@9J{J8{qkRv~kG9cU-FFml8b+O^ydC$jXic1tjA| zk)4GFb=v;tYKQVwJ*R3)gnIw?+X&0Ts7rC;=rpDnJ9*`Hvc@cdIvEk5N!AqeA>K|? zoy-jcLwHw)v&gc_TzO~mcsg=Zw7*|HkIW7M&NfNolQOPA0JnMTK=!5$t{5GDlO7XG z9Vqqx5CP$$Na<7bZwD|#&WXrtZl`AKYMv+IC^{Ix5ofuxw+A`3l!)Z%%2OBe?TzZ=SVAbZ_hrw^= zib%;TE$H7~0fy||Vwdr_Ek7(J@a#>$LH4fZEv^c&QD?NKq*ahz>kK}ya3>{}2>doQ z*YjT#@4b3(2_Q&S`5?+5&aAHZD+B5L#^)Wzpxw)+=?m$sC_Y_9;BW<%gW_G7-HGxRW;QWF^yQ~qomlv)uVIaBy_4uR6 zf%fOmn*O@Zx3;g*^MkVwxm>IFGNs4$bOgWfokC}oA=#Qx-GI!I+$2v!_Kp4|VMrB` zW2oHo(@nP0O8%wONvb*-R{@=JIc9XZH@lDhGcGwsMx30dBsego3{|kJldvDv@rSEi zo}=I2m~Av)fRrtDq`K9=SnJe17}2!93*z%_zt(ViEp{q^qP_l`il452-SFq{jJ(-KtI5`8Z?<(l3dlhe!g zv76mceV6qzT~3-_eO^S|Tq?|)ZfDRn-qRb#m{WY6p1y^N0xthZZ35;|PAZvvD0b9q z)#8`gch;4?OF)S{uMqf;OSG4pk|z?NKhNel%yeCW?j60aQVRrC67uV3nU0$lo$HUMb#M>)rwpKCi<2` zZ|u~lk^5ny6nmZqagE>y(5=&ztJ8Ty)21(z8jj;Mu7Xj^>aKB9{L2Xakv1B|4g-JT zh2ObGa^WeSbxN{r>t?gL1hUX149=ooDG%xO`TaV*1V{ zXQUB7xMyQXwbnc#jVSOu2sK{GXo}UcIJiS=#M#o8%_IMp>TCpDDOcPWf3eIw`&TXH zT4DjS?a8v~GU|RzOU(97#kW@SOeHTT0>VnDxZaGgj}EwTOl8W9CZ+6Sx*1}VEHIeT$*%J+K7x2 zSbiH%F@xn}U;A&|fpbyC&zc~JA-c2bjT8SA=V=gu*va&mE>WixpSz5#xfH8e6-$4P z`bfg$T0ZeS@0xhOd!3BeuUvYGDYdHmZo#WxHIA@ks!lGD#kIPVKD}*kw>}|Oxr|!= zE5X?VljgRjGo%Z2*wOEu&X`M2QnQicDRBUBCUAAfhbMb?2DciA64px;*L=Hgx+xLQ zCr6>~nk~d13^RF!_ZGaNH^E7P#bii8!$+Kg^>#7j6GBFu_+wr7VjcLbREi{y=_GQ zy~4~a>`k|>guubxNuj|sP?5#|sM^v5L`O00eFr_ZqW&{Te?igQIMoPgauG9@qt_Mf zLyd84?eFf0Q@==zJlP(@YaDN;iJHWBn)Lk4KvQ4%Pa?xCo~P#r2Nzjnq=Qn$K~sh- zuvxN-#YreOiH)ohYY&-In?HdN#ggNv`5(Cy62*c#w5}=&^9C*T`=oNdjnJ7P@iBeM z_(OSzKuC|EGXO>iC;UNcR+_2!#yp+}KNuEM=DCP}w~W=JxVj)AANC7jG4q8irOnGG zkr~{H4XWWX&s32G4v7k;aGqM$9As;{KuN&|rvG7g^mRJYA+AhXsXcUg?LTg%ZT#lx zEMcv&nj@_hr)Ab9)vDUMg%{;RscG&GZ3az5Z4=KE%6OOl>jGD{i`@S=L|H%#rRq@wCYEKlFTW4=1tm9xE|z(M{mO?e{C1i-aG=+_` z9h}O)3bW;SW4rn0axQo`+#&-^X1Qa!l3}xSFA@QQ-S}y3OPPQ z2Xtt2i}|b%_TQKrMi~s=>c#2R2^5Wgc%Qq0Ybi(ym)dK|N_-6a^Q((p1$qPCfgafB zuRfatu@pSAGiot(;B9GidlTz29^fgJa4lQ810io!<*2_7*P8|aC>f9Ujq-Qisg2N5 zMAim9-X2aTw;ghg_bVSikFEHP?lmKwv5+2S_?O=^KrEk5?`VX)NkzJrRP*@hczQWd z!A({w<)0jxf$wTZJ#xyix~Mk;;0voMd95LSgfohvX4fZlLfG7_5gbFA&X?&F=e=@I zlD72eW><8Vyh=`kAiWbE#P@=~>1Iww>i&uPDxd$@9%!F2X*%C|YjA0=`e~T$T|Yyx z;u){>db%BQOU%z>^>V6XJ02}HMvKf`cgXJ>aDs^&5P2M4owY0{oV6lmby;43>Bn~4 zqrDK8_AgrtY2W{l7@jL>dC8sNGM-2hSmp3d>lus?{U%&uPJ*Eg9Gs}~O)5;yLA*A| zlVvf2Ggh#yjqYiZf=_cI_Lk~U@aWm6qm-ionlufqjdvC{(je9su;P_o2k0(HCWpftF>fiFX z#e>|96>mL{{U75R`gM!kr8RnfG$Wo|SCmfFt;Far7aI8)a%qOD-cUywKvWdYD zbPwcY=Cq6zkv^d5PZ_k(O(h2dRnO4 z^`z-6OF9#oiLj5n^q*h)#ruutlUUH{ow)8aVZ_rT^qhQxzMdGWGN4sW^>O6)A1QKH z$t)6w9NGIV)UN=|1T=&+j-cu`2Ac0NL(Mu6243?J0Z9(Z#y>9OTG&NM!=k6LD*Kh; zwEEo3)X?iz-BaozW8Rk?M#hL-CG=*EKKhkW$de8*By*iN zL9|Q4%j;66lc1r4p%e6^v(~Tgz|-J2aP9ROv0WZt{DbFupvtH#=g+u3@qTS9@*00T zQ`+sGQjvvlH31041z~N=$*|o6$6oYe*4`!L@ozx-vk6>B8-4$Vp#bfvCtiK|lq6a{ z{F{A@_BT`Uuai;bSGf1Yz5%uS9dAwXT)tW%NdkzW z{LsLwfC9^$R{)mBm$)g8Dej0`XC%#U&wX;TsOaDBCQ}Z^A3^^T)onu7gvwaGtI%wn!qpU#0>5?blK&%DFG6*ku?7`5jn#u@o?muwqh!HUKgXv zEJ*9uGz*JJ<{J{AY+1KUut!!1tm!GR(^Aqali0HGQJ~W?R9eVDqGE2{3?;nxmO&b2 z9`VR3&}#K>WjPsw3+N?RKwa4M$*$1%4N;&C=KGcG&ucdpdYCJf<{P5WW!cmp76EwM z1B`|^U0K`p9mXqhENIs*+?t?g03yVOkWiArl~T;uv-AA9@@kc2d!OdU8esMPQh2`n zlAWdUKs`y5t&Xy2PjUh~nHAmy^Gl}6 zg&CNxIlk`9rLQmC92GY4+ZC_CY3+pDA+8}^YD>~Kl(z0|DWE{l+n$qqsukb6t6<2H1EU@g#hy>vVsnWzWDB4(>$%neEW10eCZLYNi0q3V=Wd68IMH zyJXi?Y>wcQ3+k3aY_3W2WCtx{3TRam6k^98?H2zKQ_W$?6mHHgF?{i5W7wOJ-?ap* zL;OlKw73%_hUX z{*gRrqL0QGmBb8w<~$7R(*vO^e~bwcDGV&=Arx9~hij>BF~UZhl_0pSRh#VGPgBon z=;xfdF<`9|Swmd#1wBABv=rAjHopRyYE=#HmO6`Sd*f?!)uu8F+QRPo&tNtEZ@}Lg zV}g!H~{aM`dp@PE=R``+vi3A#T5FJ1mGo&)3YUF4<9 zcH^-hisTGGOo_&~puFVG0OPeuiIpLs>tt tIXE6m`vU*OhB3K}4dm^j4weU9wFJ2{E)Ol6_x>$`YZn#4tt+T1bnvV(dFZc4CxD zQTAytn53~Y3}cw}KHi`EzOMVa?myuE<@;r2U8>D13gR6JVP)`&Szu<{EhQVzX;E42r6_@d^(? zii(1p&;1y@L_s^itEA$8b36~eG>8%buOgB#@CrKsUK9=f&oBR<)qwwhV&f^g+4cQ1 zVd)DN?}ee=($!v0ZJUwv|9{Mw56m%Mxtu9fditt4eBYVSB_8Gcixy@x&ElK$yQy=#q^!ll`<}{XxyR%EwmW998#AjX%8kEgnzSZuyEp@}F))FRbk& z`>Tz0)OaOY@4klaQ9rL=h97P$;>sJga>bMW^_!s|`hR}3M_*3~Su5Vrf7>Bjk1Pj| ziv2ARm6h>SS=n!Bz>eQ&ZV`RZ<#O;V3|})cUGcYT(N{jVV<%NV0EhQ}$K(vc zYc&NS33nxEN&2;Nk@LbcVfh5d(TIV?$!vdw@6gHjuiy2OLdBkp`87@HkZfJ>|D4yK zvpaj4dgDUL>n9_QdB1(uYHs3-{`ky=4~xKm{p;~vi=$0`KboPUsx=yiQFDCx>>-T3 zAA>sFqIy9nykFtyP}=UQy5cs>z`IerT6nY4>{rxDi-MHS>hO&#zLTFnxv;k;9aIq6 z2KO1RD%%f*ikyQ*1#nhsrTsbI+xd3BYlMOBmOBoYQpQ#zCD9AzzC6zJIcHZ>*R;?X zxCbLecja?6yY6Jzz4ktFvSaN=$FrBvYth^Z#o<#)c}0$$dUpyIdBP>x`sooAvFyDb zNZY&7Sk9wobp6S#9huI9&uKag)xD>AS$x_b>~*$ip-u81#VF|axFmGuku~&t57x#} zh-`e1z|KP6(s$+HO7VAF`zkoZmWn@b5F@kgvxe5Ado=Rti&)OLYBr&i-FWNfg|o%= z)qc~>kG#F5OvMScuhLUHYTmFrFLrXBOw5L4wo|w0?un*gI;i>w5*n z7pgGE7T;l8zS@;O!c>3CVdDX8n!Hx!j8_IQPUbh&3W5 z=qH|m>g=I3w?OBniI%2;+mvdTcz9u!iQTo247ZqzJwft+!mwmzVhsCY(?W|cd%TkV zlKbO|v+IirboFhoh1mWAS%kfhx#uhK1h9|$#eb50kQv>?Vaw2<;r`X2et-DV(s3DtNRp)Wa5O~~1`cNfksJJ%@)_58EdQ%aG@Cb569NnuK}AEr6gx{F$> z`(%=Yb@wPMC?C0G&n-f0H1(A`bx;gGa3Hxy9)*O<`yL-v!9_m^#a&4HIQ;_R?-E227@=zfYn8G&u|XS{4R7Z zjHp-&NGIY*)(OS>HMz6D#OwG&7bo~4AV0+iaAE}@k6%dvC@=LJlhup8AvXPeDh22ui625*p9Ba;NRi*Ax2!-NpoLT?2e^LNV}{# z`0_ug);3%ubF0wd$3!!?n4kNt{A{^rJ$DPNC=06~IE`r!JZ8j@#YMB~Kbbe;~!#wd9Ve5`~Bh3%Yc5w-L*U|_Bx;U~WF;X(%4Yi9LZcI%4{Rz0M;h zp^HxFFyxi6&td*h@~u&h&0&`q1^;58-vu!1?&6ksT^m&>BJ^*)QQ{4K!ck@7-lUkK zKTvD!@W9U+v1qbyz>xkwnlHmjf8Ui6{A|(+AMk0QR9>XjmGz4Kscp5Up@N^I*0u7O z0aN33^AViuCb8{Zk2>ym2y8(|>&DlWj=ihmzVRzIBC_q8XOUJ1%L8w66hQe|TkeO3 zIZ6h5p&O2)Uxs#xA-hX!1DxcpnHnwzo>UjD`_qZn7{&c7Ax!s$^%=Gv>SNR631a~k zG}P4o%fdz*D5~2v{Q9{HG`(wnc?0Lv+~D>-2+BkgNtIWM{J}c8;+aKEr(Sm5%918o z;{DdR6>O&1H7yTD4)Hb826OYM>Dyx7$gOGI82^;wlpn(53UX&=mNG%cz~WZf89TO3 z`LDkIQn%GC;|8-UO+RAG)I_S3Qc~V7;^)+ucgPAYYPb93&MQFE+!@SlEx~Jn%TF1u zQ&UZ*oK$%8bcMjbecXPsuuk1xZ=-hMYjD0_)R+u&#y=5n+Rb84adZA~stbm<`MI#Tq-ESH^u zJ+q2u`qJ3QN+#c#&b_UKbBaW8CMWLjj6ThN>C2<0lw}O~VOy4&fqYdC8TPluF9=rz z5fm$sqPMd`NioYr9^X7_7*7tz7CEs?)o0VTPIc( z5S*$q>l$VW(+{M-ldozxB!yvV zp7-3>7MdvC8oDbHp~0v#(o5Q6(Aj-L(+v_%(301hO@c^9H5m?~H=O@(b2pmL-Li2L z+c6c^N!!LfQYv4~>Y4o#Rw64b#MA3XIuVuBXSpBN*I6^!8* zV(--~?3-eIMt0J6Ps^0*|FC%*IgV;%;#pPiLlmyGS*#wC9p;h#DP4Z_a(!lW8l zHIQS^PUN1<+jV#HO3CmhJ&eR*r^+VYF!tufw5kxZQH`cydY2bTuj{nJG^G(dv` zrJEs|8W}KC!@0JS$d&p>_a)c6*Q2djt)k*r2zF$;p}>zK47*;Vc>DEN3WB484<5Bb zWB<#3R4?k>{K>{%f#W4iYw#Y`i3%)cJVAk_u*$3Cf{nW5BW18-K0gOav%S}%VHbYX z=U!6Gll=EwBf+UM@vZnlqhGqb)pTj5Yq2N;9n{~+ zvaVj=deeQftFSi+TibJ+QX$uky-^`&S+m#Yv{Cc&YJ1@X@s2D*e>HNo75id0br^t(+X0=Obk@@Iu%eHuaOaoSq zpMC+V2#+{l@}taMUGMMNe~_*mOMNShW>eoUWBb(g+Ez2OrfGwU9H^>OoJsQC$4p!( z+28DCnCX{uzCCB6Z~4m#uU0ykgI1^|bk|ncx7hH0V!qOkH}he{Kx&nZp74cuEK2}u zjmQt@54sCNO>W*&2G1N5zjKugIJcsln}bV2JvO9Cb2IE?7TP5KJ7`p9x2t5PnHcBK zs138=`vU_Zm_GE_>9s}LmP`9$TUbzL;Y95Oe^+zD-|%ts$eM@}PDw=EBVxdpl1}_z zpR%{fmQW@Op|^@>nK2GE^IZ&}il)S@epu9jv5#%{m8XgW{wBY1lzMo6?fSndnDV`j zE8`b_CbM(UDlGw#Roz<$R}>W)Ob|b;YJ%D9x*zgGi5KlOd-?7=Y~@vk6ZIA&{%;mi zA2QcV-41!L-`fgnRlgh$_qMu7iol|!GT*o?jHF|{c(iO!qv(fc66=SDha(kQ`9tsz>y?)BG!d!|lPc`g!2c!tPG1o1CaS;6hL|Ps6q;wGR9wHvAzb zoh$ErV1Q8eZ~@4u%(v!<->7TRT5|KyKSCySex4!*%tT{bwttpaga!|u0}YE>l!B0X zu5)KubwEnDE!N!yDZM*YDP;yBQfj|v*R`77zyy-qVz;A99mSG4B2(WF>R}+C)x=_7 z(9OW;sPDt&wO!jV-#Fftl8o#vK%0P>9XBanwrfsao8Kk_0RGD=Zs1);&ByJeIT3Z9Tdu*N>^@W2J9Vo&rrO2S;t zrIhd%7x1BNO0cvuVi4`t$WZ=KoZI8wfGn#S0gwd%SO!FPsb#P^J=hU8iDD|x%8610 z;QWu1r5b;~JLA>t5u#NxXhUWZASll92T%teKyK%Av)!ei|GWtMb3`y1F|gezT|NhT zqJ+D%5inmj`AsJuwguLl!Jht9%-*B+x$5uI!3QT3bVOfp`0MwEPEB*?XhRgP9gCg3 z{TV$?-qdg7>V^cSIOPxPCie-JIma!S)1BXcmnPC+Ciy~MsL<2}rEOPVBy>Lx9-77t zOW{Aw03EGlY6zJ-$th;5>BUlBMM|{_!zA>iU&sM;_1|173Cw-$CQ4;c==>EW!chvC zjm7w{S>IxuYLY7h&wBP1dmb#9{Qo8*bU!U5zsfif)%b(&*6-E%8)=b&(yr3Gf&m4wSo%c_ zPEcavYj=Y2FWKu^H#+n4h$gd%h0p2DSfY~#?_eC{ z_Bl7Eebq+jNVDQGd7&QLMtkg$x{*e2_6wz_;T~xTK2m2c_9z-iclk=lbr^ z;MFEAFe7aVl(mP6n3kPWh(py&w6)o{)Rmfhs?wy(wMCJZdPyw{3IE&sQy}>$x=lQ2 zwGFrfXiu~3i*{lGZrNA<(s6a$Z;xZh4NvmObRTghZn&JEsfcyTlz_`W3gFbt@aF&k zWb&RV2C!d$pq3z}!}#u#B|i(t(zGkr`>!;YImdw}!XyoY0q zV8t7GzZga261>w-v;8JFw*PhE`LfwR?L)o(^{E-9jX2&R_y&w3L{<%>y1rqIV5erd z?eT=j1a1qZmuA``yPc{K-p(qdT&cg8Hqtq}r{vz)H#JR0=w1E?fW|2#hgF`@Zdhxm zIn2^s4xAsO^s#HyD~!h%CRUPT>=9~AszXYcu^;M%v5F}ZVK=;ZaJbG-B?kg+FwEdG z!H8hSt`#!cxU_M3Llk3C)s%@oa-EUzZ_O;Wo~fY4t95?_&P{z5=zXmn?Q_oNN1s|& zGH`FXQ*+mUCKg2ZU-4aloMc`osa|on9ZoN2U#S^y@okzZiuzau1M|0R#$r%NStid< zWrjIOW0x+(w$l^nFX_8>+ICxa*ddzi3Bbz3t#zX)LF+J_<-+bQhbL#A@rE56$li|^%wCgMU z^1J10#s3Bjg^*8~B9#O39!BZSaQlI5aS*zGz$TTm4<_ehk^mogYL{Y0o!Zmxr|_h7 zG9cK_AXB@!H-sPL{*(KL_)K&+5iqRqb+u7;0*;C2d-3_m_aFh@Qli|zZ4cS^J>Qxj zg;&MBcVY0jB2lyZiAKdK*2ug$mAGT@sO9XlNv>kQ3*dl)BTsjA??tU!5w&uG15Yf$L-3L=PhX%=s=H+QdU=3*fl=WN#}G20{s_Hmta}r?YZ>p#FNQa zw0Om_r+#qBF~<#{V;R=1)`Qkd8o6__g1@R2Z_m!sP0(jk^4zm$-gRQs2PFcYtQKKb z#F=xoG==TC7xnda{toA%U0lZK54aKZn^?ozs18JL+|{kuY;jjyoFb1pfJU9qdx9;F zO=T*a6NIkcc&!W9_zUW+hID3Fz0bzkh4^`6C+5_r>2bB8?ygnb9~n<+O{;)71Agz}P{QB&WEP+QqZFFG{MQbvR z(p^UiOR|^%7Cr;rR10@RVRlMwpRHJ7g!{(1jq@8qPyF#Ytn-Ygd7K_(9oH0sM;%WT zg@cfPctp^#%%$vIQOirzEuYHmJD1g5x?{pk?5e0dw+3oP-RNo+j3Xn#onx;BV!hdh zmb}LS`@TdG4<50>6}ndD(zpe*!xnnyCy+5B&{sPhk$NvFu)8Dak@v=pHXC%YUC6!D zVt_lYDOPPQE+z+d+wEC2LpQJQ_{b}VG&wBCzByJ)WLKZNMPx-pRuccrs#p4~1o2?8 znd;0Q{`eRH|LmCOx0wmk=&R=f+HxSd>=K#9(x1|c<=m%luai6g!*<_sH2s5Q@|CIu z-cUpvrgKeN(EE_V{iqh()y9?p_Bc^2Ss@VtkBnGtE*&%HW}!b@&R!~X{b!Neehw7T zZ6Mzinf`(o9#d9kioty?n(FNJo%HtBG#R&@ANoecE<`=s{`X;Nt*X?BT|hm-Cuk&A zwaDpU^S+bsqA~YHY#bQ9GE31w$nxCX zr(K%o?MUxNH~TC=58^5nZ@c71yMoU3m3-e&piKO*DWL3EOx zFHkCc@*~hgR?lG?*RYgm=eTG_)?-#L&`5T93^Zr-#ULXgL#h79%6KyaVA!*aFLA^@ zMPDgQ-ajlHko2!FKD-FKRpRk>H2M#fZ^7l z*2DW+c$IzVX8wY~bR(#nSU=P|1t893hlXub%!-@j1+bgE76Hi{dJsz8t1r^?!5M9s zDSEpm=*~uH`LND)_N5z0+mInM)7aC~YH3ON>;f@yrtTU;B5{$hSF&lbk=G$?@5T5$ z)c2)P-|EJCEs`(`hI^z4r9zwS5E!g9X8w;w)QB;A?MKry9rQrN1uO#3>!gScxG$l};u z;}pRIQ0kc(3kWHl`CzXwEUC)G=tTT;{q{WVN4qC(^t*o5QzMWDmq4(C9i_pKm^2B{$_^(TTc3{BFU#fx2OAgN(j z3@Xe-wmmJ!yLh?KwgKX-YgV8{_PNX?X_0voyUIHPI;tcb<$LXXwu?YN-6^70j9Tf@J%UU}eD z+BZk}+JTMC3d;@+rdH?0;MNP!ZKVAJyLJI85U$s%WT4i+sFtWc;2JWTA*y{PvAdpA zCsFVHM(F;o_HwTXGH!EC4wZ6J)U8on)u%Ai63zUrMwe5~FS`@7_xb6ITmr>T704$a zTF|LN_vcRZZ}5z^%x%4&x;I2GxX#EkhRoYiIszy!`HBIq9KU{h)-vvjAoLos54vS9 znL4wY>^auJ?w>bi7w5hF7Fql!o2w!9I+y=JScaG9&_Kwi=mj3}QFxHiN(~Ce2GB_js0$=NI z-DQKF)N#28+qwLp6~B0|{QQo8d_%Z&6uJ8oK|^IKsfs9Ty{JZwok9v=_ktO@VuhhK1&GqIYym5FL}&A zsCm9|hPB*-3s$Dsc43R?{s0LV$nrLfcn2Us=>8>BA#VU=wmpdAaE7TxPQC%dW<4Wc z4y0%UT_RwfmLk>F5!w^{elBk=f3E#6_EQIAV4)z zwn{>Rp05D`U=bCnW{^LWjzE>}tHqgrfp(dCxQvq%w6#1g#Q5CRm}wkj^al4a&VK5+ zvth}-RJ#MQWQzT5)(F;TD_EbikYuJrs_5f~QGck^*U`E_*fg`)f9QnSm4=b2{G*yV z9p%r!(*V#NY4iM9$}G*%r|K(;3OG6gi=^mIVQ3g=4fO{V$@5*^EqeTiK%*!1UHYr9 zJCQx({OXfZZ*VW;qfQbk>3Wiv32U6c3btl@=CXt&%wW)ZT9cFFDwa8RU-_wHWKkGq zmesL?v`~~C)f?OKS?tHLyFo5Nm=_gyOXwwcZxz*FA?MS7jv%jr05KM4ZoG^NlFSr3 zTdZ146|2#DU$Rf{gw)|a(Lk(|B5~5YV(xbUyPsi*>nQ8MFXY>C3-<60y8$#iwgVEp z<*jA_N|*AJQ02^HlzPiXYwUOQE|&fk>mQ9A5;O4aP+`Sf=3Lg?gGWhrNlr;9lcHsX z47Od^a{)+>f7{}rkiU}1;4P_4TkWdVi;-D(-jU%X4}Iq#2aKbl*NuRojqb=&DU`&a z(s#ulibouk)!S;tDQiX(5^(6V_0~coKn|~Zn=@prZ(5)Hxi~u0Z-O{qmZ7|JH>Pn@ zqfg9i_MAc%OmSCkVg-~7Y+bSWcYQDOK@4{*lRy~6e?{I-lnX812G~joxb>aY0=Pf^ zr}QLgtP*qRy_splNDA}cqw_-PSQp{a&Tg%-N;>-EW?ky24B%+};2yjs2wg%zmS4bg zoGKOSDR^wtrP?f|sXJ?7aN=br)(`hgzSAmw@sut_ho-|nlO2}cF}0d@L8V~%9JcQq zzim?q6@Wo3OJ7*ExS7yE+0!!9QRlZRfJ|!jyMOdcTqovvQIw0PyiPecK^zxn~IlG0C8YxXIsFCCuTgH5_F&Xqv(qa-1>O`SwKS~>osQj{O@htJg2 zWjcKadn@1`thyRFS`zjt19Ar+M5X7g_)ayrO*u{N+p3ZP06G4KE%}~mQsiHJ2R?u^ z@!piCAP<91T@r#7AG5wQUArIX%0*E=8`l=nIhHGWCI^A0_uT_&)B6Gnd6kYz_eu{a z?JwXaP5ICYBOFiYt)C-p_lzf`)bMfugt8&7rpsNA3#m6gZ*vmbr- zx2$Kn%F3}f`)oSax=)Jnw^(oYO8CitnAAy5UJc~Wka^b6F=<=2h(NcIEuSvoh0XJ_ zMe}unef|7rCud8}?7!_YS^1$8HZnIKK`-+C>fUiBm=!9DTNE#)HBYRMjo^luV;TRvR0j-)PwFZ=KZy~(#3cTowo zl!i0s2FM*<1zjawh@G~JPf2#q3->zugifQVHlWvU)8GwmgF%Zbnmd2fM9lO4C~UV* zKm$1AvwRz%#{d9l6c7!i8K!1QO?vZZzT%qQrljZI+b-stsmohvSLb%*UYxSl=YB#a zIiY#=2sjiWsQ_&=6Z#B-aH;TaEvvt9)TUeD@Ec>9;;lBcoXcG(-b&SS*ach%d39)3 z%$DcxVCi8&UK+vfg$B3WdI~`jpM+rm;t^yrPX%MBSNtnC$`=m4+$dz&BTuI1E-3}c zpX^?`iM?q%cGa;#*RSc$Kh=KyV+6le%ns-`CNCdEe**k-l9^{&VBOtv^tWI%df(v= z4`&`(*jeLkj$EXD$XIq70C}BVIq7B~9XN!AU#50hMy{i%FQc)8JB_9F%`Km---Hwd zx5)@zlmWu4Do)+iDe?)xGug(!sQS9+j)sF#f_T|CV|c>VOWhr59dA3*o3l4XJigngH)S3YIp03P~zI3u(HZsHICaOv!Zc(7eYA)NsUu@)rE=mXF_qj0s zl66bzJMIC8^%QxQ!Xj5d0oZ;e4rxmNHiBz(7aAXt7pf?GI3b8!yTZdR9~0q=z86i(zWN8LmRdMl)?Otw10`~5=@@MdaT-h zs8zrOSjP%pW{3g-w+6VFuCxC3NdPEvRcvroP*=<2OZ@BxcZM?<)`7XH0N`2a8B?4i zC#xeRuP=}fC@POvV@Ubk|8A2oX%+|NU+B{EW)G0p$*|h=?$o=QAq8IdPLYsyS1m)4 zI%a7{#4d{}8*P@qWObsMqp}{8hFhNsU<=eff*_|?azZ`H+u<5g|0KZA>(yCnqxAM_ zHkl;HJfZ)S!tcWG7nq;x$?S4cmSj#w?)>kx)^pmw}!VG@RVkj>azTl2O#C0m~; z4g$d0_1o`S1F}!_+Y;G)fBXs27q2!!4Sq2}w%&c0^E61Z!d+Rhe@5*p&Y9!knTHwOthF|G(vB3olIja`4T`K#uj*^?r%r#_ zq!+)l#ksp~Ok_zyzq4|IXtJ>`bYCvn86{ai(CFG?9{w@7QFOaowk3!%WWQMtYR;tV zVb`-RiJi9o9f3p~n1}Kx+fLgG%Dh`ZZ|_0Mi^3rJBxQM<^Rw~mih$=XO+pY8ri#m| zY9*c=0P66c_uWh1LvC)mx^$4!Rt-l{&ibBBcO2gT)Z!_7DF-YUW64pmXQ8Or5unHbB?9TBawO?VI5@@nMNdt64o;4tv$ z^=ufNt>cb5Vt^$H`4T;C2G;f%(`+Ka$PkKJ$QJ!>CRF(9DPUrK99uQmYaEG_zWW%S zZU@-1SaWmjCGCK4{<1J{DfKff>GjaPN$d;9^(g@exK7^fxH9n)eB>(An~U(`#x_->@q!)!3&muG0o7i0#7-a{0998hXrS+cc}v# z!(09)0#&5PJlymb@wH)7zIZ3vMTHx1u)ge1ah(x`K-7?F4gd=yyy{`ATh}q=gD;5T z*+j;~@@}qIs)4^&140t#LF=lLLD?p_(MMtKTSNt0?4P5f(t_2ig>E~F+@v|t6t=3! zZu%6HpLWLiDIIuM297sh2ySntPwiTefXjU|>mGNUn z`lmdoA3MI>QBer6R~}t2h~=fR+iMR%tycjqGH6R9f&etvx5FIuVJ5~*_tRFjVH*Z9 zpB6A*X?D2hk5iLksq~FugpIyxn(GFh{u(49^5I#=?#si)kF`6Q!Arjl(-q?vX2;a^ zn6};bYUC(-{$#7svy*AjDC{gw3#X20?|XNp^6uc7#^1v{rTBU zq}td&lJ)lwBKx9I^S;M2f{{0WUD(AlJdMUStak~^Va=#+tbsoWYjss%VNBYUBpbu4 z%mFL5VA(8%VZfr$$0L_X}_9E8?dR(aW?pwz4KQ`AY= zY|-i(USpUakAP;-K4Q^znqHK-85`@XNmH<#P%7(ZJ6jBXgjza{8D#gepLU#~-)p5e14HEfycjUdiCvq$O64vv zuj_!q)W|LBFl~N!T0{wl=PDBhBS?`?Mb&puWW4pLPaNcL(hjnp7*|M~8BV0$qlQzl zCV2|19QrtjM$Uh0(;p%EqD9U8+`Hl>pP`zr(X=`m&u?J1aOWfYheh3AajE3LL2q-$ zBo6WgI%plt4*n(pQU;L;bYE0R)IM-HM}G?dtPg;Pwb(tmlmdTz^Eg@$qi}fTb7Cjv ztK846FW5h-JI@p~8Sdy`;i(Z+C{F(w7O)Bsq#FZ1lr_bFKZL~neD1%NfU^|-0Tsu1 zVEV3;+kuYr>U^Sute*Z?G5A7#PCI=~f9(rR7}GJ8OhMJSP}Y5|!j?9{Q1=otL<(%r z$YEa?N2&F9ZR?+(#AkUWow2)x>BzL1~Ir?69 zMBrA8#wyGH;9e&Iw5pZ&5K;>=rpVZ*>ov&X)nQ`K>i@OQ!prft}Shr zT9|E>HwA$B{$Ec?$&^ktO|v2WooNZlEHjb42X$QcY5j6&iNuEnZ|IR3%~<3r{%$5c z^X`u8>k3WxA*jjITP;fY%+Ii5=1F_87Y+*}MeoXa2YiBwCm%d{|FRR~M|kELm_yO3 zp6I{xwcWQpUZ3jK392uzHdldV*J8(Gs_-Yqv2xgX88|dwY)u8#c8eIi=2&r1@Wz#8 zR!8T5UY0lC8|DkXUY9ZeUa$+ znqLcR0#VcC|GEgWc?1+GAJC-dg!)}z8XtU__PvQyx845PwfMP0O=%r@UG;q^&r=kv zc!(>yxoED$NDYaqOC-=x@jx!p^5)ENuh)SMLlk|o5-KEi7fWg$lA}mVGDa-<{ctkC zR>o@^PdoLU-j|2aKNVI?^xm0SuTXCqX|dO~!?Rnq{ML9t&Z#;f^s;rUtXFzxf_-ld7~=RU;p#@nT6#3WMt^gO6!IPGTDi4X1qgPa6>t=x7~gow3Ak#@gNSb4}HpJ1E&pUyYLbz(7CY#!HD zOJR)}ymupDaCz`f7BHo1Qk}@7^G|>;wS#tNtbm!&eD=wg3}a;^WfvWIN62u$5@~$- zyY$8ymRt@rcY;kB$Qg-S8P=@cKNYvGj?7RJjYH2LGMWGz`RWqkW1{NvYt4X1$V9OZ)9Ap z6Vk8K!qpcL-rCS`(R_hqWOs@>LIJ2VBLv`?tfB`4E6A34Z7|9sb{zZ`I7(%80mDY2m=5f1E^|-Fl<%1Lx3G0DK179%B<3SSvoYR1a&+;4#N zBvq7c9q?TkR(wfV3|?TS&O1}}tHJMP>Nn#%z=Pf;ea~IWfIvvCBxubY04>Rh_^$LB ztGDW$m2>e2X z-a`4{QOgZyM$!*QqrkFD-WMV#+rFf~6|DfS8yuT+iw^%xA6KIqb*4N^{?C<;ytoqv zUAzjk^`v}db6}G*H29!c;nrL>!%S}Je$X1c{J;Qn)xbaY0K{%yUI9%=T^Aik&!PiM zb|Al_1oT^kj`mgF@w-ajcYCxMZo0NEIH}<9Ew54Dd%X;QH_jV9RbT0~D|?%^B3Dx@UIDl&VD3`qUJl z^MP0GCg*su2y|>aKzsX%0Eau~6J1iZE0_AOfV0?t7xy-#m$%Shh8)J-Yv{guSgj9QFD)361*@)nzF;~t&E`SQCC;}&tPHG(wqss zkpq+MJnUlC$z|HPPxLefM?!k>l)97grp{v5a$`~9`a=ksIIvH!FopUMvS}sKow+~f z?>b4JIP}zcvA-6;J9<+|@Xxqi<{%NPVDH5X-9MUEkpIVQ+X#JFkG(M;D4i1KD8`q3 zCd(^p&WXt9c;bOeje3r1L^YwB$zkJ!z$5LlDV}x71C@2-D==?+-rIzi2|1p2W;Y(% zZzb)5yF@t0}k zpT!g%cwPWMvFY=0UO1Km9Zgf>LAdEB!cA(&&?DFi$#{ZnO`}ON{<%G`&kq|pjRKY{ zgdRB2;$R|4)-+>O?8B%~WjD~)INvN^JNaL0V{v?rjy`R^CLkBgj&$v2lZ?c2x`9pO zHMK-6*%-kw(c;}{$z>+o0bSpnT;q`c{883IE^oDKf)3gFrn@V?qn+M6l=j*rR!w?JjSNgw<73D$@$1nbN{o}rYR4_2PK)&H8ZIT}#|qqhE@RmN zk_pr4(2LyIp}7tG5OZPbMFq#I(H^O>`kC+(&DY@V*4?o$x9r)0$%{rGKRy%=-aqhe z=6EnGRYwnRTQZtau~2mND0}`>fIh>nto)VBKhNEBVJ8m1j|WHLPBbO*T?0Q6 z$Pr}W=Oe6pL&WFuCxZKHn`&p;uo~i-zfZI<60-Qcn>RHdv3B26UY3irxlk$^cH1e_ zX80bUuy`6iA=N&6uEmEhnpCOFp{wzI==87Hbb34$hf`8;unhaw&1J{n+_7<+b)-z9 zUhUX+I3UrwO-JqZZt0-_;N{)MndRvpX>Cz1BfXqn(@73^uEe)DZu@uUD{AAGB-F!h zuLm%pegzhV68nvl+${{8Fr8DyMkhaZ5ND9 zU7&;9llhbX+O5a8JFg8{(nZg2e5Q9=Q1@&)SM~eA0Mh69sk;TCR4IMvl9|x9i$G{w zAotVMdB=Q$lVbj|tYECC`ke}$Nw1$Ft2uW&U(Gat>mMgq6P|!>;qt5PaBKGxl1u`8 z&^EoX^6n`@&*?5}16;-m-pMg+4Eu>5O-;BC1Yx8y4 z(F2QWo0dhgoy~0PmSlwOD^6DT%S#AOQvnn70f%8g4ZNrRVxqu%4P55(Rz z>87`Nbjl)4G@dx6w6)V{6=*+l54M^0ZMPy%mmEtjTKwXhg8wML6T`eX+R_;JVF5)tfhe72% z?0`OGAl--)eM|y7qJ}Gz@6c#uRci@eBsGJ3K;J?Dr3>(!zD4AdaNhSVSN4L1D$OP3 z8=q;GX$ABytaV_4_$=C~Bw%*`vE++N^XR!ovr)%p@1s;9zYf_Bg_#DvdNcNlG8}r; zDhw|ku=!Y$Lc)no121yFNo7!NrQ z46sgaBP*S1r|>`t!BB$H#hl|a^EzY(?|ykxUIYyV8`rDj_Oja#9fS;&tY5N=qQt>P zmZ+pjpCfdW_}5p2uAJ7RVT;0wgDOML{O36WG~_w{Ux6!Uz;r$g{3q1(vTGoKHT3w+ z8g|I}#yI$uYJdFAk7Jz{zHKYKB#EF=3=P?(0`m5Z2qgI^_XMc|Tmj3Bb_ICf2UN2g z<6Xn}pzze@n9J8m#B!QbV^`zYnsFm@Q=Jcc^i^TMB4prg{gGV+F<5{Ca?BrfdZ%5x zlmn0wPAFk(&YTa4+1}Wdyt={zd{2k0AXa1x40`bL%_h+rsb&yi1jLF@*H#>thdXxY zDU9`{N&zL^Wr5{d1Fj^Q0m8W%a8x@$C_hr#C%9e|1+3gopcdGM{M?4&Z+P7g=YeZCAuhHDwTvc#CtNcHaxx7YxQ$qv8NfIs(`{ zL6G1-{v!$>_*MYqF>M&JV`$b1fI(eVk-dQ-KzCk1x1_0ZOn{H6ksSuQMZs7I%Ay-a zp(G2p7>a%R18TOCt+o|6Y+!!&@}1pQ79~x&bE%*|oGY0tohzFwpQEk7C8gky;L(|d zqNxH?@%uogrpOfffsz*eDPkg3Q(R;F#J6&%asP?b@|--*2#9|$>xo*V;1lp(Rsxx> znR0^s+nJ$;Zuz4wh3_165^sjcsKy`9nUg^wo1Q1Hit&Rm{Sw?>hVX;)P?X!Kml}}h zSUFJLuSw9OBi#*ur}lnAHu*P3CL1$(v3szSydA1=C=*EUhCTUPt}WeG^aEZK{FG1G z$>-n>ltf5+P_wcZFoJey@ftG#`8ke0;0;#Q5#ZUka$A6}-yr^?rccn6Ny@Cz{E=0? zIGv`ejjm}Iy~ZpZH*oSSCh2s`57lo#) z$R5V~+?Y+hy)k3YB+pOa!9@rvwaNihO=0C=sMGHa%s0R(N^RwiVA{pBX9^qsf~i2w^@bW7o2eo!#=u?x;vfj8(KC%3S^U#bg}A{32pW7R7iVe& z%vPIT^j#F0$9e^GZlsCQ1s3QL#|WpOqk>TDi-BX6a^ehmjO6bCu~JXD(G7aTY*r!B z=K4du>=iutgL8G3 zbFV>m{(~%DosbIzYj^x-($`Z2I*O#$@?3-0+6=akZI$y=X1hOp{Cf=y(5@$Y`yr z5^h%o8C`yTiYu+luTur~kzgRt+pi0siF*9J^VbE7#QFV#!V>b_lv(A|rJ$vd!qCi)MZMd~i-; zx(JDJ+!8Y%4pO1xo@La^avj;+cKbZvb$ax3Kij;^iXfn64wOz8_*r$ZS+Nt``>a6>3=wB`%wfVtzMZLWrHhoNSat?9 z?-mRHDsmiCwx(_GlvxZxA?|-oRwtPAE&hUwVZr-bbijC}d|O%G|5OI8qJUswJ}*5# zeCLWv$Fb_ZdFI1l$=f68fbaW%pgM`M3@a^U5R>ill@@r5l;uiN?+CRl{fvdKlCqN$ zlH~23B}n_M5?E|_TbE&}mbKFaownr7;jmCgU;_$hp45#PgQm{*a0Apo3qZ>?cAjO1{bi?Fgn{<%4 zEkH=h47F+gQQ(^36!bi~)-||(SlMFA)f8v6y}!z`9f$*6BWrLy`i(Y@cJBIiPZ?!Z zZ8?bkI@u{C|B4)GVE$P3u<}!?Zx5g?M5d72TG5&>_zr>43y2-bdw)j0w=8c*UyNVY zW3BC-qSsH$yW&qIMFM4d=RRoNiC}KTGwr{QA5ta2fx1-7=9bn+!@E6TZzNvG$TY^= zS)kOYEi1L}=`7J`A!ka*bU6l@{M?Dmm!Z1E*nE&uz5IPd2-ndL1MR(L1P@wG@@O@` zt&W%xZX7qb0)9Wo%z6pH%yM_trG4__V$}BHjdd<4G~UHP2p&)@jeCyVVD*9Kb3nmq z`-#sQd=EKG9E-D8l#Ej2O>oq{usv6Mv&W~^U}8`5=*5}TMpf_p=GQjKtHF(1{4X@w z0@PO1Yq?Zo*5F_8L?O&^y%(koxE3pw=z}Fx^TO0d<|*S0LW&nHbBqD4y5@|d#x)xe z#=`;iU0xm#&B3{`^%nco?&4nob9Ui-#rsJD&?Q4WAaus*kaUEZN9 z;s2%s1y?$6wr}g(uH3wY{2}R{?S|(HYEJOUOyY4Bh(t@^NVtQdI<{o6U9_3=Srj_F z1cD^a3!~yJtMMc}5sJ2%Y~!;CSl$myHOiG5Al9NxF`>KQ-|IYz%@3*WybT-fLmt|V zAIeUWlS44~AY?=;6ls!dv8nApO`$j#Z`y#nKUPyavjIV9?sk!3>BceE!6RKyE{wvK zI3BgY&n872V$WXk(+`%CfQ}^ zyoa?Pik?n!K}uoaJ$yic;F0jdHv7skG~Yqx`?5`;XdK`v!Sw< z`nLu6UyQo5X=hT8Pe9Ajbeqt$tE^hnz!igzloe*C-O%%|j-v1_Igo$a}IH5d36H88SQSDM<$1t#`I2+lSdq8HD z_!lT?yfAM+&5Xai$n>R<^d!A+rc%eBMJdr+9(L61PoGsCbBpMJ7WO*kH9~!|?A+4M zcNbw-^yj5hdF&Q1_pu+xW5~SYxfutB)Yg#eAqGOT5&F=gYcON{92d`YV;4Pke%hF! zcF5;y-=Fw%CqcUt`0+AA*lUuL+;c>IQ4@MRq&INy8G7T1Hd64rvDaHpKd6ne@o=vZbRx z;!rh+44!hRo%D@|9^?~4o&j+aS2B6wJa%#bFGu``m`(s$4^+U4 zNw|xZwb#uM#Kj4E1;1Em6oT!RWTE_xL%q#u+*(-6gBm72G+uv zxEr?ehK*;}b$N9U0dYD{wXi>T{7~Ac)SPSZqp@C|$u*OA3xYScSKHl=pKGy;m;3ka5JT+iXv>66Ee9Y&$bPd)L>7B8drpkUjg;) zt>1t!z-obmDa2b0C+pAR|NfhRq0^hxal`FjETimFjVDkR^q~ZM%Lpbe63%&cuCW&y z#IpK)o|;ChWH!&t-hz*x91r`p0dmB0dkt)vIh+w5CQi5S)G9Ok)me$ZCnT>$TQXIh06aX6I3s)b#`Oiz|K&JWSSjKV>)CRs9S83 z-GFmB)O3Ppfp|(GjOJSf7Yt{aOFEo;uqyI}sUDeCx2Ch@fM0IvFTOFW`R-jxm zz$55dAkvTx=n`X&9HdUec6l{J#XRw53>EL$DpxwsmI}PmxEC9p+H*r!#j`dO(jG`)aS*k;c41}hV$p!>Upvn~obud;}bRfgQoe|u(jB2rVnPu^a^ zj^nCC+%s$Yt5Rk4V3MzyZF@tsIs+570|Z>2m#c;$8iCz44W5N-PkRcbL|cV@1ND`q zP--8Pr;w}5{!-{P>SDly2CCYj{;s974*T$b6fo}3#L}{vUF{rKARcOFp2zXb%jO%& ztR4{b!qC^i&|h!lkI4?iCk}R*VGXp04AXmZ3bzYRDmZ;svoiYFtbd6LIti6M5a(jb zd)&7lwR@Fzu3_Q*7(kxzBb6vr^&CI>+R;)M!iEmDlq}dUFlTPU?T-4o&ngpkIK$Y{ zwiNQZ0NJ4x(1U__WJ0H7> zQtw^cDNl)*zuGv3=V*N{Cn{K8P-~(BO;8dhY4*Urw}bOr+{V!Yb+bNlN_I9uLf!ws z$Adk$D5;NsS0$)l(4?+gj>w{wlf?M1zo^(->PJ?2@3Ym-^|e$Vp9)c#D{kmei^e54 zNh6lSnqwhz7eW6{R9DH=2~+48h}LxgXVDF`0Zl-IBU+e)-to+VxQP$1Z#1Ndg5Gm+ zYAC=Pjo?+RffOV_cLM0^v`?+=CxC!24LX7zXtebSm+zMVytAG!%l$YLlOK>XKPCADu5xq3l0m8g4`PwnJ$>dqD;lH zBM};C_VP|7eD8oDuGb%t3f&xKaPxgYVT^?;(D?ECJcfh1kM#u*Lk5T^HVa0`8V?Ps z4Uo4vvf{sf%>akwR%9-RLxY+R7Y6opcb`ottG3-{tAu(jl*AUGK5`;#%BckYK5oeKgJ-DYv&oy^1$0#l64mkuP!EHlOo+JZ8esNn8(>a$Lg1z6zxl8- zL$|(#5(xV8*X2!qiX}L|x$zv0(0%hPgH~oAJ@}?YV=m~d4jt%tAh-y`3z4m5fxM|B zF2>ZpK%*<6C2#%+kZ~mM1Oxxk>vEw;^}txsUfCz$_-3SMPnWT{yVdGE*1}J!YBkPL zQ+ovt#2?b&K)gH~t^H>bCM=zIFW(e02Q=X+B}d(Ka(krQg&b~2+b$W_)#@=~s^x_k z=`=@RlqHxY%|7LB9hlQw=bcBjP8Hmc_G0IwwBmY+_FA(+h`_(& zK(&A?feu+;z;jE99{?2gfB)gwf9ZzaOvH(AeTxo-&;H1~?j6M_q diff --git a/src/background.js b/src/background.js index 4ea6e34..f8c4da1 100644 --- a/src/background.js +++ b/src/background.js @@ -1,12 +1,21 @@ "use strict"; -const { exec } = require("child_process"); -// const fs = require('fs') -import { app, protocol, BrowserWindow } from "electron"; + +import path from 'path' +// import { autoUpdater } from "electron-updater" +import { + app, + protocol, + BrowserWindow, + ipcMain, + dialog, + globalShortcut, +} from "electron"; import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; import installExtension, { VUEJS_DEVTOOLS } from "electron-devtools-installer"; -const isDevelopment = process.env.NODE_ENV !== "production"; + // maybe use for modify app menu -// const contextMenu = require('electron-context-menu'); +// import contextMenu from 'electron-context-menu' +const isDevelopment = process.env.NODE_ENV !== "production"; // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -18,36 +27,19 @@ protocol.registerSchemesAsPrivileged([ ]); function createWindow() { - console.log("Node Version: ", process.version); - const napi = exec("npm run napi:run"); - let scriptOutput = ""; - napi.stdout.setEncoding('utf8'); - napi.stdout.on('data', (data) => { - console.log('napi: ' + data); - data = data.toString(); - scriptOutput += data + '\n'; - // TODO write file with stream - // const log = fs.createWriteStream(__dirname, '/tmp/' + +new Date + '.log') - // log.write(scriptOutput) - }); - // napi.stdout.on('error', (err) => { - // console.log('napi error: ' + err); - // data = err.toString(); - // scriptOutput += data + '\n'; - // const log = fs.createWriteStream(__dirname, '/tmp/' + +new Date + 'error.log') - // log.write(scriptOutput) - // }); - - // Create the browser window. + require('./electron/services') + +// Create the browser window. win = new BrowserWindow({ - width: 1920, + width: 1153, height: 768, webPreferences: { webSecurity: false, - // Use pluginOptions.nodeIntegration, leave this alone // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info nodeIntegration: true, }, + icon: path.join(__static, "./img/icons/android-chrome-512x512.png"), + preload: path.join(__dirname, "./electron/preload.js"), }); if (process.env.WEBPACK_DEV_SERVER_URL) { @@ -58,7 +50,7 @@ function createWindow() { createProtocol("app"); // Load the index.html when not in development win.loadURL("app://./index.html"); - win.webContents.openDevTools(); + // autoUpdater.checkForUpdatesAndNotify() } win.on("closed", () => { @@ -95,9 +87,38 @@ app.on("ready", async () => { console.error("Vue Devtools failed to install:", e.toString()); } } + // Register shortcut for debug + globalShortcut.register("CommandOrControl+K", function () { + win.webContents.openDevTools(); + }); createWindow(); }); +ipcMain.on("close", () => { + win.close(); + app.quit(); +}); +ipcMain.on("minimize", () => { + win.minimize(); +}); + +// autoUpdater.on("checking-for-update", () => {}); +// autoUpdater.on("update-available", info => { +// console.log(info); +// dialog.showMessageBox({ +// title: "新版本发布", +// message: "有新内容更新,稍后将重新为您安装", +// buttons: ["确定"], +// type: "info", +// noLink: true +// }); +// }); + +// autoUpdater.on("update-downloaded", info => { +// console.log(info); +// autoUpdater.quitAndInstall(); +// }); + // Exit cleanly on request from parent process in development mode. if (isDevelopment) { if (process.platform === "win32") { @@ -112,3 +133,19 @@ if (isDevelopment) { }); } } + +// Make sure the app is singleton. +function initialize() { + const shouldQuit = !app.requestSingleInstanceLock(); + if (shouldQuit) return app.quit(); + // loadComponent() +} + +/** + * 注册主线程文件里的所有js + */ +// function loadComponent () { +// require('./electron/menu.js') +// } + +initialize(); diff --git a/src/electron/command.js b/src/electron/command.js new file mode 100644 index 0000000..c71471c --- /dev/null +++ b/src/electron/command.js @@ -0,0 +1,116 @@ +"use strict"; + +import { app, ipcMain, Menu, MenuItem, BrowserWindow, globalShortcut } from 'electron' + +let loginWindow, senders; + +function openWindow(url) { + const win = new BrowserWindow({ + height: 500, + width: 350, + useContentSize: true, + transparent: false, + frame: false, + darkTheme: true, + backgroundColor: "#FFF", + }); + + win.loadURL(url); + + win.on("closed", () => { + loginWindow = null; + }); + + return win; +} + +const menu = new Menu(); + +const settingsMenu = { + playMenu: function () { + const settings = { + paly: { + label: "播放", + click: function () { + senders.send("play-start"); + }, + }, + addPlayList: { + label: "添加到播放列表", + click: function () { + senders.send("add-play-list"); + }, + }, + collect: { + label: "收藏", + submenu: [ + { + label: "创建新歌单", + click: function () { + senders.send("i-like-star"); + }, + }, + ], + }, + share: { + label: "分享", + }, + copyLink: { + label: "复制链接", + }, + }; + menu.append(new MenuItem(settings.paly)); + menu.append(new MenuItem(settings.addPlayList)); + menu.append(new MenuItem({ type: "separator" })); + menu.append(new MenuItem(settings.collect)); + menu.append(new MenuItem(settings.share)); + menu.append(new MenuItem(settings.copyLink)); + }, +}; + +export function command(mainWindow, winURL) { + // 显示播放菜单 + settingsMenu.playMenu(); + // 接收显示菜单指令 + ipcMain.on("show-content-menu", (event) => { + senders = event.sender; + const win = BrowserWindow.fromWebContents(senders); + menu.popup(win); + }); + // 设置app名称 + app.setName("网易云音乐App"); + // 关闭window窗口 + ipcMain.on("window-close", (event) => { + app.quit(); + }); + // 最大化window窗口 + ipcMain.on("window-max", (event) => { + if (mainWindow.isMaximized()) { + mainWindow.unmaximize(); + } else { + mainWindow.maximize(); + } + }); + // 最小化window窗口 + ipcMain.on("window-min", (event) => { + if (!mainWindow.isMinimized()) { + mainWindow.minimize(); + } + }); + // 新建登录窗口 + ipcMain.on("open-login-window", (event, url) => { + if (loginWindow) { + loginWindow.focus(); + } else { + loginWindow = openWindow(url); + } + }); + // 关闭登录窗口 + ipcMain.on("close-login-window", (event) => { + loginWindow.close(); + }); + // 触发调试 Shift+i + globalShortcut.register("Shift+i", () => { + require("electron-debug")({ showDevTools: true }); + }); +} diff --git a/src/electron/menu.js b/src/electron/menu.js new file mode 100644 index 0000000..7e2713f --- /dev/null +++ b/src/electron/menu.js @@ -0,0 +1,161 @@ +const { Menu, app } = require("electron"); + +const version = app.getVersion(); + +let win; +let updateSource = "menu"; // 更新事件触发来源 menu:通过菜单触发 vue:通过vue页面触发 +let template = [ + { + label: "编辑", + submenu: [ + { + label: "剪切", + accelerator: (() => { + if (process.platform === "darwin") { + return "CmdOrCtrl+X"; + } else { + return "Ctrl+X"; + } + })(), + role: "cut", + }, + { + label: "复制", + accelerator: (() => { + if (process.platform === "darwin") { + return "CmdOrCtrl+C"; + } else { + return "Ctrl+C"; + } + })(), + role: "copy", + }, + { + label: "粘贴", + accelerator: (() => { + if (process.platform === "darwin") { + return "CmdOrCtrl+V"; + } else { + return "Ctrl+V"; + } + })(), + role: "paste", + }, + ], + }, + { + label: "工具", + submenu: [ + { + label: "刷新", + accelerator: (() => { + if (process.platform === "darwin") { + return "CmdOrCtrl+R"; + } else { + return "F5"; + } + })(), + click: (item, focusedWindow) => { + if (focusedWindow) { + focusedWindow.reload(); + } + }, + }, + { + label: "全屏", + accelerator: (() => { + if (process.platform === "darwin") { + return "Ctrl+Command+F"; + } else { + return "F11"; + } + })(), + click: (item, focusedWindow) => { + if (focusedWindow) { + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); + } + }, + }, + { + label: "检查", + accelerator: "F12", + click: (item, focusedWindow) => { + if (focusedWindow) { + focusedWindow.toggleDevTools(); + } + }, + }, + ], + }, +]; + +function findReopenMenuItem() { + const menu = Menu.getApplicationMenu(); + if (!menu) return; + + let reopenMenuItem; + menu.items.forEach((item) => { + if (item.submenu) { + item.submenu.items.forEach((item) => { + if (item.key === "reopenMenuItem") { + reopenMenuItem = item; + } + }); + } + }); + return reopenMenuItem; +} + +// mac 添加退出 +if (process.platform === "darwin") { + const name = app.getName(); + template.unshift({ + label: name + " v" + version, + submenu: [ + { + label: "退出", + accelerator: "Command+Q", + click: () => { + app.quit(); + }, + }, + ], + }); +} +// win 添加更新菜单 +if (process.platform === "win32") { + template.push({ + label: "帮助", + submenu: [ + { + label: `当前版本 v${version}`, + enabled: false, + }, + { + label: "检查更新", + accelerator: "Ctrl+U", + click: (item, focusedWindow) => { + // 执行自动更新检查 + win = focusedWindow; + updateSource = "menu"; + autoUpdater.checkForUpdates(); + }, + }, + ], + }); +} + +app.on('ready', () => { + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) +}) + +app.on('browser-window-created', () => { + let reopenMenuItem = findReopenMenuItem() + if (reopenMenuItem) reopenMenuItem.enabled = false +}) + +app.on('window-all-closed', () => { + let reopenMenuItem = findReopenMenuItem() + if (reopenMenuItem) reopenMenuItem.enabled = true +}) diff --git a/src/electron/preload.js b/src/electron/preload.js new file mode 100644 index 0000000..e69de29 diff --git a/src/electron/services.js b/src/electron/services.js new file mode 100644 index 0000000..9f2d783 --- /dev/null +++ b/src/electron/services.js @@ -0,0 +1,61 @@ +const express = require("express"); +const path = require("path"); +const bodyParser = require('body-parser') +const cache = require('../../napi/util/apicache').middleware +const fileUpload = require('express-fileupload') + +import routes from "../../napi/routes"; + +// Integrate API +const app = express() + +// CORS & Preflight request +app.use((req, res, next) => { + if (req.path !== '/' && !req.path.includes('.')) { + res.set({ + 'Access-Control-Allow-Credentials': true, + 'Access-Control-Allow-Origin': req.headers.origin || '*', + 'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type', + 'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS', + 'Content-Type': 'application/json; charset=utf-8', + }) + } + req.method === 'OPTIONS' ? res.status(204).end() : next() +}) + +// cookie parser +app.use((req, res, next) => { + req.cookies = {} + ;(req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => { + let crack = pair.indexOf('=') + if (crack < 1 || crack == pair.length - 1) return + req.cookies[ + decodeURIComponent(pair.slice(0, crack)).trim() + ] = decodeURIComponent(pair.slice(crack + 1)).trim() + }) + next() +}) + +// body parser +app.use(bodyParser.json()) +app.use(bodyParser.urlencoded({ extended: false })) + +app.use(fileUpload()) + +// static +// app.use(express.static(path.join(__dirname, 'public'))) + +// cache +app.use(cache('2 minutes', (req, res) => res.statusCode === 200)) +// router + +Object.keys(routes).forEach(route => { + app.use(route, routes[route]) +}) + +const port = process.env.PORT || 3000 +const host = process.env.HOST || '' + +app.server = app.listen(port, host, () => { + console.log(`server running @ http://${host ? host : 'localhost'}:${port}`) +}) \ No newline at end of file diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js index 1473a0a..b8a8c97 100644 --- a/src/registerServiceWorker.js +++ b/src/registerServiceWorker.js @@ -2,7 +2,7 @@ import { register } from "register-service-worker"; -if (process.env.NODE_ENV === "production") { +if (process.env.NODE_ENV === "production" && process.env.IS_ELECTRON === 'undefined') { register(`${process.env.BASE_URL}service-worker.js`, { ready() { console.log( diff --git a/vue.config.js b/vue.config.js index c08614c..0f10e28 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,5 +1,5 @@ const path = require("path"); -const CopywebpackPlugin = require('copy-webpack-plugin') +const CopyPlugin = require('copy-webpack-plugin') function resolve(dir) { return path.join(__dirname, dir); } @@ -50,72 +50,56 @@ module.exports = { pluginOptions: { // electron-builder的配置文件 electronBuilder: { + preload: 'src/electron/preload.js', builderOptions: { - // files: [ - // { - // 'filter': ['**/*'] - // } - // ], - // extraFiles: ['./extensions/'], // 应用名称 productName: 'Yes Play Music', // 版权 copyright: 'Copyright © YesPlayMusic', compression: "maximum", - // 是否打包加密 + publish: ["github"], + // Compress app using 'electron/asar' asar: true, - // // 项目打包生成的文件目录 - // directories: { - // output: 'build' - // }, - // window的icon头标 + + // 项目打包生成的文件目录 + directories: { + output: 'dist_electron' + }, + // window 的 icon 头标 win: { icon: 'public/favicon.ico' }, // 是否静默安装 nsis: { + // 是否一键安装,建议为 false,可以让用户点击下一步、下一步、下一步的形式安装程序,如果为true,当用户双击构建好的程序,自动安装程序并打开,即:一键安装 oneClick: false, + // 允许修改安装目录,建议为 true,是否允许用户改变安装目录,默认是不允许 allowToChangeInstallationDirectory: true }, // 集成 nodejs, https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration // nodeIntegration: true }, + // 主线程的配置文件 chainWebpackMainProcess: config => { - // console.log(config) - let outputDir = 'dist_electron/bundled' - config.plugin('copy').use(CopywebpackPlugin, [ - [ - { - from: path.resolve(__dirname, './NeteaseCloudMusicApi-master'), - to: path.join(__dirname, outputDir, 'NeteaseCloudMusicApi-master') - } - ] - ]) - } + config.plugin('define').tap((args) => { + args[0]['IS_ELECTRON'] = true + return args + }) + }, // 渲染线程的配置文件 - // chainWebpackRendererProcess: config => { - // // 渲染线程的一些其他配置 - // // Chain webpack config for electron renderer process only - // // The following example will set IS_ELECTRON to true in your app - // config.plugin('define').tap((args) => { - // args[0]['IS_ELECTRON'] = true - // return args - // }) - // }, + chainWebpackRendererProcess: config => { + // 渲染线程的一些其他配置 + // Chain webpack config for electron renderer process only + // The following example will set IS_ELECTRON to true in your app + config.plugin('define').tap((args) => { + args[0]['IS_ELECTRON'] = true + return args + }) + }, // 主入口文件 // mainProcessFile: 'src/main.js', - // mainProcessWatch: [], + mainProcessWatch: ['../napi/routes.js'], // mainProcessArgs: [] } - }, - // 打包时不生成.map文件,减少体积,加快速度如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 - productionSourceMap: false, - // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。 - assetsDir: 'src/renderer/static', - // 跨域配置 - devServer: { - disableHostCheck: true - }, - // css 样式 - css: {} + } }; diff --git a/yarn.lock b/yarn.lock index 590482f..f8b5e98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1050,6 +1050,11 @@ dependencies: defer-to-connect "^1.0.1" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.npm.taobao.org/@tootallnate/once/download/@tootallnate/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha1-zLkURTYBeaBOf+av94wA/8Hur4I= + "@types/anymatch@*": version "1.3.1" resolved "https://registry.npm.taobao.org/@types/anymatch/download/@types/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -1732,6 +1737,13 @@ address@^1.1.2: resolved "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY= +agent-base@6: + version "6.0.2" + resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-6.0.2.tgz?cache=0&sync_timestamp=1603480100923&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fagent-base%2Fdownload%2Fagent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c= + dependencies: + debug "4" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.1.0.tgz?cache=0&sync_timestamp=1598049717562&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faggregate-error%2Fdownload%2Faggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1860,6 +1872,11 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +apicache@^1.5.3: + version "1.5.3" + resolved "https://registry.npm.taobao.org/apicache/download/apicache-1.5.3.tgz#8977b358bf7d579d55fe3d183c907ae5dbcfb357" + integrity sha1-iXezWL99V51V/j0YPJB65dvPs1c= + app-builder-bin@3.5.10: version "3.5.10" resolved "https://registry.npm.taobao.org/app-builder-bin/download/app-builder-bin-3.5.10.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fapp-builder-bin%2Fdownload%2Fapp-builder-bin-3.5.10.tgz#4a7f9999fccc0c435b6284ae1366bc76a17c4a7d" @@ -1987,11 +2004,23 @@ assign-symbols@^1.0.0: resolved "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types@^0.13.2: + version "0.13.4" + resolved "https://registry.npm.taobao.org/ast-types/download/ast-types-0.13.4.tgz?cache=0&sync_timestamp=1599935985242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fast-types%2Fdownload%2Fast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" + integrity sha1-7g13s0MmOWXsw/ti2hbnIisrZ4I= + dependencies: + tslib "^2.0.1" + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k= +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/astral-regex/download/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha1-SDFDxWeu7UeFdZwIZXhtx319LjE= + async-each@^1.0.1: version "1.0.3" resolved "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" @@ -2057,10 +2086,10 @@ aws4@^1.8.0: resolved "https://registry.npm.taobao.org/aws4/download/aws4-1.10.1.tgz?cache=0&sync_timestamp=1597236947743&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" integrity sha1-4eguTz6Zniz9YbFhKA0WoRH4ZCg= -axios@^0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd" - integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA== +axios@^0.21.0: + version "0.21.0" + resolved "https://registry.npm.taobao.org/axios/download/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" + integrity sha1-Jt8IiAOiNQ3/LCf5b++Z/klEKso= dependencies: follow-redirects "^1.10.0" @@ -2172,6 +2201,11 @@ bfj@^6.1.1: hoopy "^0.1.4" tryer "^1.0.1" +big-integer@^1.6.48: + version "1.6.48" + resolved "https://registry.npm.taobao.org/big-integer/download/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" + integrity sha1-j9iL0WMsukocjD49cVnwi7lbS54= + big.js@^3.1.3: version "3.2.0" resolved "https://registry.npm.taobao.org/big.js/download/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" @@ -2447,6 +2481,13 @@ builtin-status-codes@^3.0.0: resolved "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +busboy@^0.3.1: + version "0.3.1" + resolved "https://registry.npm.taobao.org/busboy/download/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b" + integrity sha1-FwiZJ0xb84quJ9XGK3EmjNWF/Rs= + dependencies: + dicer "0.3.0" + bytes@3.0.0: version "3.0.0" resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz?cache=0&sync_timestamp=1589682741197&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbytes%2Fdownload%2Fbytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2830,6 +2871,14 @@ cli-spinners@^2.0.0: resolved "https://registry.npm.taobao.org/cli-spinners/download/cli-spinners-2.4.0.tgz#c6256db216b878cfba4720e719cec7cf72685d7f" integrity sha1-xiVtsha4eM+6RyDnGc7Hz3JoXX8= +cli-truncate@^2.0.0: + version "2.1.0" + resolved "https://registry.npm.taobao.org/cli-truncate/download/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha1-w54ovwXtzeW+O5iZKiLe7Vork8c= + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + cli-width@^3.0.0: version "3.0.0" resolved "https://registry.npm.taobao.org/cli-width/download/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -3455,6 +3504,11 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-uri-to-buffer@3: + version "3.0.1" + resolved "https://registry.npm.taobao.org/data-uri-to-buffer/download/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha1-WUuJc5OMW8LDMEZTV4U0GrxPNjY= + dayjs@^1.8.36: version "1.8.36" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.36.tgz#be36e248467afabf8f5a86bae0de0cdceecced50" @@ -3472,6 +3526,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.2.0" + resolved "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" + integrity sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E= + dependencies: + ms "2.1.2" + debug@^3.1.1, debug@^3.2.5: version "3.2.6" resolved "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -3479,13 +3540,6 @@ debug@^3.1.1, debug@^3.2.5: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E= - dependencies: - ms "2.1.2" - debug@^4.3.0: version "4.3.0" resolved "https://registry.npm.taobao.org/debug/download/debug-4.3.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.3.0.tgz#efa41cbf14fc9448075367fdaaddf82376da211e" @@ -3603,6 +3657,15 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +degenerator@^2.2.0: + version "2.2.0" + resolved "https://registry.npm.taobao.org/degenerator/download/degenerator-2.2.0.tgz#49e98c11fa0293c5b26edfbb52f15729afcdb254" + integrity sha1-SemMEfoCk8Wybt+7UvFXKa/NslQ= + dependencies: + ast-types "^0.13.2" + escodegen "^1.8.1" + esprima "^4.0.0" + del@^4.1.1: version "4.1.1" resolved "https://registry.npm.taobao.org/del/download/del-4.1.1.tgz?cache=0&sync_timestamp=1589682730753&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdel%2Fdownload%2Fdel-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" @@ -3644,6 +3707,13 @@ detect-node@^2.0.4: resolved "https://registry.npm.taobao.org/detect-node/download/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" integrity sha1-AU7o+PZpxcWAI9pkuBecCDooxGw= +dicer@0.3.0: + version "0.3.0" + resolved "https://registry.npm.taobao.org/dicer/download/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872" + integrity sha1-6s2Ys7+/kuirXC/bcaqsRLsGuHI= + dependencies: + streamsearch "0.1.2" + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.npm.taobao.org/diffie-hellman/download/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -3861,6 +3931,15 @@ electron-builder@^22.2.0: update-notifier "^4.1.1" yargs "^16.0.3" +electron-context-menu@^2.3.0: + version "2.3.0" + resolved "https://registry.npm.taobao.org/electron-context-menu/download/electron-context-menu-2.3.0.tgz#d9af9733b19a76c78c413d8eb7b00b1ae1ead356" + integrity sha1-2a+XM7GadseMQT2Ot7ALGuHq01Y= + dependencies: + cli-truncate "^2.0.0" + electron-dl "^3.0.0" + electron-is-dev "^1.0.1" + electron-debug@^3.1.0: version "3.1.0" resolved "https://registry.npm.taobao.org/electron-debug/download/electron-debug-3.1.0.tgz#0df17297487fa3c82344d810812853bf67f0bd69" @@ -3878,12 +3957,21 @@ electron-devtools-installer@^3.1.1: semver "^7.2.1" unzip-crx-3 "^0.2.0" +electron-dl@^3.0.0: + version "3.0.2" + resolved "https://registry.npm.taobao.org/electron-dl/download/electron-dl-3.0.2.tgz#302a46f9a449ddce720cb8e7f2a24c386e19a26c" + integrity sha1-MCpG+aRJ3c5yDLjn8qJMOG4Zomw= + dependencies: + ext-name "^5.0.0" + pupa "^2.0.1" + unused-filename "^2.1.0" + electron-is-accelerator@^0.1.0: version "0.1.2" resolved "https://registry.npm.taobao.org/electron-is-accelerator/download/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b" integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns= -electron-is-dev@^1.1.0, electron-is-dev@^1.2.0: +electron-is-dev@^1.0.1, electron-is-dev@^1.1.0, electron-is-dev@^1.2.0: version "1.2.0" resolved "https://registry.npm.taobao.org/electron-is-dev/download/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e" integrity sha1-LlzqChs8zxyG9XfO53Nj71XesF4= @@ -4125,6 +4213,18 @@ escape-string-regexp@^4.0.0: resolved "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ= +escodegen@^1.8.1: + version "1.14.3" + resolved "https://registry.npm.taobao.org/escodegen/download/escodegen-1.14.3.tgz?cache=0&sync_timestamp=1596669832613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescodegen%2Fdownload%2Fescodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM= + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-loader@^2.2.1: version "2.2.1" resolved "https://registry.npm.taobao.org/eslint-loader/download/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337" @@ -4225,7 +4325,7 @@ espree@^6.1.2, espree@^6.2.1: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz?cache=0&sync_timestamp=1589682833047&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fesprima%2Fdownload%2Fesprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha1-E7BM2z5sXRnfkatph6hpVhmwqnE= @@ -4244,7 +4344,7 @@ esrecurse@^4.1.0, esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0= @@ -4364,6 +4464,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +express-fileupload@^1.2.0: + version "1.2.0" + resolved "https://registry.npm.taobao.org/express-fileupload/download/express-fileupload-1.2.0.tgz#356c4dfd645be71ab9fb2f4e6d84eeb00d247979" + integrity sha1-NWxN/WRb5xq5+y9ObYTusA0keXk= + dependencies: + busboy "^0.3.1" + express@^4.16.3, express@^4.17.1: version "4.17.1" resolved "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz?cache=0&sync_timestamp=1589682766604&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexpress%2Fdownload%2Fexpress-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -4400,6 +4507,21 @@ express@^4.16.3, express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.npm.taobao.org/ext-list/download/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha1-C5jmTtgvWs8PKTG6v2khLvUt3Tc= + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.npm.taobao.org/ext-name/download/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha1-cHgZgdGD7hXROZPIgiBFxQbI8KY= + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -4554,6 +4676,11 @@ file-uri-to-path@1.0.0: resolved "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90= +file-uri-to-path@2: + version "2.0.0" + resolved "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba" + integrity sha1-e0Fa66In1XWFHgpbDGQNdlZAP7o= + filelist@^1.0.1: version "1.0.1" resolved "https://registry.npm.taobao.org/filelist/download/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb" @@ -4812,6 +4939,14 @@ fsevents@~2.1.2: resolved "https://registry.npm.taobao.org/fsevents/download/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha1-+3OHA66NL5/pAMM4Nt3r7ouX8j4= +ftp@^0.3.10: + version "0.3.10" + resolved "https://registry.npm.taobao.org/ftp/download/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -4856,6 +4991,18 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-uri@3: + version "3.0.2" + resolved "https://registry.npm.taobao.org/get-uri/download/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c" + integrity sha1-8O8TVvqrxw4flAT6O2ayupv8clw= + dependencies: + "@tootallnate/once" "1" + data-uri-to-buffer "3" + debug "4" + file-uri-to-path "2" + fs-extra "^8.1.0" + ftp "^0.3.10" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -5276,17 +5423,7 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz?cache=0&sync_timestamp=1593407858306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-errors@~1.7.2: +http-errors@1.7.3, http-errors@~1.7.2: version "1.7.3" resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz?cache=0&sync_timestamp=1593407858306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY= @@ -5297,11 +5434,30 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz?cache=0&sync_timestamp=1593407858306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + http-parser-js@>=0.5.1: version "0.5.2" resolved "https://registry.npm.taobao.org/http-parser-js/download/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" integrity sha1-2i4x0jezk6rnKs5DiC3X4nCo/3c= +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.npm.taobao.org/http-proxy-agent/download/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha1-ioyO9/WTLM+VPClsqCkblap0qjo= + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -5335,6 +5491,14 @@ https-browserify@^1.0.0: resolved "https://registry.npm.taobao.org/https-browserify/download/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@5: + version "5.0.0" + resolved "https://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha1-4qkFQqu2inYuCghQ9sntrf2FBrI= + dependencies: + agent-base "6" + debug "4" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -5868,6 +6032,11 @@ is-yarn-global@^0.3.0: resolved "https://registry.npm.taobao.org/is-yarn-global/download/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" integrity sha1-1QLTOCWQ6jAEiTdGdUyJE5lz4jI= +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -6569,6 +6738,11 @@ mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I= +mime-db@^1.28.0: + version "1.45.0" + resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.45.0.tgz?cache=0&sync_timestamp=1600831210195&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" + integrity sha1-zO7aIczXw6dF66LezVXUtz54eeo= + mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.27.tgz?cache=0&sync_timestamp=1589682770020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" @@ -6710,6 +6884,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.npm.taobao.org/mkdirp/download/mkdirp-1.0.4.tgz?cache=0&sync_timestamp=1589682820707&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha1-PrXtYmInVteaXw4qIh3+utdcL34= +modify-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.npm.taobao.org/modify-filename/download/modify-filename-1.1.0.tgz#9a2dec83806fbb2d975f22beec859ca26b393aa1" + integrity sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE= + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -6801,6 +6980,11 @@ neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: resolved "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha1-tKr7k+OustgXTKU88WOrfXMIMF8= +netmask@^1.0.6: + version "1.0.6" + resolved "https://registry.npm.taobao.org/netmask/download/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" + integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.npm.taobao.org/nice-try/download/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -7098,7 +7282,7 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -optionator@^0.8.3: +optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU= @@ -7232,6 +7416,30 @@ p-try@^2.0.0: resolved "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha1-yyhoVA4xPWHeWPr741zpAE1VQOY= +pac-proxy-agent@^4.1.0: + version "4.1.0" + resolved "https://registry.npm.taobao.org/pac-proxy-agent/download/pac-proxy-agent-4.1.0.tgz#66883eeabadc915fc5e95457324cb0f0ac78defb" + integrity sha1-Zog+6rrckV/F6VRXMkyw8Kx43vs= + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + get-uri "3" + http-proxy-agent "^4.0.1" + https-proxy-agent "5" + pac-resolver "^4.1.0" + raw-body "^2.2.0" + socks-proxy-agent "5" + +pac-resolver@^4.1.0: + version "4.1.0" + resolved "https://registry.npm.taobao.org/pac-resolver/download/pac-resolver-4.1.0.tgz#4b12e7d096b255a3b84e53f6831f32e9c7e5fe95" + integrity sha1-SxLn0JayVaO4TlP2gx8y6cfl/pU= + dependencies: + degenerator "^2.2.0" + ip "^1.1.5" + netmask "^1.0.6" + package-json@^6.3.0: version "6.5.0" resolved "https://registry.npm.taobao.org/package-json/download/package-json-6.5.0.tgz?cache=0&sync_timestamp=1589683698535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpackage-json%2Fdownload%2Fpackage-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" @@ -8128,6 +8336,16 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^2.2.0: + version "2.4.1" + resolved "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha1-MKyC+Yu1rowVLmcUnayNVRU7Fow= + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + rc@^1.2.8: version "1.2.8" resolved "https://registry.npm.taobao.org/rc/download/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -8172,6 +8390,16 @@ read-pkg@^5.1.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-1.1.14.tgz?cache=0&sync_timestamp=1589682741447&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz?cache=0&sync_timestamp=1589682741447&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" @@ -8789,6 +9017,20 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha1-Md3BCTCht+C2ewjJbC9Jt3p4l4c= + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.npm.taobao.org/smart-buffer/download/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha1-kWBcJdkWUvRmHqacz0XxszHKIbo= + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.npm.taobao.org/snapdragon-node/download/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -8840,6 +9082,30 @@ sockjs@0.3.20: uuid "^3.4.0" websocket-driver "0.6.5" +socks-proxy-agent@5: + version "5.0.0" + resolved "https://registry.npm.taobao.org/socks-proxy-agent/download/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" + integrity sha1-fA82Tnsc9KekN+cSU77XLpAEvmA= + dependencies: + agent-base "6" + debug "4" + socks "^2.3.3" + +socks@^2.3.3: + version "2.5.0" + resolved "https://registry.npm.taobao.org/socks/download/socks-2.5.0.tgz?cache=0&sync_timestamp=1603686517008&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocks%2Fdownload%2Fsocks-2.5.0.tgz#3a7c286db114f67864a4bd8b4207a91d1db3d6db" + integrity sha1-OnwobbEU9nhkpL2LQgepHR2z1ts= + dependencies: + ip "^1.1.5" + smart-buffer "^4.1.0" + +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.npm.taobao.org/sort-keys-length/download/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= + dependencies: + sort-keys "^1.0.0" + sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.npm.taobao.org/sort-keys/download/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" @@ -9061,6 +9327,11 @@ stream-shift@^1.0.0: resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0= +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.npm.taobao.org/streamsearch/download/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -9115,6 +9386,11 @@ string_decoder@^1.0.0, string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -9580,6 +9856,11 @@ tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.1: + version "2.0.3" + resolved "https://registry.npm.taobao.org/tslib/download/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" + integrity sha1-jgdBrEX8DCJuWKF7/D5kubxsphw= + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.npm.taobao.org/tty-browserify/download/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -9754,6 +10035,14 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unused-filename@^2.1.0: + version "2.1.0" + resolved "https://registry.npm.taobao.org/unused-filename/download/unused-filename-2.1.0.tgz#33719c4e8d9644f32d2dec1bc8525c6aaeb4ba51" + integrity sha1-M3GcTo2WRPMtLewbyFJcaq60ulE= + dependencies: + modify-filename "^1.1.0" + path-exists "^4.0.0" + unzip-crx-3@^0.2.0: version "0.2.0" resolved "https://registry.npm.taobao.org/unzip-crx-3/download/unzip-crx-3-0.2.0.tgz#d5324147b104a8aed9ae8639c95521f6f7cda292" @@ -10535,6 +10824,11 @@ xdg-basedir@^4.0.0: resolved "https://registry.npm.taobao.org/xdg-basedir/download/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha1-S8jZmEQDaWIl74OhVzy7y0552xM= +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/xregexp/download/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= + xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz?cache=0&sync_timestamp=1589682817913&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxtend%2Fdownload%2Fxtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"