[\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/netease_api/module/resource_like.js b/netease_api/module/resource_like.js
deleted file mode 100644
index de285b6..0000000
--- a/netease_api/module/resource_like.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// 点赞与取消点赞资源
-
-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/netease_api/module/scrobble.js b/netease_api/module/scrobble.js
deleted file mode 100644
index ad542d5..0000000
--- a/netease_api/module/scrobble.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// 听歌打卡
-
-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/netease_api/module/search.js b/netease_api/module/search.js
deleted file mode 100644
index b2e1ff9..0000000
--- a/netease_api/module/search.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 搜索
-
-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/netease_api/module/search_default.js b/netease_api/module/search_default.js
deleted file mode 100644
index b573254..0000000
--- a/netease_api/module/search_default.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 默认搜索关键词
-
-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/netease_api/module/search_hot.js b/netease_api/module/search_hot.js
deleted file mode 100644
index 75c95a6..0000000
--- a/netease_api/module/search_hot.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 热门搜索
-
-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/netease_api/module/search_hot_detail.js b/netease_api/module/search_hot_detail.js
deleted file mode 100644
index aae7c7e..0000000
--- a/netease_api/module/search_hot_detail.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 热搜列表
-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/netease_api/module/search_multimatch.js b/netease_api/module/search_multimatch.js
deleted file mode 100644
index 6e4c0e8..0000000
--- a/netease_api/module/search_multimatch.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 多类型搜索
-
-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/netease_api/module/search_suggest.js b/netease_api/module/search_suggest.js
deleted file mode 100644
index e78b255..0000000
--- a/netease_api/module/search_suggest.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 搜索建议
-
-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/netease_api/module/send_album.js b/netease_api/module/send_album.js
deleted file mode 100644
index 8af5673..0000000
--- a/netease_api/module/send_album.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 私信专辑
-
-module.exports = (query, request) => {
- query.cookie.os = 'ios'
- query.cookie.appver = '8.1.20'
- const data = {
- id: query.id,
- msg: query.msg || '',
- type: 'album',
- userIds: '[' + query.user_ids + ']',
- }
- return request('POST', `https://music.163.com/api/msg/private/send`, data, {
- crypto: 'api',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/send_playlist.js b/netease_api/module/send_playlist.js
deleted file mode 100644
index a1d9bd4..0000000
--- a/netease_api/module/send_playlist.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// 私信歌单
-
-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/netease_api/module/send_song.js b/netease_api/module/send_song.js
deleted file mode 100644
index 932cde1..0000000
--- a/netease_api/module/send_song.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 私信歌曲
-
-module.exports = (query, request) => {
- query.cookie.os = 'ios'
- query.cookie.appver = '8.1.20'
- const data = {
- id: query.id,
- msg: query.msg || '',
- type: 'song',
- userIds: '[' + query.user_ids + ']',
- }
- return request('POST', `https://music.163.com/api/msg/private/send`, data, {
- crypto: 'api',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/send_text.js b/netease_api/module/send_text.js
deleted file mode 100644
index a13ad35..0000000
--- a/netease_api/module/send_text.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 私信
-
-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/netease_api/module/setting.js b/netease_api/module/setting.js
deleted file mode 100644
index 7dd8279..0000000
--- a/netease_api/module/setting.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 设置
-
-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/netease_api/module/share_resource.js b/netease_api/module/share_resource.js
deleted file mode 100644
index 64c016a..0000000
--- a/netease_api/module/share_resource.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 分享歌曲到动态
-
-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/netease_api/module/simi_artist.js b/netease_api/module/simi_artist.js
deleted file mode 100644
index 36d2572..0000000
--- a/netease_api/module/simi_artist.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 相似歌手
-const config = require('../util/config.json')
-module.exports = (query, request) => {
- if (!('MUSIC_U' in query.cookie))
- query.cookie.MUSIC_A = config.anonymous_token
- 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/netease_api/module/simi_mv.js b/netease_api/module/simi_mv.js
deleted file mode 100644
index 6dd1c5f..0000000
--- a/netease_api/module/simi_mv.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// 相似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/netease_api/module/simi_playlist.js b/netease_api/module/simi_playlist.js
deleted file mode 100644
index 11052df..0000000
--- a/netease_api/module/simi_playlist.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 相似歌单
-
-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/netease_api/module/simi_song.js b/netease_api/module/simi_song.js
deleted file mode 100644
index 58b3be9..0000000
--- a/netease_api/module/simi_song.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 相似歌曲
-
-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/netease_api/module/simi_user.js b/netease_api/module/simi_user.js
deleted file mode 100644
index 65a96d1..0000000
--- a/netease_api/module/simi_user.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 相似用户
-
-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/netease_api/module/song_detail.js b/netease_api/module/song_detail.js
deleted file mode 100644
index 338fddc..0000000
--- a/netease_api/module/song_detail.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 歌曲详情
-
-module.exports = (query, request) => {
- query.ids = query.ids.split(/\s*,\s*/)
- const data = {
- c: '[' + query.ids.map((id) => '{"id":' + id + '}').join(',') + ']',
- }
- return request('POST', `https://music.163.com/api/v3/song/detail`, data, {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/song_order_update.js b/netease_api/module/song_order_update.js
deleted file mode 100644
index 0dfb416..0000000
--- a/netease_api/module/song_order_update.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// 更新歌曲顺序
-
-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/netease_api/module/song_purchased.js b/netease_api/module/song_purchased.js
deleted file mode 100644
index c86dfa1..0000000
--- a/netease_api/module/song_purchased.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 已购单曲
-
-module.exports = (query, request) => {
- const data = {
- limit: query.limit || 20,
- offset: query.offset || 0,
- }
- return request(
- 'POST',
- `https://music.163.com/weapi/single/mybought/song/list`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/song_url.js b/netease_api/module/song_url.js
deleted file mode 100644
index 46e6bf1..0000000
--- a/netease_api/module/song_url.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 歌曲链接
-
-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/netease_api/module/top_album.js b/netease_api/module/top_album.js
deleted file mode 100644
index d220297..0000000
--- a/netease_api/module/top_album.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// 新碟上架
-
-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/netease_api/module/top_artists.js b/netease_api/module/top_artists.js
deleted file mode 100644
index a1a40b6..0000000
--- a/netease_api/module/top_artists.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 热门歌手
-
-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/netease_api/module/top_list.js b/netease_api/module/top_list.js
deleted file mode 100644
index c33b251..0000000
--- a/netease_api/module/top_list.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 排行榜
-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/netease_api/module/top_mv.js b/netease_api/module/top_mv.js
deleted file mode 100644
index 2dc7c22..0000000
--- a/netease_api/module/top_mv.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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/netease_api/module/top_playlist.js b/netease_api/module/top_playlist.js
deleted file mode 100644
index 4f41edb..0000000
--- a/netease_api/module/top_playlist.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// 分类歌单
-
-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/netease_api/module/top_playlist_highquality.js b/netease_api/module/top_playlist_highquality.js
deleted file mode 100644
index a704652..0000000
--- a/netease_api/module/top_playlist_highquality.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 精品歌单
-
-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/netease_api/module/top_song.js b/netease_api/module/top_song.js
deleted file mode 100644
index 4b37d38..0000000
--- a/netease_api/module/top_song.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 新歌速递
-
-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/netease_api/module/topic_detail.js b/netease_api/module/topic_detail.js
deleted file mode 100644
index e0dd006..0000000
--- a/netease_api/module/topic_detail.js
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = (query, request) => {
- const data = {
- actid: query.actid,
- }
- return request('POST', `https://music.163.com/api/act/detail`, data, {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/topic_detail_event_hot.js b/netease_api/module/topic_detail_event_hot.js
deleted file mode 100644
index a979b6f..0000000
--- a/netease_api/module/topic_detail_event_hot.js
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = (query, request) => {
- const data = {
- actid: query.actid,
- }
- return request('POST', `https://music.163.com/api/act/event/hot`, data, {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/topic_sublist.js b/netease_api/module/topic_sublist.js
deleted file mode 100644
index 153b298..0000000
--- a/netease_api/module/topic_sublist.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 收藏的专栏
-
-module.exports = (query, request) => {
- const data = {
- limit: query.limit || 50,
- offset: query.offset || 0,
- total: true,
- }
- return request('POST', `https://music.163.com/api/topic/sublist`, data, {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/toplist.js b/netease_api/module/toplist.js
deleted file mode 100644
index c690241..0000000
--- a/netease_api/module/toplist.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 所有榜单介绍
-
-module.exports = (query, request) => {
- return request(
- 'POST',
- `https://music.163.com/api/toplist`,
- {},
- {
- crypto: 'api',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/toplist_artist.js b/netease_api/module/toplist_artist.js
deleted file mode 100644
index 825a649..0000000
--- a/netease_api/module/toplist_artist.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 歌手榜
-
-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/netease_api/module/toplist_detail.js b/netease_api/module/toplist_detail.js
deleted file mode 100644
index e194e03..0000000
--- a/netease_api/module/toplist_detail.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 所有榜单内容摘要
-
-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/netease_api/module/user_account.js b/netease_api/module/user_account.js
deleted file mode 100644
index 0eff002..0000000
--- a/netease_api/module/user_account.js
+++ /dev/null
@@ -1,9 +0,0 @@
-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/netease_api/module/user_audio.js b/netease_api/module/user_audio.js
deleted file mode 100644
index b63e700..0000000
--- a/netease_api/module/user_audio.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 用户创建的电台
-
-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/netease_api/module/user_binding.js b/netease_api/module/user_binding.js
deleted file mode 100644
index 559b4b5..0000000
--- a/netease_api/module/user_binding.js
+++ /dev/null
@@ -1,14 +0,0 @@
-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/netease_api/module/user_bindingcellphone.js b/netease_api/module/user_bindingcellphone.js
deleted file mode 100644
index abe1c98..0000000
--- a/netease_api/module/user_bindingcellphone.js
+++ /dev/null
@@ -1,21 +0,0 @@
-module.exports = (query, request) => {
- const data = {
- phone: query.phone,
- countrycode: query.countrycode || '86',
- captcha: query.captcha,
- password: query.password
- ? crypto.createHash('md5').update(query.password).digest('hex')
- : '',
- }
- return request(
- 'POST',
- `https://music.163.com/api/user/bindingCellphone`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/user_cloud.js b/netease_api/module/user_cloud.js
deleted file mode 100644
index 3134960..0000000
--- a/netease_api/module/user_cloud.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 云盘数据
-
-module.exports = (query, request) => {
- const data = {
- limit: query.limit || 30,
- offset: query.offset || 0,
- }
- return request('POST', `https://music.163.com/api/v1/cloud/get`, data, {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- })
-}
diff --git a/netease_api/module/user_cloud_del.js b/netease_api/module/user_cloud_del.js
deleted file mode 100644
index 7a5577b..0000000
--- a/netease_api/module/user_cloud_del.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// 云盘歌曲删除
-
-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/netease_api/module/user_cloud_detail.js b/netease_api/module/user_cloud_detail.js
deleted file mode 100644
index 45f1b5a..0000000
--- a/netease_api/module/user_cloud_detail.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 云盘数据详情
-
-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/netease_api/module/user_comment_history.js b/netease_api/module/user_comment_history.js
deleted file mode 100644
index bb98221..0000000
--- a/netease_api/module/user_comment_history.js
+++ /dev/null
@@ -1,22 +0,0 @@
-module.exports = (query, request) => {
- query.cookie.os = 'ios'
- query.cookie.appver = '8.1.20'
- const data = {
- compose_reminder: 'true',
- compose_hot_comment: 'true',
- limit: query.limit || 10,
- user_id: query.uid,
- time: query.time || 0,
- }
- return request(
- 'POST',
- `https://music.163.com/api/comment/user/comment/history`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/user_detail.js b/netease_api/module/user_detail.js
deleted file mode 100644
index b3da340..0000000
--- a/netease_api/module/user_detail.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 用户详情
-
-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/netease_api/module/user_dj.js b/netease_api/module/user_dj.js
deleted file mode 100644
index 45a6a3a..0000000
--- a/netease_api/module/user_dj.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 用户电台节目
-
-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/netease_api/module/user_event.js b/netease_api/module/user_event.js
deleted file mode 100644
index 0c642ae..0000000
--- a/netease_api/module/user_event.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 用户动态
-
-module.exports = (query, request) => {
- query.cookie.os = 'ios'
- query.cookie.appver = '8.1.20'
- const data = {
- getcounts: true,
- time: query.lasttime || -1,
- limit: query.limit || 30,
- total: false,
- }
- return request(
- 'POST',
- `https://music.163.com/api/event/get/${query.uid}`,
- data,
- {
- crypto: 'api',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/user_followeds.js b/netease_api/module/user_followeds.js
deleted file mode 100644
index 678477a..0000000
--- a/netease_api/module/user_followeds.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 关注TA的人(粉丝)
-
-module.exports = (query, request) => {
- const data = {
- userId: query.uid,
- time: '0',
- limit: query.limit || 30,
- offset: query.offset || 0,
- getcounts: 'true',
- }
- 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/netease_api/module/user_follows.js b/netease_api/module/user_follows.js
deleted file mode 100644
index cff742f..0000000
--- a/netease_api/module/user_follows.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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/netease_api/module/user_level.js b/netease_api/module/user_level.js
deleted file mode 100644
index 107a45f..0000000
--- a/netease_api/module/user_level.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 类别热门电台
-
-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/netease_api/module/user_playlist.js b/netease_api/module/user_playlist.js
deleted file mode 100644
index 51a7c45..0000000
--- a/netease_api/module/user_playlist.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 用户歌单
-
-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/netease_api/module/user_record.js b/netease_api/module/user_record.js
deleted file mode 100644
index 8f5f2cc..0000000
--- a/netease_api/module/user_record.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 听歌排行
-
-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/netease_api/module/user_replacephone.js b/netease_api/module/user_replacephone.js
deleted file mode 100644
index feed2fe..0000000
--- a/netease_api/module/user_replacephone.js
+++ /dev/null
@@ -1,19 +0,0 @@
-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/netease_api/module/user_subcount.js b/netease_api/module/user_subcount.js
deleted file mode 100644
index cfa53ab..0000000
--- a/netease_api/module/user_subcount.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 收藏计数
-
-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/netease_api/module/user_update.js b/netease_api/module/user_update.js
deleted file mode 100644
index 96c7af1..0000000
--- a/netease_api/module/user_update.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 编辑用户信息
-
-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/netease_api/module/video_category_list.js b/netease_api/module/video_category_list.js
deleted file mode 100644
index 88c13c7..0000000
--- a/netease_api/module/video_category_list.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 视频分类列表
-
-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/netease_api/module/video_detail.js b/netease_api/module/video_detail.js
deleted file mode 100644
index 63507ae..0000000
--- a/netease_api/module/video_detail.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 视频详情
-
-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/netease_api/module/video_detail_info.js b/netease_api/module/video_detail_info.js
deleted file mode 100644
index 4a163ae..0000000
--- a/netease_api/module/video_detail_info.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 视频点赞转发评论数数据
-
-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/netease_api/module/video_group.js b/netease_api/module/video_group.js
deleted file mode 100644
index 9c39129..0000000
--- a/netease_api/module/video_group.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 视频标签/分类下的视频
-
-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/netease_api/module/video_group_list.js b/netease_api/module/video_group_list.js
deleted file mode 100644
index 22acdc7..0000000
--- a/netease_api/module/video_group_list.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 视频标签列表
-
-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/netease_api/module/video_sub.js b/netease_api/module/video_sub.js
deleted file mode 100644
index 562a7c2..0000000
--- a/netease_api/module/video_sub.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 收藏与取消收藏视频
-
-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/netease_api/module/video_timeline_all.js b/netease_api/module/video_timeline_all.js
deleted file mode 100644
index b05a46c..0000000
--- a/netease_api/module/video_timeline_all.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// 全部视频列表
-
-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/netease_api/module/video_timeline_recommend.js b/netease_api/module/video_timeline_recommend.js
deleted file mode 100644
index 1ca218a..0000000
--- a/netease_api/module/video_timeline_recommend.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// 推荐视频
-
-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/netease_api/module/video_url.js b/netease_api/module/video_url.js
deleted file mode 100644
index b564f8a..0000000
--- a/netease_api/module/video_url.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 视频链接
-
-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/netease_api/module/vip_growthpoint.js b/netease_api/module/vip_growthpoint.js
deleted file mode 100644
index e035c5a..0000000
--- a/netease_api/module/vip_growthpoint.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 会员成长值
-
-module.exports = (query, request) => {
- const data = {}
- return request(
- 'POST',
- `https://music.163.com/weapi/vipnewcenter/app/level/growhpoint/basic`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/vip_growthpoint_details.js b/netease_api/module/vip_growthpoint_details.js
deleted file mode 100644
index be9c927..0000000
--- a/netease_api/module/vip_growthpoint_details.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 会员成长值领取记录
-
-module.exports = (query, request) => {
- const data = {
- limit: query.limit || 20,
- offset: query.offset || 0,
- }
- return request(
- 'POST',
- `https://music.163.com/weapi/vipnewcenter/app/level/growth/details`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/vip_growthpoint_get.js b/netease_api/module/vip_growthpoint_get.js
deleted file mode 100644
index 69ae94b..0000000
--- a/netease_api/module/vip_growthpoint_get.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 领取会员成长值
-
-module.exports = (query, request) => {
- const data = {
- taskIds: query.ids,
- }
- return request(
- 'POST',
- `https://music.163.com/weapi/vipnewcenter/app/level/task/reward/get`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/vip_info.js b/netease_api/module/vip_info.js
deleted file mode 100644
index 30cba78..0000000
--- a/netease_api/module/vip_info.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 获取 VIP 信息
-
-module.exports = (query, request) => {
- return request(
- 'POST',
- `https://music.163.com/weapi/music-vip-membership/front/vip/info`,
- {},
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/vip_tasks.js b/netease_api/module/vip_tasks.js
deleted file mode 100644
index 256e67a..0000000
--- a/netease_api/module/vip_tasks.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 会员任务
-
-module.exports = (query, request) => {
- const data = {}
- return request(
- 'POST',
- `https://music.163.com/weapi/vipnewcenter/app/level/task/list`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/weblog.js b/netease_api/module/weblog.js
deleted file mode 100644
index 1b593e3..0000000
--- a/netease_api/module/weblog.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 操作记录
-
-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/netease_api/module/yunbei.js b/netease_api/module/yunbei.js
deleted file mode 100644
index b2bee9a..0000000
--- a/netease_api/module/yunbei.js
+++ /dev/null
@@ -1,10 +0,0 @@
-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/netease_api/module/yunbei_expense.js b/netease_api/module/yunbei_expense.js
deleted file mode 100644
index 50b6f95..0000000
--- a/netease_api/module/yunbei_expense.js
+++ /dev/null
@@ -1,17 +0,0 @@
-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/netease_api/module/yunbei_info.js b/netease_api/module/yunbei_info.js
deleted file mode 100644
index 68ea2bf..0000000
--- a/netease_api/module/yunbei_info.js
+++ /dev/null
@@ -1,9 +0,0 @@
-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/netease_api/module/yunbei_rcmd_song.js b/netease_api/module/yunbei_rcmd_song.js
deleted file mode 100644
index 94ddeaa..0000000
--- a/netease_api/module/yunbei_rcmd_song.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 云贝推歌
-
-module.exports = (query, request) => {
- const data = {
- songId: query.id,
- reason: query.reason || '好歌献给你',
- scene: '',
- fromUserId: -1,
- }
- return request(
- 'POST',
- `https://music.163.com/weapi/yunbei/rcmd/song/submit`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/yunbei_rcmd_song_history.js b/netease_api/module/yunbei_rcmd_song_history.js
deleted file mode 100644
index 224a4f8..0000000
--- a/netease_api/module/yunbei_rcmd_song_history.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 云贝推歌历史记录
-
-module.exports = (query, request) => {
- const data = {
- page: JSON.stringify({
- size: query.size || 20,
- cursor: query.cursor || '',
- }),
- }
- return request(
- 'POST',
- `https://music.163.com/weapi/yunbei/rcmd/song/history/list`,
- data,
- {
- crypto: 'weapi',
- cookie: query.cookie,
- proxy: query.proxy,
- realIP: query.realIP,
- },
- )
-}
diff --git a/netease_api/module/yunbei_receipt.js b/netease_api/module/yunbei_receipt.js
deleted file mode 100644
index 5eb04ca..0000000
--- a/netease_api/module/yunbei_receipt.js
+++ /dev/null
@@ -1,17 +0,0 @@
-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/netease_api/module/yunbei_sign.js b/netease_api/module/yunbei_sign.js
deleted file mode 100644
index 9765f6d..0000000
--- a/netease_api/module/yunbei_sign.js
+++ /dev/null
@@ -1,11 +0,0 @@
-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/netease_api/module/yunbei_task_finish.js b/netease_api/module/yunbei_task_finish.js
deleted file mode 100644
index 0988ae9..0000000
--- a/netease_api/module/yunbei_task_finish.js
+++ /dev/null
@@ -1,17 +0,0 @@
-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/netease_api/module/yunbei_tasks.js b/netease_api/module/yunbei_tasks.js
deleted file mode 100644
index fdc2d43..0000000
--- a/netease_api/module/yunbei_tasks.js
+++ /dev/null
@@ -1,14 +0,0 @@
-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/netease_api/module/yunbei_tasks_todo.js b/netease_api/module/yunbei_tasks_todo.js
deleted file mode 100644
index a294484..0000000
--- a/netease_api/module/yunbei_tasks_todo.js
+++ /dev/null
@@ -1,14 +0,0 @@
-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/netease_api/module/yunbei_today.js b/netease_api/module/yunbei_today.js
deleted file mode 100644
index 5b542bf..0000000
--- a/netease_api/module/yunbei_today.js
+++ /dev/null
@@ -1,9 +0,0 @@
-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/netease_api/module_example/avatar_upload.js b/netease_api/module_example/avatar_upload.js
deleted file mode 100644
index 39ea5e5..0000000
--- a/netease_api/module_example/avatar_upload.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const { avatar_upload, login_cellphone } = require('../main')
-const fs = require('fs')
-const path = require('path')
-
-async function main() {
- const result = await login_cellphone({
- phone: '手机号',
- password: '密码',
- })
- const filePath = './test.jpg'
- await avatar_upload({
- imgFile: {
- name: path.basename(filePath),
- data: fs.readFileSync(filePath),
- },
- imgSize: 1012, //图片尺寸,需要正方形图片
- cookie: result.body.cookie,
- })
-}
-main()
diff --git a/netease_api/module_example/song_upload.js b/netease_api/module_example/song_upload.js
deleted file mode 100644
index 6973301..0000000
--- a/netease_api/module_example/song_upload.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const { cloud, login_cellphone } = require('../main')
-const fs = require('fs')
-const path = require('path')
-
-async function main() {
- const result = await login_cellphone({
- phone: '手机号',
- password: '密码',
- })
- const filePath = './test.mp3'
- try {
- await cloud({
- songFile: {
- name: path.basename(filePath),
- data: fs.readFileSync(filePath),
- },
- cookie: result.body.cookie,
- })
- } catch (error) {
- console.log(error, 'error')
- }
-}
-main()
diff --git a/netease_api/module_example/test.jpg b/netease_api/module_example/test.jpg
deleted file mode 100644
index 790c2e7..0000000
Binary files a/netease_api/module_example/test.jpg and /dev/null differ
diff --git a/netease_api/module_example/test.js b/netease_api/module_example/test.js
deleted file mode 100644
index 1a019d7..0000000
--- a/netease_api/module_example/test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const {
- login_cellphone,
- user_cloud,
- album_sublist,
- song_url,
-} = require('../main')
-async function test() {
- try {
- const result = await login_cellphone({
- phone: '手机号',
- password: '密码',
- })
- console.log(result)
- const result2 = await user_cloud({
- cookie: result.body.cookie,
- })
- console.log(result2.body)
- const result3 = await album_sublist({
- cookie: result.body.cookie,
- })
- console.log(result3.body)
- const result4 = await song_url({
- cookie: result.body.cookie,
- id: 33894312,
- })
- console.log(result4.body)
- } catch (error) {
- console.log(error)
- }
-}
-test()
diff --git a/netease_api/module_example/test.mp3 b/netease_api/module_example/test.mp3
deleted file mode 100644
index e85b76e..0000000
Binary files a/netease_api/module_example/test.mp3 and /dev/null differ
diff --git a/netease_api/module_example/test.ts b/netease_api/module_example/test.ts
deleted file mode 100644
index c5c1751..0000000
--- a/netease_api/module_example/test.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { banner, lyric } from 'NeteaseCloudMusicApi'
-banner({ type: 0 }).then((res) => {
- console.log(res)
-})
-lyric({
- id: '33894312',
-}).then((res) => {
- console.log(res)
-})
diff --git a/netease_api/package-lock.json b/netease_api/package-lock.json
deleted file mode 100644
index d9dfd5d..0000000
--- a/netease_api/package-lock.json
+++ /dev/null
@@ -1,4439 +0,0 @@
-{
- "name": "NeteaseCloudMusicApi",
- "version": "4.0.8",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.12.13"
- },
- "dependencies": {
- "@babel/helper-validator-identifier": {
- "version": "7.12.11",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
- "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
- "dev": true
- },
- "@babel/highlight": {
- "version": "7.13.8",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz",
- "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==",
- "dev": true,
- "requires": {
- "@babel/helper-validator-identifier": "^7.12.11",
- "chalk": "^2.0.0",
- "js-tokens": "^4.0.0"
- }
- },
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- }
- }
- },
- "@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.4.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz",
- "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==",
- "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",
- "minimatch": "^3.0.4",
- "strip-json-comments": "^3.1.1"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "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"
- }
- },
- "@tokenizer/token": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.1.1.tgz",
- "integrity": "sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w=="
- },
- "@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/debug": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
- "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ=="
- },
- "@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.14.31",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz",
- "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g=="
- },
- "@types/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
- "dev": true
- },
- "@types/readable-stream": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz",
- "integrity": "sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw==",
- "requires": {
- "@types/node": "*",
- "safe-buffer": "*"
- }
- },
- "@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.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
- "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
- "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.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
- "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
- "dev": true,
- "requires": {
- "clean-stack": "^2.0.0",
- "indent-string": "^4.0.0"
- }
- },
- "ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "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.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
- "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
- "dev": true,
- "requires": {
- "type-fest": "^0.11.0"
- },
- "dependencies": {
- "type-fest": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
- "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
- "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=",
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "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": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "dev": true
- },
- "axios": {
- "version": "0.21.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
- "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
- "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
- },
- "base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
- },
- "binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "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.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
- "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
- "dev": true
- },
- "buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "requires": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
- "buffer-alloc": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
- "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
- "requires": {
- "buffer-alloc-unsafe": "^1.1.0",
- "buffer-fill": "^1.0.0"
- }
- },
- "buffer-alloc-unsafe": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
- "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg=="
- },
- "buffer-fill": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
- "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw="
- },
- "buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
- },
- "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="
- },
- "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"
- }
- }
- }
- },
- "charenc": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
- "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
- },
- "chokidar": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
- "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
- "dev": true,
- "requires": {
- "anymatch": "~3.1.1",
- "braces": "~3.0.2",
- "fsevents": "~2.3.1",
- "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"
- }
- },
- "clean-stack": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
- "dev": true
- },
- "cli-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
- "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
- "dev": true,
- "requires": {
- "restore-cursor": "^3.1.0"
- }
- },
- "cli-truncate": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
- "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
- "dev": true,
- "requires": {
- "slice-ansi": "^3.0.0",
- "string-width": "^4.2.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "slice-ansi": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
- "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
- "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.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
- "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
- "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=",
- "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="
- },
- "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=",
- "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=",
- "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=",
- "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="
- },
- "commander": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
- "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
- "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": "7.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
- "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
- "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"
- }
- },
- "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"
- }
- },
- "crypt": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
- "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
- },
- "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="
- },
- "dedent": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/dedent/-/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": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
- "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
- },
- "dijkstrajs": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
- "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs="
- },
- "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.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
- "requires": {
- "esutils": "^2.0.2"
- }
- },
- "dom-serializer": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz",
- "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==",
- "dev": true,
- "requires": {
- "domelementtype": "^2.0.1",
- "domhandler": "^4.0.0",
- "entities": "^2.0.0"
- },
- "dependencies": {
- "domhandler": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
- "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
- "dev": true,
- "requires": {
- "domelementtype": "^2.1.0"
- }
- }
- }
- },
- "domelementtype": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
- "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==",
- "dev": true
- },
- "domhandler": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
- "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
- "dev": true,
- "requires": {
- "domelementtype": "^2.0.1"
- }
- },
- "domutils": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz",
- "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==",
- "dev": true,
- "requires": {
- "dom-serializer": "^1.0.1",
- "domelementtype": "^2.0.1",
- "domhandler": "^4.0.0"
- },
- "dependencies": {
- "domhandler": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
- "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
- "dev": true,
- "requires": {
- "domelementtype": "^2.1.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="
- },
- "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.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "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.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
- "dev": true
- },
- "error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "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"
- }
- },
- "escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
- "dev": true
- },
- "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.21.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
- "integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "7.12.11",
- "@eslint/eslintrc": "^0.4.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.1",
- "esquery": "^1.4.0",
- "esutils": "^2.0.2",
- "file-entry-cache": "^6.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.20",
- "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": "^6.0.4",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
- },
- "dependencies": {
- "@babel/code-frame": {
- "version": "7.12.11",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
- "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.10.4"
- }
- },
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "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
- },
- "levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "requires": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- }
- },
- "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
- },
- "optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
- "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.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true
- },
- "type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "requires": {
- "prelude-ls": "^1.2.1"
- }
- }
- }
- },
- "eslint-config-prettier": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz",
- "integrity": "sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA==",
- "dev": true
- },
- "eslint-plugin-html": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.1.1.tgz",
- "integrity": "sha512-JSe3ZDb7feKMnQM27XWGeoIjvP4oWQMJD9GZ6wW67J7/plVL87NK72RBwlvfc3tTZiYUchHhxAwtgEd1GdofDA==",
- "dev": true,
- "requires": {
- "htmlparser2": "^5.0.1"
- }
- },
- "eslint-plugin-prettier": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz",
- "integrity": "sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ==",
- "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.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
- "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
- "dev": true,
- "requires": {
- "acorn": "^7.4.0",
- "acorn-jsx": "^5.3.1",
- "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.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
- "dev": true,
- "requires": {
- "estraverse": "^5.1.0"
- },
- "dependencies": {
- "estraverse": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
- "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
- "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.1.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
- "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
- "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.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
- },
- "fast-diff": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
- "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
- "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.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "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.npmjs.org/figures/-/figures-3.2.0.tgz",
- "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
- "dev": true,
- "requires": {
- "escape-string-regexp": "^1.0.5"
- }
- },
- "file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "dev": true,
- "requires": {
- "flat-cache": "^3.0.4"
- }
- },
- "file-type": {
- "version": "16.1.0",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.1.0.tgz",
- "integrity": "sha512-G4Klqf6tuprtG0pC4r9kni4Wv8XhAAsfHphVqsQGA+YiOlPAO40BZduDqKfv0RFsu9q9ZbFObWfwszY/NqhEZw==",
- "requires": {
- "readable-web-to-node-stream": "^3.0.0",
- "strtok3": "^6.0.3",
- "token-types": "^2.0.0",
- "typedarray-to-buffer": "^3.1.5"
- }
- },
- "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": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "requires": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "flat": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
- "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
- "dev": true
- },
- "flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "dev": true,
- "requires": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- }
- },
- "flatted": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
- "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
- "dev": true
- },
- "follow-redirects": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz",
- "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg=="
- },
- "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.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "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="
- },
- "get-own-enumerable-property-symbols": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
- "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
- "dev": true
- },
- "get-stream": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
- "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
- "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.npmjs.org/growl/-/growl-1.10.5.tgz",
- "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
- "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.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true
- },
- "htmlparser2": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz",
- "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==",
- "dev": true,
- "requires": {
- "domelementtype": "^2.0.1",
- "domhandler": "^3.3.0",
- "domutils": "^2.4.2",
- "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.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
- "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
- "dev": true
- },
- "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"
- }
- },
- "ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
- },
- "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.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
- },
- "indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "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.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
- "dev": true
- },
- "is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "requires": {
- "binary-extensions": "^2.0.0"
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
- },
- "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="
- },
- "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.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
- "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
- "dev": true
- },
- "is-plain-obj": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
- "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
- "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.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
- "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
- "dev": true
- },
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
- "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-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
- },
- "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.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
- },
- "json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
- },
- "json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
- },
- "json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/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.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
- "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
- "dev": true
- },
- "lint-staged": {
- "version": "10.5.4",
- "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz",
- "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==",
- "dev": true,
- "requires": {
- "chalk": "^4.1.0",
- "cli-truncate": "^2.1.0",
- "commander": "^6.2.0",
- "cosmiconfig": "^7.0.0",
- "debug": "^4.2.0",
- "dedent": "^0.7.0",
- "enquirer": "^2.3.6",
- "execa": "^4.1.0",
- "listr2": "^3.2.2",
- "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": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dev": true,
- "requires": {
- "ms": "2.1.2"
- }
- },
- "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
- }
- }
- },
- "listr2": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.4.1.tgz",
- "integrity": "sha512-TYim70Kml0vISlYH7mWHqeiBytkfDwWtp4Z+HmxEXWkXCRz6sCxHisOM3b1w+OYfhLlwB7ADblC0cdZhZIriPA==",
- "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.6",
- "through": "^2.3.8",
- "wrap-ansi": "^7.0.0"
- }
- },
- "locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "requires": {
- "p-locate": "^5.0.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.npmjs.org/log-update/-/log-update-4.0.0.tgz",
- "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
- "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.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "string-width": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
- "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
- "dev": true,
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- }
- }
- },
- "md5": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
- "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
- "requires": {
- "charenc": "0.0.2",
- "crypt": "0.0.2",
- "is-buffer": "~1.1.6"
- }
- },
- "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.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "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.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "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"
- }
- },
- "mocha": {
- "version": "8.3.1",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.1.tgz",
- "integrity": "sha512-5SBMxANWqOv5bw3Hx+HVgaWlcWcFEQDUdaUAr1AUU+qwtx6cowhn7gEDT/DwQP7uYxnvShdUOVLbTYAHOEGfDQ==",
- "dev": true,
- "requires": {
- "@ungap/promise-all-settled": "1.1.2",
- "ansi-colors": "4.1.1",
- "browser-stdout": "1.3.1",
- "chokidar": "3.5.1",
- "debug": "4.3.1",
- "diff": "5.0.0",
- "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": "4.0.0",
- "log-symbols": "4.0.0",
- "minimatch": "3.0.4",
- "ms": "2.1.3",
- "nanoid": "3.1.20",
- "serialize-javascript": "5.0.1",
- "strip-json-comments": "3.1.1",
- "supports-color": "8.1.1",
- "which": "2.0.2",
- "wide-align": "1.1.3",
- "workerpool": "6.1.0",
- "yargs": "16.2.0",
- "yargs-parser": "20.2.4",
- "yargs-unparser": "2.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dev": true,
- "requires": {
- "ms": "2.1.2"
- },
- "dependencies": {
- "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
- }
- }
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "js-yaml": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
- "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
- "dev": true,
- "requires": {
- "argparse": "^2.0.1"
- }
- },
- "ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
- },
- "string-width": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
- "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
- "dev": true,
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "y18n": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
- "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
- "dev": true
- },
- "yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "dev": true,
- "requires": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- }
- },
- "yargs-parser": {
- "version": "20.2.4",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
- "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
- "dev": true
- }
- }
- },
- "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"
- }
- }
- }
- },
- "music-metadata": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-7.6.0.tgz",
- "integrity": "sha512-XSBNmv+4JwithIharDmqwEVGLqEQ62nvrpSJAc5OQcgciSlTjjZLxmAQRic1AofiMB4t45D4MS4mwGk/5PeVeQ==",
- "requires": {
- "content-type": "^1.0.4",
- "debug": "^4.3.1",
- "file-type": "^16.1.0",
- "media-typer": "^1.1.0",
- "strtok3": "^6.0.4",
- "token-types": "^2.0.0"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
- }
- },
- "nanoid": {
- "version": "3.1.20",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
- "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
- "dev": true
- },
- "natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/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.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "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.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dev": true,
- "requires": {
- "mimic-fn": "^2.1.0"
- }
- },
- "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=",
- "requires": {
- "p-try": "^2.0.0"
- }
- },
- "p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "requires": {
- "p-limit": "^3.0.2"
- },
- "dependencies": {
- "p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- }
- }
- },
- "p-map": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
- "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
- "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="
- },
- "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.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "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.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "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
- },
- "peek-readable": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-3.1.0.tgz",
- "integrity": "sha512-KGuODSTV6hcgdZvDrIDBUkN0utcAVj1LL7FfGbM0viKTtCHmtZcuEJ+lGqsp0fTFkGqesdtemV2yUSMeyy3ddA=="
- },
- "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
- },
- "please-upgrade-node": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
- "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
- "dev": true,
- "requires": {
- "semver-compare": "^1.0.0"
- }
- },
- "pngjs": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
- "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
- },
- "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.2.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
- "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
- "dev": true
- },
- "prettier-linter-helpers": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
- "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
- "dev": true,
- "requires": {
- "fast-diff": "^1.1.2"
- }
- },
- "progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "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.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true
- },
- "qrcode": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz",
- "integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==",
- "requires": {
- "buffer": "^5.4.3",
- "buffer-alloc": "^1.2.0",
- "buffer-from": "^1.1.1",
- "dijkstrajs": "^1.0.1",
- "isarray": "^2.0.1",
- "pngjs": "^3.3.0",
- "yargs": "^13.2.4"
- },
- "dependencies": {
- "isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
- }
- }
- },
- "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.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "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"
- }
- },
- "readable-web-to-node-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.0.tgz",
- "integrity": "sha512-HNmLb3n0SteGAs8HQlErYPGeO+y7cvL/mVUKtXeUkl0iCZ/2GIgKGrCFHyS7UXFnO8uc9U+0y3pYIzAPsjFfvA==",
- "requires": {
- "@types/readable-stream": "^2.3.9",
- "readable-stream": "^3.6.0"
- },
- "dependencies": {
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- },
- "string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "requires": {
- "safe-buffer": "~5.2.0"
- }
- }
- }
- },
- "readdirp": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
- "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
- "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="
- },
- "require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "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="
- },
- "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.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
- "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
- "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": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "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.6",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz",
- "integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==",
- "dev": true,
- "requires": {
- "tslib": "^1.9.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "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.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
- "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
- "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.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
- "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
- "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="
- },
- "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.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
- "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
- "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": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- }
- }
- },
- "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.npmjs.org/sprintf-js/-/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.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
- "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
- "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=",
- "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="
- },
- "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=",
- "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.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
- "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
- "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-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "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
- },
- "strtok3": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.0.5.tgz",
- "integrity": "sha512-enqQyimC8HLT3w18MQb3qcWl53QDxQ+eo9OPucprMsfLGBIlMlSId4GjK/xWvNOUowp/s4woyKvPBzcIbm59FA==",
- "requires": {
- "@tokenizer/token": "^0.1.1",
- "@types/debug": "^4.1.5",
- "peek-readable": "^3.1.0"
- }
- },
- "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": "6.0.7",
- "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz",
- "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==",
- "dev": true,
- "requires": {
- "ajv": "^7.0.2",
- "lodash": "^4.17.20",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.0"
- },
- "dependencies": {
- "ajv": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.1.tgz",
- "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==",
- "dev": true,
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- }
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
- "string-width": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.1.tgz",
- "integrity": "sha512-LL0OLyN6AnfV9xqGQpDBwedT2Rt63737LxvsRxbcwpa2aIeynBApG2Sm//F3TaLHIR1aJBN52DWklc06b94o5Q==",
- "dev": true,
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
- }
- }
- }
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
- "dev": true
- },
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/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="
- },
- "token-types": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/token-types/-/token-types-2.0.0.tgz",
- "integrity": "sha512-WWvu8sGK8/ZmGusekZJJ5NM6rRVTTDO7/bahz4NGiSDb/XsmdYBn6a1N/bymUHuWYTWeuLUg98wUzvE4jPdCZw==",
- "requires": {
- "@tokenizer/token": "^0.1.0",
- "ieee754": "^1.1.13"
- }
- },
- "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
- },
- "typedarray-to-buffer": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
- "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
- "requires": {
- "is-typedarray": "^1.0.0"
- }
- },
- "typescript": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
- "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
- "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.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "requires": {
- "punycode": "^2.1.0"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "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.2.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
- "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
- "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="
- },
- "wide-align": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
- "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
- "dev": true,
- "requires": {
- "string-width": "^1.0.2 || 2"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-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.1.0",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
- "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
- "dev": true
- },
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "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.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "string-width": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
- "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
- "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
- },
- "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="
- },
- "yaml": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
- "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
- "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=",
- "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=",
- "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=",
- "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=",
- "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="
- }
- }
- },
- "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=",
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
- },
- "yargs-unparser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
- "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
- "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.2.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
- "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
- "dev": true
- },
- "decamelize": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
- "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
- "dev": true
- }
- }
- },
- "yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true
- }
- }
-}
diff --git a/netease_api/package.json b/netease_api/package.json
deleted file mode 100644
index 3990157..0000000
--- a/netease_api/package.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "name": "NeteaseCloudMusicApi",
- "version": "4.0.8",
- "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",
- "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.21.1",
- "express": "^4.17.1",
- "express-fileupload": "^1.1.9",
- "md5": "^2.3.0",
- "music-metadata": "^7.5.3",
- "pac-proxy-agent": "^4.0.0",
- "qrcode": "^1.4.4",
- "tunnel": "^0.0.6"
- },
- "devDependencies": {
- "@types/node": "14.14.31",
- "@typescript-eslint/eslint-plugin": "4.4.1",
- "@typescript-eslint/parser": "4.4.1",
- "eslint": "7.21.0",
- "eslint-config-prettier": "7.1.0",
- "eslint-plugin-html": "6.1.1",
- "eslint-plugin-prettier": "3.3.1",
- "intelli-espower-loader": "1.0.1",
- "lint-staged": "10.5.4",
- "mocha": "8.3.1",
- "power-assert": "1.6.1",
- "prettier": "2.2.1",
- "typescript": "4.2.3"
- }
-}
diff --git a/netease_api/plugins/songUpload.js b/netease_api/plugins/songUpload.js
deleted file mode 100644
index 89d85fc..0000000
--- a/netease_api/plugins/songUpload.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const axios = require('axios')
-module.exports = async (query, request) => {
- // 获取key和token
- const tokenRes = await request(
- 'POST',
- `https://music.163.com/weapi/nos/token/alloc`,
- {
- bucket: 'jd-musicrep-privatecloud-audio-public',
- ext: 'mp3',
- filename: query.songFile.name.replace('.mp3', ''),
- local: false,
- nos_product: 3,
- type: 'audio',
- md5: query.songFile.md5,
- },
- { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy },
- )
-
- // 上传
- const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F')
- try {
- await axios({
- method: 'post',
- url: `http://45.127.129.8/jd-musicrep-privatecloud-audio-public/${objectKey}?offset=0&complete=true&version=1.0`,
- headers: {
- 'x-nos-token': tokenRes.body.result.token,
- 'Content-MD5': query.songFile.md5,
- 'Content-Type': 'audio/mpeg',
- 'Content-Length': String(query.songFile.size),
- },
- data: query.songFile.data,
- maxContentLength: Infinity,
- maxBodyLength: Infinity,
- })
- } catch (error) {
- console.log('error', error.response)
- throw error.response
- }
- return {
- ...tokenRes,
- }
-}
diff --git a/netease_api/plugins/upload.js b/netease_api/plugins/upload.js
deleted file mode 100644
index cddb52b..0000000
--- a/netease_api/plugins/upload.js
+++ /dev/null
@@ -1,48 +0,0 @@
-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/netease_api/public/avatar_update.html b/netease_api/public/avatar_update.html
deleted file mode 100644
index 7b0817f..0000000
--- a/netease_api/public/avatar_update.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
- 更新头像
-
-
-
-
-
-
-
-
-
diff --git a/netease_api/public/cloud.html b/netease_api/public/cloud.html
deleted file mode 100644
index 746b9b2..0000000
--- a/netease_api/public/cloud.html
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
- 云盘上传
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/netease_api/public/index.html b/netease_api/public/index.html
deleted file mode 100644
index ff4c0fa..0000000
--- a/netease_api/public/index.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
- 网易云音乐 API
-
-
-
- 网易云音乐 API
- 当你看到这个页面时,这个服务已经成功跑起来了~
- 查看文档
-
例子:
-
-
-
-
-
diff --git a/netease_api/public/playlist_cover_update.html b/netease_api/public/playlist_cover_update.html
deleted file mode 100644
index 75e0fe6..0000000
--- a/netease_api/public/playlist_cover_update.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
歌单封面上传
-
-
-
-
-
![]()
-
-
-
-
diff --git a/netease_api/public/qrlogin.html b/netease_api/public/qrlogin.html
deleted file mode 100644
index a6beb3e..0000000
--- a/netease_api/public/qrlogin.html
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
二维码登录
-
-
-
-
![]()
-
-
-
-
-
-
diff --git a/netease_api/public/test.html b/netease_api/public/test.html
deleted file mode 100644
index fccca52..0000000
--- a/netease_api/public/test.html
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
test
-
-
-
-
请在控制台看结果
-
-
-
-
-
-
diff --git a/netease_api/renovate.json b/netease_api/renovate.json
deleted file mode 100644
index f45d8f1..0000000
--- a/netease_api/renovate.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "extends": [
- "config:base"
- ]
-}
diff --git a/netease_api/routes/index.js b/netease_api/routes/index.js
deleted file mode 100644
index 816ff3a..0000000
--- a/netease_api/routes/index.js
+++ /dev/null
@@ -1,101 +0,0 @@
-const {
- cookieToJson
-} = require('../util/index');
-const request = require('../util/request');
-const clc = require('cli-color');
-
-const table = {
- // 注意 /album 这样的路由必须放在 /album/new 这样的路由后面
- '/top/playlist/highquality': require('../module/top_playlist_highquality'),
- '/album/detail/dynamic': require('../module/album_detail_dynamic'),
- '/recommend/resource': require('../module/recommend_resource'),
- '/playlist/subscribe': require('../module/playlist_subscribe'),
- '/user/cloud/detail': require('../module/user_cloud_detail'),
- '/playlist/catlist': require('../module/playlist_catlist'),
- '/playlist/detail': require('../module/playlist_detail'),
- '/login/cellphone': require('../module/login_cellphone'),
- '/playlist/delete': require('../module/playlist_delete'),
- '/playlist/create': require('../module/playlist_create'),
- '/playlist/tracks': require('../module/playlist_tracks'),
- '/recommend/songs': require('../module/recommend_songs'),
- '/login/qr/create': require('../module/login_qr_create'),
- '/login/qr/check': require('../module/login_qr_check'),
- '/user/cloud/del': require('../module/user_cloud_del'),
- '/toplist/artist': require('../module/toplist_artist'),
- '/artist/sublist': require('../module/artist_sublist'),
- '/login/refresh': require('../module/login_refresh'),
- '/user/playlist': require('../module/user_playlist'),
- '/album/sublist': require('../module/album_sublist'),
- '/artist/album': require('../module/artist_album'),
- '/personalized': require('../module/personalized'),
- '/top/playlist': require('../module/top_playlist'),
- '/user/account': require('../module/user_account'),
- '/login/qr/key': require('../module/login_qr_key'),
- '/daily_signin': require('../module/daily_signin'),
- '/simi/artist': require('../module/simi_artist'),
- '/song/detail': require('../module/song_detail'),
- '/user/detail': require('../module/user_detail'),
- '/personal_fm': require('../module/personal_fm'),
- '/artist/sub': require('../module/artist_sub'),
- '/mv/sublist': require('../module/mv_sublist'),
- '/user/cloud': require('../module/user_cloud'),
- '/album/new': require('../module/album_new'),
- '/album/sub': require('../module/album_sub'),
- '/mv/detail': require('../module/mv_detail'),
- '/artist/mv': require('../module/artist_mv'),
- '/song/url': require('../module/song_url'),
- '/top/song': require('../module/top_song'),
- '/scrobble': require('../module/scrobble'),
- '/likelist': require('../module/likelist'),
- '/fm_trash': require('../module/fm_trash'),
- '/artists': require('../module/artists'),
- '/simi/mv': require('../module/simi_mv'),
- '/toplist': require('../module/toplist'),
- '/logout': require('../module/logout'),
- '/mv/url': require('../module/mv_url'),
- '/mv/sub': require('../module/mv_sub'),
- '/search': require('../module/search'),
- '/lyric': require('../module/lyric'),
- '/cloud': require('../module/cloud'),
- '/album': require('../module/album'),
- '/login': require('../module/login'),
- '/like': require('../module/like'),
-}
-
-const handleRequest = (req, res, func) => {
- 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,
- )
- return func(query, request)
- .then((answer) => {
- console.log(`${clc.redBright('[NetEase API]')} OK, ${decodeURIComponent(req.originalUrl)}`);
- res.append('Set-Cookie', answer.cookie);
- res.status(answer.status).send(answer.body);
- })
- .catch((answer) => {
- console.log(`${clc.redBright('[NetEase API]')} ERROR 🚫 `, 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);
- });
-}
-
-let defaultExport = {};
-
-for (const [route, func] of Object.entries(table)) {
- defaultExport[route] = (req, res) => {
- return handleRequest(req, res, func);
- };
-};
-
-export default defaultExport;
diff --git a/netease_api/static/artist_album.png b/netease_api/static/artist_album.png
deleted file mode 100644
index 7188755..0000000
Binary files a/netease_api/static/artist_album.png and /dev/null differ
diff --git a/netease_api/static/artists.png b/netease_api/static/artists.png
deleted file mode 100644
index dfe4422..0000000
Binary files a/netease_api/static/artists.png and /dev/null differ
diff --git a/netease_api/static/banner.png b/netease_api/static/banner.png
deleted file mode 100644
index fac182a..0000000
Binary files a/netease_api/static/banner.png and /dev/null differ
diff --git a/netease_api/static/comment.png b/netease_api/static/comment.png
deleted file mode 100644
index 6631f62..0000000
Binary files a/netease_api/static/comment.png and /dev/null differ
diff --git a/netease_api/static/docs.png b/netease_api/static/docs.png
deleted file mode 100644
index 1f1794a..0000000
Binary files a/netease_api/static/docs.png and /dev/null differ
diff --git a/netease_api/static/fm_trash.png b/netease_api/static/fm_trash.png
deleted file mode 100644
index 4c85539..0000000
Binary files a/netease_api/static/fm_trash.png and /dev/null differ
diff --git a/netease_api/static/like.png b/netease_api/static/like.png
deleted file mode 100644
index 85acf19..0000000
Binary files a/netease_api/static/like.png and /dev/null differ
diff --git a/netease_api/static/likeSuccess.png b/netease_api/static/likeSuccess.png
deleted file mode 100644
index d882a6b..0000000
Binary files a/netease_api/static/likeSuccess.png and /dev/null differ
diff --git a/netease_api/static/mv.png b/netease_api/static/mv.png
deleted file mode 100644
index dbb9b16..0000000
Binary files a/netease_api/static/mv.png and /dev/null differ
diff --git a/netease_api/static/new_albums.png b/netease_api/static/new_albums.png
deleted file mode 100644
index b5ceaa4..0000000
Binary files a/netease_api/static/new_albums.png and /dev/null differ
diff --git a/netease_api/static/personal_fm.png b/netease_api/static/personal_fm.png
deleted file mode 100644
index ba0d297..0000000
Binary files a/netease_api/static/personal_fm.png and /dev/null differ
diff --git a/netease_api/static/play_mv.png b/netease_api/static/play_mv.png
deleted file mode 100644
index de23951..0000000
Binary files a/netease_api/static/play_mv.png and /dev/null differ
diff --git a/netease_api/static/screenshot1.png b/netease_api/static/screenshot1.png
deleted file mode 100644
index eb20062..0000000
Binary files a/netease_api/static/screenshot1.png and /dev/null differ
diff --git a/netease_api/static/screenshot2.png b/netease_api/static/screenshot2.png
deleted file mode 100644
index 1d8418d..0000000
Binary files a/netease_api/static/screenshot2.png and /dev/null differ
diff --git a/netease_api/static/signinError.png b/netease_api/static/signinError.png
deleted file mode 100644
index e5815dc..0000000
Binary files a/netease_api/static/signinError.png and /dev/null differ
diff --git a/netease_api/static/signinSuccess.png b/netease_api/static/signinSuccess.png
deleted file mode 100644
index 7778a57..0000000
Binary files a/netease_api/static/signinSuccess.png and /dev/null differ
diff --git a/netease_api/static/songDetail.png b/netease_api/static/songDetail.png
deleted file mode 100644
index 808d0b1..0000000
Binary files a/netease_api/static/songDetail.png and /dev/null differ
diff --git a/netease_api/static/top_artists.png b/netease_api/static/top_artists.png
deleted file mode 100644
index 4105876..0000000
Binary files a/netease_api/static/top_artists.png and /dev/null differ
diff --git a/netease_api/static/top_list.png b/netease_api/static/top_list.png
deleted file mode 100644
index d1fbe02..0000000
Binary files a/netease_api/static/top_list.png and /dev/null differ
diff --git a/netease_api/static/top_playlist.png b/netease_api/static/top_playlist.png
deleted file mode 100644
index 51715d6..0000000
Binary files a/netease_api/static/top_playlist.png and /dev/null differ
diff --git a/netease_api/static/专辑.png b/netease_api/static/专辑.png
deleted file mode 100644
index 251f6a8..0000000
Binary files a/netease_api/static/专辑.png and /dev/null differ
diff --git a/netease_api/static/推荐歌单.png b/netease_api/static/推荐歌单.png
deleted file mode 100644
index 05a425a..0000000
Binary files a/netease_api/static/推荐歌单.png and /dev/null differ
diff --git a/netease_api/static/推荐歌曲.png b/netease_api/static/推荐歌曲.png
deleted file mode 100644
index fdd8f9e..0000000
Binary files a/netease_api/static/推荐歌曲.png and /dev/null differ
diff --git a/netease_api/static/搜索.png b/netease_api/static/搜索.png
deleted file mode 100644
index c787181..0000000
Binary files a/netease_api/static/搜索.png and /dev/null differ
diff --git a/netease_api/static/歌单详情.png b/netease_api/static/歌单详情.png
deleted file mode 100644
index 9300715..0000000
Binary files a/netease_api/static/歌单详情.png and /dev/null differ
diff --git a/netease_api/static/歌词.png b/netease_api/static/歌词.png
deleted file mode 100644
index e886906..0000000
Binary files a/netease_api/static/歌词.png and /dev/null differ
diff --git a/netease_api/static/用户歌单.png b/netease_api/static/用户歌单.png
deleted file mode 100644
index 5c1835f..0000000
Binary files a/netease_api/static/用户歌单.png and /dev/null differ
diff --git a/netease_api/static/登录.png b/netease_api/static/登录.png
deleted file mode 100644
index fdf6c80..0000000
Binary files a/netease_api/static/登录.png and /dev/null differ
diff --git a/netease_api/static/音乐 url.png b/netease_api/static/音乐 url.png
deleted file mode 100644
index 14599c6..0000000
Binary files a/netease_api/static/音乐 url.png and /dev/null differ
diff --git a/netease_api/test/album.test.js b/netease_api/test/album.test.js
deleted file mode 100644
index 2a6a1b9..0000000
--- a/netease_api/test/album.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const assert = require('assert')
-const axios = require('axios')
-const host = global.host || 'http://localhost:3000'
-
-describe('测试获取歌手专辑列表是否正常', () => {
- it('数据的 code 应该为200', (done) => {
- const qs = {
- id: 32311,
- }
-
- axios
- .get(`${host}/album`, {
- params: qs,
- })
- .then(({ status, data }) => {
- if (status == 200) {
- assert(data.code === 200)
- }
- done()
- })
- .catch((err) => {
- done(err)
- })
- })
-})
diff --git a/netease_api/test/comment.test.js b/netease_api/test/comment.test.js
deleted file mode 100644
index 612f670..0000000
--- a/netease_api/test/comment.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const assert = require('assert')
-const axios = require('axios')
-const host = global.host || 'http://localhost:3000'
-
-describe('测试获取评论是否正常', () => {
- it('数据的 code 应该为200', (done) => {
- const qs = {
- id: 32311,
- }
-
- axios
- .get(`${host}/comment/album`, {
- params: qs,
- })
- .then(({ status, data }) => {
- if (status == 200) {
- assert(data.code === 200)
- }
- done()
- })
- .catch((err) => {
- done(err)
- })
- })
-})
diff --git a/netease_api/test/login.test.js b/netease_api/test/login.test.js
deleted file mode 100644
index d10da4b..0000000
--- a/netease_api/test/login.test.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const assert = require('assert')
-const axios = require('axios')
-const host = global.host || 'http://localhost:3000'
-
-console.log('注意: 测试登录需在 test/login.test.js 中填写账号密码!!!')
-const phone = ''
-const password = ''
-describe('测试登录是否正常', () => {
- it('手机登录 code 应该等于200', (done) => {
- const qs = {
- phone: process.env.NCM_API_TEST_LOGIN_PHONE || phone || '',
- password: process.env.NCM_API_TEST_LOGIN_PASSWORD || password || '',
- }
-
- axios
- .get(`${host}/login/cellphone`, {
- params: qs,
- })
- .then(({ status, data }) => {
- if (status == 200) {
- console.log('昵称:' + data.profile.nickname)
- assert(data.code === 200)
- done()
- } else {
- done('登录错误')
- }
- })
- .catch((err) => {
- done(err)
- })
- })
-})
diff --git a/netease_api/test/lyric.test.js b/netease_api/test/lyric.test.js
deleted file mode 100644
index 41886e4..0000000
--- a/netease_api/test/lyric.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const assert = require('assert')
-const axios = require('axios')
-const host = global.host || 'http://localhost:3000'
-
-describe('测试获取歌词是否正常', () => {
- it('数据应该有 lrc 字段', (done) => {
- const qs = {
- id: 347230,
- }
-
- axios
- .get(`${host}/lyric`, {
- params: qs,
- })
- .then(({ status, data }) => {
- if (status == 200) {
- assert(typeof data.lrc !== 'undefined')
- }
- done()
- })
- .catch((err) => {
- done(err)
- })
- })
-})
diff --git a/netease_api/test/music_url.test.js b/netease_api/test/music_url.test.js
deleted file mode 100644
index cf7777c..0000000
--- a/netease_api/test/music_url.test.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const assert = require('assert')
-const axios = require('axios')
-const host = global.host || 'http://localhost:3000'
-
-describe('测试获取歌曲是否正常', () => {
- it('歌曲的 url 不应该为空', (done) => {
- const qs = {
- id: 462791935,
- br: 999000,
- }
-
- axios
- .get(`${host}/song/url`, {
- params: qs,
- })
- .then(({ status, data }) => {
- if (status == 200) {
- assert(!!data.data[0].url)
- }
- done()
- })
- .catch((err) => {
- done(err)
- })
- })
-})
diff --git a/netease_api/test/search.test.js b/netease_api/test/search.test.js
deleted file mode 100644
index e80dea5..0000000
--- a/netease_api/test/search.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const assert = require('assert')
-const axios = require('axios')
-const host = global.host || 'http://localhost:3000'
-
-describe('测试搜索是否正常', () => {
- it('获取到的数据的 name 应该和搜索关键词一致', (done) => {
- const qs = {
- keywords: '海阔天空',
- type: 1,
- }
- axios
- .get(`${host}/search`, {
- params: qs,
- })
- .then(({ status, data }) => {
- if (status == 200) {
- assert(data.result.songs[0].name === '海阔天空')
- }
- done()
- })
- .catch((err) => {
- done(err)
- })
- })
-})
diff --git a/netease_api/tsconfig.json b/netease_api/tsconfig.json
deleted file mode 100644
index 9656c53..0000000
--- a/netease_api/tsconfig.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "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"
- ]
- }
\ No newline at end of file
diff --git a/netease_api/util/apicache.js b/netease_api/util/apicache.js
deleted file mode 100644
index a71c998..0000000
--- a/netease_api/util/apicache.js
+++ /dev/null
@@ -1,830 +0,0 @@
-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/netease_api/util/config.json b/netease_api/util/config.json
deleted file mode 100644
index dbfda36..0000000
--- a/netease_api/util/config.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "anonymous_token": "8aae43f148f990410b9a2af38324af24e87ab9227c9265627ddd10145db744295fcd8701dc45b1ab8985e142f491516295dd965bae848761274a577a62b0fdc54a50284d1e434dcc04ca6d1a52333c9a",
- "resourceTypeMap": {
- "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_"
- }
-}
diff --git a/netease_api/util/crypto.js b/netease_api/util/crypto.js
deleted file mode 100644
index 3f99e85..0000000
--- a/netease_api/util/crypto.js
+++ /dev/null
@@ -1,67 +0,0 @@
-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/netease_api/util/index.js b/netease_api/util/index.js
deleted file mode 100644
index 06aade5..0000000
--- a/netease_api/util/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-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/netease_api/util/memory-cache.js b/netease_api/util/memory-cache.js
deleted file mode 100644
index 6b6deaa..0000000
--- a/netease_api/util/memory-cache.js
+++ /dev/null
@@ -1,63 +0,0 @@
-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/netease_api/util/request.js b/netease_api/util/request.js
deleted file mode 100644
index 7b4f45a..0000000
--- a/netease_api/util/request.js
+++ /dev/null
@@ -1,192 +0,0 @@
-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 || '8.0.0', // 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: [] }
- let settings = {
- method: method,
- url: url,
- headers: headers,
- data: queryString.stringify(data),
- httpAgent: new http.Agent({ keepAlive: true }),
- httpsAgent: new https.Agent({ keepAlive: true, rejectUnauthorized: false }),
- }
-
- 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('代理配置无效,不使用代理')
- }
- }
- }
- if (options.crypto === 'eapi') {
- settings = {
- ...settings,
- responseType: 'arraybuffer',
- }
- }
- axios(settings)
- .then((res) => {
- const body = res.data
- answer.cookie = (res.headers['set-cookie'] || []).map((x) =>
- x.replace(/\s*Domain=[^(;|$)]+;*/, ''),
- )
- try {
- if (options.crypto === 'eapi') {
- answer.body = JSON.parse(encrypt.decrypt(body).toString())
- } else {
- answer.body = body
- }
-
- answer.status = answer.body.code || res.status
- if (
- [201, 302, 400, 502, 800, 801, 802, 803].indexOf(answer.body.code) >
- -1
- ) {
- // 特殊状态码
- answer.status = 200
- }
- } catch (e) {
- // console.log(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/netease_api/vercel.json b/netease_api/vercel.json
deleted file mode 100644
index e8eaad7..0000000
--- a/netease_api/vercel.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "version": 2,
- "builds": [
- {
- "src": "./index.js",
- "use": "@vercel/node"
- }
- ],
- "routes": [
- {
- "src": "/(.*)",
- "dest": "/"
- }
- ]
-}
diff --git a/package.json b/package.json
index 5edf246..bb87fdd 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
{
"name": "yesplaymusic",
- "version": "0.4.1",
+ "version": "0.4.9",
"private": true,
"description": "A third party music player for Netease Music",
- "author": "hawtim
",
+ "author": "qier222",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
@@ -18,62 +18,68 @@
"electron:publish": "vue-cli-service electron:build -mwl -p always",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps",
- "prettier": "npx prettier --write ./src ./script",
- "netease_api:run": "cd ./netease_api && npm run start",
- "netease_api:pull": "node script/pull.js",
- "netease_api:install": "cd ./netease_api && npm install",
- "netease_api:setup": "npm run netease_api:pull && npm run netease_api:install"
+ "prettier": "npx prettier --write ./src",
+ "netease_api:run": "npx NeteaseCloudMusicApi"
},
"main": "background.js",
+ "engines": {
+ "node": "14 || 16"
+ },
"dependencies": {
- "@revincx/unblockneteasemusic": "^0.25.7",
- "axios": "^0.21.0",
+ "@unblockneteasemusic/rust-napi": "^0.4.0",
+ "NeteaseCloudMusicApi": "^4.23.3",
+ "axios": "^0.26.1",
"change-case": "^4.1.2",
"cli-color": "^2.0.0",
- "color": "^3.1.3",
+ "color": "^4.2.3",
"core-js": "^3.6.5",
"crypto-js": "^4.0.0",
"dayjs": "^1.8.36",
"dexie": "^3.0.3",
"discord-rich-presence": "^0.0.8",
- "electron": "^13.0.1",
- "electron-builder": "^22.10.5",
- "electron-context-menu": "^2.3.0",
+ "electron": "^13.6.7",
+ "electron-builder": "^23.0.0",
+ "electron-context-menu": "^3.1.2",
"electron-debug": "^3.1.0",
"electron-devtools-installer": "^3.2",
- "electron-icon-builder": "^1.0.2",
- "electron-is-dev": "^1.2.0",
+ "electron-icon-builder": "^2.0.1",
+ "electron-is-dev": "^2.0.0",
"electron-log": "^4.3.0",
- "electron-store": "^6.0.1",
- "electron-updater": "^4.3.5",
+ "electron-store": "^8.0.1",
+ "electron-updater": "^5.0.1",
+ "esbuild": "^0.20.1",
+ "esbuild-loader": "^4.0.3",
"express": "^4.17.1",
- "md5": "^2.3.0",
- "music-metadata": "^7.5.3",
"express-fileupload": "^1.2.0",
"express-http-proxy": "^1.6.2",
"extract-zip": "^2.0.1",
"howler": "^2.2.3",
"js-cookie": "^2.2.1",
+ "jsbi": "^4.1.0",
"lodash": "^4.17.20",
- "node-vibrant": "^3.1.6",
+ "md5": "^2.3.0",
+ "mpris-service": "^2.1.2",
+ "music-metadata": "^7.5.3",
+ "node-vibrant": "^3.2.1-alpha.1",
"nprogress": "^0.2.0",
"pac-proxy-agent": "^4.1.0",
"plyr": "^3.6.2",
- "prettier": "2.1.2",
"qrcode": "^1.4.4",
"register-service-worker": "^1.7.1",
- "svg-sprite-loader": "^5.0.0",
+ "svg-sprite-loader": "^6.0.11",
"tunnel": "^0.0.6",
- "vscode-codicons": "^0.0.14",
+ "vscode-codicons": "^0.0.17",
"vue": "^2.6.11",
- "vue-analytics": "^5.22.1",
"vue-clipboard2": "^0.3.1",
+ "vue-gtag": "1",
"vue-i18n": "^8.22.0",
"vue-router": "^3.4.3",
"vue-slider-component": "^3.2.5",
- "vuex": "^3.4.0"
+ "vuex": "^3.4.0",
+ "x11": "^2.3.0"
},
"devDependencies": {
+ "@types/node": "^17.0.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-pwa": "~4.5.0",
@@ -85,11 +91,17 @@
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.9.0",
"husky": "^4.3.0",
+ "prettier": "2.5.1",
"sass": "^1.26.11",
"sass-loader": "^10.0.2",
- "vue-cli-plugin-electron-builder": "~2.0.0-rc.4",
+ "vue-cli-plugin-electron-builder": "~2.1.1",
"vue-template-compiler": "^2.6.11"
},
+ "resolutions": {
+ "icon-gen": "3.0.0",
+ "degenerator": "2.2.0",
+ "electron-builder": "^23.0.0"
+ },
"eslintConfig": {
"root": true,
"env": {
diff --git a/public/img/icons/menu-dark@88.png b/public/img/icons/menu-dark@88.png
new file mode 100644
index 0000000..a2feb00
Binary files /dev/null and b/public/img/icons/menu-dark@88.png differ
diff --git a/public/img/icons/menu@88.png b/public/img/icons/menu-light@88.png
similarity index 100%
rename from public/img/icons/menu@88.png
rename to public/img/icons/menu-light@88.png
diff --git a/public/img/icons/pause.png b/public/img/icons/pause.png
new file mode 100644
index 0000000..509d738
Binary files /dev/null and b/public/img/icons/pause.png differ
diff --git a/public/img/icons/unlike.png b/public/img/icons/unlike.png
new file mode 100644
index 0000000..a0afa24
Binary files /dev/null and b/public/img/icons/unlike.png differ
diff --git a/public/img/logos/yesplaymusic-white24x24.png b/public/img/logos/yesplaymusic-white24x24.png
new file mode 100644
index 0000000..d8e4715
Binary files /dev/null and b/public/img/logos/yesplaymusic-white24x24.png differ
diff --git a/public/robots.txt b/public/robots.txt
index eb05362..1f53798 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -1,2 +1,2 @@
User-agent: *
-Disallow:
+Disallow: /
diff --git a/restyled.yml b/restyled.yml
new file mode 100644
index 0000000..c31d3e8
--- /dev/null
+++ b/restyled.yml
@@ -0,0 +1,7 @@
+commit_template: 'style: with ${restyler.name}'
+restylers:
+ - prettier
+ - prettier-json
+ - prettier-markdown
+ - prettier-yaml
+ - whitespace
diff --git a/script/pull.js b/script/pull.js
deleted file mode 100644
index 30ac9b2..0000000
--- a/script/pull.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// node module
-const fs = require('fs');
-const https = require('https');
-const resolve = require('path').resolve;
-const join = require('path').resolve;
-const extract = require('extract-zip');
-
-// 函数参数
-const dest = resolve(__dirname, '../');
-const fileName = 'NeteaseCloudMusicApi-master.zip';
-const options = {
- hostname: 'github.91chifun.workers.dev',
- path: `//https://github.com/Binaryify/NeteaseCloudMusicApi/archive/master.zip`,
-};
-
-// 完整的流程控制
-/**
- * 1. 检查本地文件是否已有
- * 2. 下载默认/指定版本的 zip 压缩包,等待下载
- * 3. 解压缩
- * 4. 进入目录安装依赖 npm install
- */
-
-function fix2(number) {
- return number.toFixed(2);
-}
-
-async function download(options, fileName, callback) {
- return await new Promise((resolve, reject) => {
- const destPath = join(__dirname, '../' + fileName);
- // Check if exist
- if (fs.existsSync(destPath)) return resolve(destPath);
-
- const file = fs.createWriteStream(destPath);
- const request = https.get(options, res => {
- let len = res.headers && parseInt(res.headers['content-length'], 10);
- let cur = 0;
- // 1048576 - bytes in 1Megabyte
- const MEGA = 1048576;
- let total = 0;
- if (len) {
- total = len / MEGA;
- }
- if (!len) {
- console.log(
- 'Downloading, but can not get content-length, please be patient.'
- );
- }
- res.on('data', chunk => {
- if (len) {
- cur += chunk.length;
- console.log(
- `Downloading ${fix2((100.0 * cur) / len)}% ${fix2(
- cur / MEGA
- )}/${fix2(total)}mb`
- );
- }
- });
- res.on('end', () => {
- callback('Downloading complete!');
- });
- res.pipe(file);
- file.on('finish', () => {
- file.close(() => {
- callback('File wrote complete!');
- resolve(destPath);
- });
- });
- file.on('error', err => {
- fs.unlink(destPath);
- reject(err);
- });
- request.on('error', err => {
- console.log('Error: ' + err.message);
- });
- });
- });
-}
-
-async function unzip(source, target) {
- try {
- await extract(source, {
- dir: target,
- });
- console.log('Extraction complete');
- return true;
- } catch (err) {
- // handle any errors
- if (err.message === 'end of central directory record signature not found') {
- console.log('Not a full_downloaded zip file, removed!');
- fs.unlinkSync(source);
- }
- return false;
- }
-}
-// Download process
-download(options, fileName, text => {
- console.log(text);
-}).then(path => {
- console.log(path);
- // Unzip process
- return unzip(path, dest);
-});
diff --git a/src/App.vue b/src/App.vue
index b9d7d41..59392be 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -124,6 +124,7 @@ main {
overflow: auto;
padding: 64px 10vw 96px 10vw;
box-sizing: border-box;
+ scrollbar-width: none; // firefox
}
@media (max-width: 1336px) {
diff --git a/src/api/artist.js b/src/api/artist.js
index 462f707..925df45 100644
--- a/src/api/artist.js
+++ b/src/api/artist.js
@@ -1,5 +1,7 @@
import request from '@/utils/request';
import { mapTrackPlayableStatus } from '@/utils/common';
+import { isAccountLoggedIn } from '@/utils/auth';
+import { getTrackDetail } from '@/api/track';
/**
* 获取歌手单曲
@@ -14,7 +16,13 @@ export function getArtist(id) {
id,
timestamp: new Date().getTime(),
},
- }).then(data => {
+ }).then(async data => {
+ if (!isAccountLoggedIn()) {
+ const trackIDs = data.hotSongs.map(t => t.id);
+ const tracks = await getTrackDetail(trackIDs.join(','));
+ data.hotSongs = tracks.songs;
+ return data;
+ }
data.hotSongs = mapTrackPlayableStatus(data.hotSongs);
return data;
});
diff --git a/src/api/playlist.js b/src/api/playlist.js
index b1b9a84..08177ea 100644
--- a/src/api/playlist.js
+++ b/src/api/playlist.js
@@ -26,7 +26,10 @@ export function dailyRecommendPlaylist(params) {
return request({
url: '/recommend/resource',
method: 'get',
- params,
+ params: {
+ params,
+ timestamp: Date.now(),
+ },
});
}
/**
@@ -206,3 +209,21 @@ export function dailyRecommendTracks() {
return result;
});
}
+
+/**
+ * 心动模式/智能播放
+ * 说明 : 登录后调用此接口 , 可获取心动模式/智能播放列表 必选参数 : id : 歌曲 id
+ * - id : 歌曲 id
+ * - pid : 歌单 id
+ * - sid : 要开始播放的歌曲的 id (可选参数)
+ * @param {Object} params
+ * @param {number=} params.id
+ * @param {number=} params.pid
+ */
+export function intelligencePlaylist(params) {
+ return request({
+ url: '/playmode/intelligence/list',
+ method: 'get',
+ params,
+ });
+}
diff --git a/src/api/track.js b/src/api/track.js
index 472dc6a..490c91c 100644
--- a/src/api/track.js
+++ b/src/api/track.js
@@ -15,16 +15,18 @@ import {
* @param {string} id - 音乐的 id,例如 id=405998841,33894312
*/
export function getMP3(id) {
- let br =
- store.state.settings?.musicQuality !== undefined
- ? store.state.settings.musicQuality
- : 320000;
+ const getBr = () => {
+ // 当返回的 quality >= 400000时,就会优先返回 hi-res
+ const quality = store.state.settings?.musicQuality ?? '320000';
+ return quality === 'flac' ? '350000' : quality;
+ };
+
return request({
url: '/song/url',
method: 'get',
params: {
id,
- br,
+ br: getBr(),
},
});
}
diff --git a/src/api/user.js b/src/api/user.js
index 8269297..ec02014 100644
--- a/src/api/user.js
+++ b/src/api/user.js
@@ -50,6 +50,23 @@ export function userPlaylist(params) {
});
}
+/**
+ * 获取用户播放记录
+ * 说明 : 登录后调用此接口 , 传入用户 id, 可获取用户播放记录
+ * - uid : 用户 id
+ * - type : type=1 时只返回 weekData, type=0 时返回 allData
+ * @param {Object} params
+ * @param {number} params.uid
+ * @param {number} params.type
+ */
+export function userPlayHistory(params) {
+ return request({
+ url: '/user/record',
+ method: 'get',
+ params,
+ });
+}
+
/**
* 喜欢音乐列表(需要登录)
* 说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组)
diff --git a/src/assets/icons/fullscreen-exit.svg b/src/assets/icons/fullscreen-exit.svg
new file mode 100644
index 0000000..f76f601
--- /dev/null
+++ b/src/assets/icons/fullscreen-exit.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/fullscreen.svg b/src/assets/icons/fullscreen.svg
new file mode 100644
index 0000000..e6128c0
--- /dev/null
+++ b/src/assets/icons/fullscreen.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/sort-up.svg b/src/assets/icons/sort-up.svg
new file mode 100644
index 0000000..3efe4cf
--- /dev/null
+++ b/src/assets/icons/sort-up.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/background.js b/src/background.js
index b3c90cb..94dbbc0 100644
--- a/src/background.js
+++ b/src/background.js
@@ -7,7 +7,16 @@ import {
dialog,
globalShortcut,
nativeTheme,
+ screen,
} from 'electron';
+import {
+ isWindows,
+ isMac,
+ isLinux,
+ isDevelopment,
+ isCreateTray,
+ isCreateMpris,
+} from '@/utils/platform';
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
import { startNeteaseMusicApi } from './electron/services';
import { initIpcMain } from './electron/ipcMain.js';
@@ -18,23 +27,64 @@ import { createDockMenu } from './electron/dockMenu';
import { registerGlobalShortcut } from './electron/globalShortcut';
import { autoUpdater } from 'electron-updater';
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
+import { EventEmitter } from 'events';
import express from 'express';
import expressProxy from 'express-http-proxy';
import Store from 'electron-store';
+import { createMpris, createDbus } from '@/electron/mpris';
+import { spawn } from 'child_process';
const clc = require('cli-color');
const log = text => {
console.log(`${clc.blueBright('[background.js]')} ${text}`);
};
-const isWindows = process.platform === 'win32';
-const isMac = process.platform === 'darwin';
-const isLinux = process.platform === 'linux';
-const isDevelopment = process.env.NODE_ENV === 'development';
+const closeOnLinux = (e, win, store) => {
+ let closeOpt = store.get('settings.closeAppOption');
+ if (closeOpt !== 'exit') {
+ e.preventDefault();
+ }
+
+ if (closeOpt === 'ask') {
+ dialog
+ .showMessageBox({
+ type: 'info',
+ title: 'Information',
+ cancelId: 2,
+ defaultId: 0,
+ message: '确定要关闭吗?',
+ buttons: ['最小化到托盘', '直接退出'],
+ checkboxLabel: '记住我的选择',
+ })
+ .then(result => {
+ if (result.checkboxChecked && result.response !== 2) {
+ win.webContents.send(
+ 'rememberCloseAppOption',
+ result.response === 0 ? 'minimizeToTray' : 'exit'
+ );
+ }
+
+ if (result.response === 0) {
+ win.hide(); //调用 最小化实例方法
+ } else if (result.response === 1) {
+ win = null;
+ app.exit(); //exit()直接关闭客户端,不会执行quit();
+ }
+ })
+ .catch(err => {
+ log(err);
+ });
+ } else if (closeOpt === 'exit') {
+ win = null;
+ app.quit();
+ } else {
+ win.hide();
+ }
+};
class Background {
constructor() {
this.window = null;
- this.tray = null;
+ this.ypmTrayImpl = null;
this.store = new Store({
windowWidth: {
width: { type: 'number', default: 1440 },
@@ -43,7 +93,7 @@ class Background {
});
this.neteaseMusicAPI = null;
this.expressApp = null;
- this.willQuitApp = isMac ? false : true;
+ this.willQuitApp = !isMac;
this.init();
}
@@ -67,6 +117,14 @@ class Background {
// handle app events
this.handleAppEvents();
+
+ // disable chromium mpris
+ if (isCreateMpris) {
+ app.commandLine.appendSwitch(
+ 'disable-features',
+ 'HardwareMediaKeyHandling,MediaSessionService'
+ );
+ }
}
async initDevtools() {
@@ -124,7 +182,10 @@ class Background {
minWidth: 1080,
minHeight: 720,
titleBarStyle: 'hiddenInset',
- frame: !isWindows,
+ frame: !(
+ isWindows ||
+ (isLinux && this.store.get('settings.linuxEnableCustomTitlebar'))
+ ),
title: 'YesPlayMusic',
show: false,
webPreferences: {
@@ -142,8 +203,42 @@ class Background {
};
if (this.store.get('window.x') && this.store.get('window.y')) {
- options.x = this.store.get('window.x');
- options.y = this.store.get('window.y');
+ let x = this.store.get('window.x');
+ let y = this.store.get('window.y');
+
+ let displays = screen.getAllDisplays();
+ let isResetWindiw = false;
+ if (displays.length === 1) {
+ let { bounds } = displays[0];
+ if (
+ x < bounds.x ||
+ x > bounds.x + bounds.width - 50 ||
+ y < bounds.y ||
+ y > bounds.y + bounds.height - 50
+ ) {
+ isResetWindiw = true;
+ }
+ } else {
+ isResetWindiw = true;
+ for (let i = 0; i < displays.length; i++) {
+ let { bounds } = displays[i];
+ if (
+ x > bounds.x &&
+ x < bounds.x + bounds.width &&
+ y > bounds.y &&
+ y < bounds.y - bounds.height
+ ) {
+ // 检测到APP窗口当前处于一个可用的屏幕里,break
+ isResetWindiw = false;
+ break;
+ }
+ }
+ }
+
+ if (!isResetWindiw) {
+ options.x = x;
+ options.y = y;
+ }
}
this.window = new BrowserWindow(options);
@@ -202,22 +297,31 @@ class Background {
this.window.once('ready-to-show', () => {
log('window ready-to-show event');
this.window.show();
+ this.store.set('window', this.window.getBounds());
});
this.window.on('close', e => {
log('window close event');
- let closeOpt = this.store.get('settings.closeAppOption');
- if (this.willQuitApp && (closeOpt === 'exit' || closeOpt === 'ask')) {
- /* the user tried to quit the app */
- this.window = null;
- app.quit();
- } else if (!this.willQuitApp && isMac) {
- e.preventDefault();
- this.window.hide();
+
+ if (isLinux) {
+ closeOnLinux(e, this.window, this.store);
+ } else if (isMac) {
+ if (this.willQuitApp) {
+ this.window = null;
+ app.quit();
+ } else {
+ e.preventDefault();
+ this.window.hide();
+ }
} else {
- /* the user only tried to close the window */
- e.preventDefault();
- this.window.minimize();
+ let closeOpt = this.store.get('settings.closeAppOption');
+ if (this.willQuitApp && (closeOpt === 'exit' || closeOpt === 'ask')) {
+ this.window = null;
+ app.quit();
+ } else {
+ e.preventDefault();
+ this.window.hide();
+ }
}
});
@@ -229,13 +333,12 @@ class Background {
this.store.set('window', this.window.getBounds());
});
- this.window.on('minimize', () => {
- if (
- !isMac &&
- this.store.get('settings.closeAppOption') === 'minimizeToTray'
- ) {
- this.window.hide();
- }
+ this.window.on('maximize', () => {
+ this.window.webContents.send('isMaximized', true);
+ });
+
+ this.window.on('unmaximize', () => {
+ this.window.webContents.send('isMaximized', false);
});
this.window.webContents.on('new-window', function (e, url) {
@@ -282,8 +385,14 @@ class Background {
});
this.handleWindowEvents();
+ // create tray
+ if (isCreateTray) {
+ this.trayEventEmitter = new EventEmitter();
+ this.ypmTrayImpl = createTray(this.window, this.trayEventEmitter);
+ }
+
// init ipcMain
- initIpcMain(this.window, this.store);
+ initIpcMain(this.window, this.store, this.trayEventEmitter);
// set proxy
const proxyRules = this.store.get('proxy');
@@ -299,21 +408,38 @@ class Background {
// create menu
createMenu(this.window, this.store);
- // create tray
- if (isWindows || isLinux || isDevelopment) {
- this.tray = createTray(this.window);
- }
-
// create dock menu for macOS
- app.dock.setMenu(createDockMenu(this.window));
+ const createdDockMenu = createDockMenu(this.window);
+ if (createDockMenu && app.dock) app.dock.setMenu(createdDockMenu);
// create touch bar
- this.window.setTouchBar(createTouchBar(this.window));
+ const createdTouchBar = createTouchBar(this.window);
+ if (createdTouchBar) this.window.setTouchBar(createdTouchBar);
// register global shortcuts
if (this.store.get('settings.enableGlobalShortcut') !== false) {
registerGlobalShortcut(this.window, this.store);
}
+
+ // try to start osdlyrics process on start
+ if (this.store.get('settings.enableOsdlyricsSupport')) {
+ await createDbus(this.window);
+ log('try to start osdlyrics process');
+ const osdlyricsProcess = spawn('osdlyrics');
+
+ osdlyricsProcess.on('error', err => {
+ log(`failed to start osdlyrics: ${err.message}`);
+ });
+
+ osdlyricsProcess.on('exit', (code, signal) => {
+ log(`osdlyrics process exited with code ${code}, signal ${signal}`);
+ });
+ }
+
+ // create mpris
+ if (isCreateMpris) {
+ createMpris(this.window);
+ }
});
app.on('activate', () => {
@@ -345,6 +471,18 @@ class Background {
// unregister all global shortcuts
globalShortcut.unregisterAll();
});
+
+ if (!isMac) {
+ app.on('second-instance', (e, cl, wd) => {
+ if (this.window) {
+ this.window.show();
+ if (this.window.isMinimized()) {
+ this.window.restore();
+ }
+ this.window.focus();
+ }
+ });
+ }
}
}
diff --git a/src/components/ArtistsInLine.vue b/src/components/ArtistsInLine.vue
index cc13384..e2c619d 100644
--- a/src/components/ArtistsInLine.vue
+++ b/src/components/ArtistsInLine.vue
@@ -2,11 +2,13 @@
{{ computedPrefix }}
-
- {{ ar.name }}
-
+ {{
+ ar.name
+ }}
{{ ar.name }}
- ,
+ ,
@@ -40,4 +42,12 @@ export default {
};
-
+
diff --git a/src/components/ContextMenu.vue b/src/components/ContextMenu.vue
index dd6365b..186448f 100644
--- a/src/components/ContextMenu.vue
+++ b/src/components/ContextMenu.vue
@@ -15,6 +15,8 @@
+
+
diff --git a/src/components/Modal.vue b/src/components/Modal.vue
index 4ddc909..6657369 100644
--- a/src/components/Modal.vue
+++ b/src/components/Modal.vue
@@ -39,11 +39,16 @@ export default {
type: Boolean,
default: false,
},
+ minWidth: {
+ type: String,
+ default: 'calc(min(23rem, 100vw))',
+ },
},
computed: {
modalStyles() {
return {
width: this.width,
+ minWidth: this.minWidth,
};
},
},
diff --git a/src/components/ModalAddTrackToPlaylist.vue b/src/components/ModalAddTrackToPlaylist.vue
index 193bcd4..e6c94dd 100644
--- a/src/components/ModalAddTrackToPlaylist.vue
+++ b/src/components/ModalAddTrackToPlaylist.vue
@@ -17,7 +17,7 @@
class="playlist"
@click="addTrackToPlaylist(playlist.id)"
>
-
+
{{ playlist.name }}
{{ playlist.trackCount }} 首
diff --git a/src/components/ModalNewPlaylist.vue b/src/components/ModalNewPlaylist.vue
index 29e997e..0bbc8f4 100644
--- a/src/components/ModalNewPlaylist.vue
+++ b/src/components/ModalNewPlaylist.vue
@@ -147,6 +147,7 @@ export default {
label {
font-size: 12px;
}
+ user-select: none;
}
}
}
diff --git a/src/components/MvRow.vue b/src/components/MvRow.vue
index a5d4d7a..a06fa6a 100644
--- a/src/components/MvRow.vue
+++ b/src/components/MvRow.vue
@@ -7,7 +7,7 @@
@mouseleave="hoverVideoID = 0"
@click="goToMv(getID(mv))"
>
-
![]()
+
${artistName}`;
+ return `
${artistName}`;
} else if (this.subtitle === 'publishTime') {
return mv.publishTime;
}
diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue
index 372fca0..dce629b 100644
--- a/src/components/Navbar.vue
+++ b/src/components/Navbar.vue
@@ -1,27 +1,8 @@
-
+
@@ -95,17 +82,16 @@ import { isLooseLoggedIn, doLogout } from '@/utils/auth';
// icons by https://github.com/microsoft/vscode-codicons
import 'vscode-codicons/dist/codicon.css';
+import Win32Titlebar from '@/components/Win32Titlebar.vue';
+import LinuxTitlebar from '@/components/LinuxTitlebar.vue';
import ContextMenu from '@/components/ContextMenu.vue';
import ButtonIcon from '@/components/ButtonIcon.vue';
-const electron =
- process.env.IS_ELECTRON === true ? window.require('electron') : null;
-const ipcRenderer =
- process.env.IS_ELECTRON === true ? electron.ipcRenderer : null;
-
export default {
name: 'Navbar',
components: {
+ Win32Titlebar,
+ LinuxTitlebar,
ButtonIcon,
ContextMenu,
},
@@ -114,7 +100,8 @@ export default {
inputFocus: false,
langs: ['zh-CN', 'zh-TW', 'en', 'tr'],
keywords: '',
- isWindowMaximized: false,
+ enableWin32Titlebar: false,
+ enableLinuxTitlebar: false,
};
},
computed: {
@@ -127,12 +114,18 @@ export default {
? `${this.data?.user?.avatarUrl}?param=512y512`
: 'http://s4.music.126.net/style/web2/img/default/default_avatar.jpg?param=60y60';
},
+ hasCustomTitlebar() {
+ return this.enableWin32Titlebar || this.enableLinuxTitlebar;
+ },
},
created() {
- if (process.env.IS_ELECTRON === true) {
- ipcRenderer.on('isMaximized', (event, value) => {
- this.isWindowMaximized = value;
- });
+ if (process.platform === 'win32') {
+ this.enableWin32Titlebar = true;
+ } else if (
+ process.platform === 'linux' &&
+ this.settings.linuxEnableCustomTitlebar
+ ) {
+ this.enableLinuxTitlebar = true;
}
},
methods: {
@@ -174,15 +167,6 @@ export default {
this.$router.push({ name: 'login' });
}
},
- windowMinimize() {
- ipcRenderer.send('minimize');
- },
- windowMaxRestore() {
- ipcRenderer.send('maximizeOrUnmaximize');
- },
- windowClose() {
- ipcRenderer.send('close');
- },
},
};
@@ -210,7 +194,7 @@ nav {
@media (max-width: 1336px) {
nav {
- padding: 0 5vw;
+ padding: 0 max(5vw, 90px);
}
}
@@ -220,68 +204,9 @@ nav {
}
}
-.win32-titlebar {
- display: none;
-}
-
-[data-electron-os='win32'] {
- nav {
- padding-top: 20px;
- -webkit-app-region: no-drag;
- }
- .win32-titlebar {
- color: var(--color-text);
- position: fixed;
- left: 0;
- top: 0;
- right: 0;
- -webkit-app-region: drag;
- display: flex;
- align-items: center;
- --hover: #e6e6e6;
- --active: #cccccc;
-
- .title {
- padding: 8px;
- font-size: 12px;
- font-family: 'Segoe UI', 'Microsoft YaHei UI', 'Microsoft YaHei',
- sans-serif;
- }
- .controls {
- height: 32px;
- margin-left: auto;
- justify-content: flex-end;
- display: flex;
- .button {
- height: 100%;
- width: 46px;
- font-size: 16px;
- display: flex;
- justify-content: center;
- align-items: center;
- -webkit-app-region: no-drag;
- &:hover {
- background: var(--hover);
- }
- &:active {
- background: var(--active);
- }
- &.close {
- &:hover {
- background: rgba(232, 17, 35, 0.9);
- }
- &:active {
- background: #f1707a;
- color: #000;
- }
- }
- }
- }
- }
- &[data-theme='dark'] .win32-titlebar {
- --hover: #191919;
- --active: #333333;
- }
+nav.has-custom-titlebar {
+ padding-top: 20px;
+ -webkit-app-region: no-drag;
}
.navigation-buttons {
diff --git a/src/components/Player.vue b/src/components/Player.vue
index 9789a67..0b98ab6 100644
--- a/src/components/Player.vue
+++ b/src/components/Player.vue
@@ -27,26 +27,34 @@
-
+
{{ currentTrack.name }}
- {{ ar.name }} {{ ar.name }} ,
-
@@ -114,7 +120,7 @@
? $t('player.repeatTrack')
: $t('player.repeat')
"
- @click.native="player.switchRepeatMode"
+ @click.native="switchRepeatMode"
>
+
-
+
@@ -319,12 +348,14 @@ export default {
opacity: 0.88;
color: var(--color-text);
margin-bottom: 4px;
- cursor: pointer;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
word-break: break-all;
+ }
+ .has-list {
+ cursor: pointer;
&:hover {
text-decoration: underline;
}
diff --git a/src/components/Toast.vue b/src/components/Toast.vue
index 93af55a..d5b5eb8 100644
--- a/src/components/Toast.vue
+++ b/src/components/Toast.vue
@@ -30,7 +30,7 @@ export default {
border-radius: 8px;
box-sizing: border-box;
padding: 6px 12px;
- z-index: 100;
+ z-index: 1010;
}
[data-theme='dark'] {
diff --git a/src/components/TrackList.vue b/src/components/TrackList.vue
index a37eb18..ebb5046 100644
--- a/src/components/TrackList.vue
+++ b/src/components/TrackList.vue
@@ -2,7 +2,10 @@
-
![]()
+
{{ rightClickedTrackComputed.name }}
{{ rightClickedTrackComputed.ar[0].name }}
@@ -46,6 +49,9 @@
@click="addTrackToPlaylist"
>{{ $t('contextMenu.addToPlaylist') }}
+
{{
+ $t('contextMenu.copyUrl')
+ }}
{
+ this.showToast(locale.t('toast.copied'));
+ })
+ .catch(err => {
+ this.showToast(`${locale.t('toast.copyFailed')}${err}`);
+ });
+ },
removeTrackFromQueue() {
this.$store.state.player.removeTrackFromQueue(
this.rightClickedTrackIndex
diff --git a/src/components/TrackListItem.vue b/src/components/TrackListItem.vue
index fb572d8..a3a6238 100644
--- a/src/components/TrackListItem.vue
+++ b/src/components/TrackListItem.vue
@@ -10,19 +10,18 @@
-
@@ -85,6 +90,7 @@
import ArtistsInLine from '@/components/ArtistsInLine.vue';
import ExplicitSymbol from '@/components/ExplicitSymbol.vue';
import { mapState } from 'vuex';
+import { isNil } from 'lodash';
export default {
name: 'TrackListItem',
@@ -92,6 +98,7 @@ export default {
props: {
trackProp: Object,
+ trackNo: Number,
highlightPlayingTrack: {
type: Boolean,
default: true,
@@ -109,6 +116,9 @@ export default {
? this.trackProp.simpleSong
: this.trackProp;
},
+ playable() {
+ return this.track?.privilege?.pl > 0 || this.track?.playable;
+ },
imgUrl() {
let image =
this.track?.al?.picUrl ??
@@ -117,18 +127,29 @@ export default {
return image + '?param=224y224';
},
artists() {
- if (this.track.ar !== undefined) return this.track.ar;
- if (this.track.artists !== undefined) return this.track.artists;
+ const { ar, artists } = this.track;
+ if (!isNil(ar)) return ar;
+ if (!isNil(artists)) return artists;
return [];
},
album() {
return this.track.album || this.track.al || this.track?.simpleSong?.al;
},
- translate() {
- let t;
- if (this.track?.tns?.length > 0) t = this.track.tns[0];
- else t = this.track.alia[0];
- return t;
+ subTitle() {
+ let tn = undefined;
+ if (
+ this.track?.tns?.length > 0 &&
+ this.track.name !== this.track.tns[0]
+ ) {
+ tn = this.track.tns[0];
+ }
+
+ //优先显示alia
+ if (this.$store.state.settings.subTitleDefault) {
+ return this.track?.alia?.length > 0 ? this.track.alia[0] : tn;
+ } else {
+ return tn === undefined ? this.track.alia[0] : tn;
+ }
},
type() {
return this.$parent.type;
@@ -136,8 +157,12 @@ export default {
isAlbum() {
return this.type === 'album';
},
- isTranslate() {
- return this.track?.tns?.length > 0 || this.track.alia?.length > 0;
+ isSubTitle() {
+ return (
+ (this.track?.tns?.length > 0 &&
+ this.track.name !== this.track.tns[0]) ||
+ this.track.alia?.length > 0
+ );
},
isPlaylist() {
return this.type === 'playlist';
@@ -150,7 +175,7 @@ export default {
},
trackClass() {
let trackClass = [this.type];
- if (!this.track.playable && this.showUnavailableSongInGreyStyle)
+ if (!this.playable && this.showUnavailableSongInGreyStyle)
trackClass.push('disable');
if (this.isPlaying && this.highlightPlayingTrack)
trackClass.push('playing');
@@ -187,6 +212,7 @@ export default {
methods: {
goToAlbum() {
+ if (this.track.al.id === 0) return;
this.$router.push({ path: '/album/' + this.track.al.id });
},
playTrack() {
@@ -251,7 +277,6 @@ button {
}
.explicit-symbol.before-artist {
- margin-right: 2px;
.svg-icon {
margin-bottom: -3px;
}
@@ -294,8 +319,9 @@ button {
font-size: 14px;
opacity: 0.72;
}
- .translate {
- color: #aeaeae;
+ .sub-title {
+ color: #7a7a7a;
+ opacity: 0.7;
margin-left: 4px;
}
}
@@ -331,7 +357,8 @@ button {
-webkit-line-clamp: 2;
overflow: hidden;
}
- .time {
+ .time,
+ .count {
font-size: 16px;
width: 50px;
cursor: default;
@@ -342,6 +369,11 @@ button {
opacity: 0.88;
color: var(--color-text);
}
+ .count {
+ font-weight: bold;
+ font-size: 22px;
+ line-height: 22px;
+ }
}
.track.focus {
@@ -398,12 +430,13 @@ button {
.title,
.album,
.time,
- .title-and-artist .translate {
+ .title-and-artist .sub-title {
color: var(--color-primary);
}
.title .featured,
.artist,
- .explicit-symbol {
+ .explicit-symbol,
+ .count {
color: var(--color-primary);
opacity: 0.88;
}
diff --git a/src/components/Win32Titlebar.vue b/src/components/Win32Titlebar.vue
new file mode 100644
index 0000000..67386b3
--- /dev/null
+++ b/src/components/Win32Titlebar.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
diff --git a/src/electron/ipcMain.js b/src/electron/ipcMain.js
index 2a89a95..aa0e3d7 100644
--- a/src/electron/ipcMain.js
+++ b/src/electron/ipcMain.js
@@ -1,58 +1,219 @@
import { app, dialog, globalShortcut, ipcMain } from 'electron';
-import match from '@revincx/unblockneteasemusic';
+import UNM from '@unblockneteasemusic/rust-napi';
import { registerGlobalShortcut } from '@/electron/globalShortcut';
import cloneDeep from 'lodash/cloneDeep';
import shortcuts from '@/utils/shortcuts';
import { createMenu } from './menu';
+import { isCreateTray, isMac } from '@/utils/platform';
const clc = require('cli-color');
const log = text => {
console.log(`${clc.blueBright('[ipcMain.js]')} ${text}`);
};
+const exitAsk = (e, win) => {
+ e.preventDefault(); //阻止默认行为
+ dialog
+ .showMessageBox({
+ type: 'info',
+ title: 'Information',
+ cancelId: 2,
+ defaultId: 0,
+ message: '确定要关闭吗?',
+ buttons: ['最小化', '直接退出'],
+ })
+ .then(result => {
+ if (result.response == 0) {
+ e.preventDefault(); //阻止默认行为
+ win.minimize(); //调用 最小化实例方法
+ } else if (result.response == 1) {
+ win = null;
+ //app.quit();
+ app.exit(); //exit()直接关闭客户端,不会执行quit();
+ }
+ })
+ .catch(err => {
+ log(err);
+ });
+};
+
+const exitAskWithoutMac = (e, win) => {
+ e.preventDefault(); //阻止默认行为
+ dialog
+ .showMessageBox({
+ type: 'info',
+ title: 'Information',
+ cancelId: 2,
+ defaultId: 0,
+ message: '确定要关闭吗?',
+ buttons: ['最小化到托盘', '直接退出'],
+ checkboxLabel: '记住我的选择',
+ })
+ .then(result => {
+ if (result.checkboxChecked && result.response !== 2) {
+ win.webContents.send(
+ 'rememberCloseAppOption',
+ result.response === 0 ? 'minimizeToTray' : 'exit'
+ );
+ }
+
+ if (result.response === 0) {
+ e.preventDefault(); //阻止默认行为
+ win.hide(); //调用 最小化实例方法
+ } else if (result.response === 1) {
+ win = null;
+ //app.quit();
+ app.exit(); //exit()直接关闭客户端,不会执行quit();
+ }
+ })
+ .catch(err => {
+ log(err);
+ });
+};
+
const client = require('discord-rich-presence')('818936529484906596');
-export function initIpcMain(win, store) {
- ipcMain.on('unblock-music', (event, track) => {
- // 兼容 unblockneteasemusic 所使用的 api 字段
- track.alias = track.alia || [];
- track.duration = track.dt || 0;
- track.album = track.al || [];
- track.artists = track.ar || [];
+/**
+ * Make data a Buffer.
+ *
+ * @param {?} data The data to convert.
+ * @returns {import("buffer").Buffer} The converted data.
+ */
+function toBuffer(data) {
+ if (data instanceof Buffer) {
+ return data;
+ } else {
+ return Buffer.from(data);
+ }
+}
- const matchPromise = match(track.id, ['qq', 'kuwo', 'migu'], track);
- const timeoutPromise = new Promise((_, reject) => {
- setTimeout(() => {
- reject('timeout');
- }, 3000);
- });
- Promise.race([matchPromise, timeoutPromise])
- .then(res => {
- event.returnValue = res;
- })
- .catch(err => {
- log('unblock music error: ', err);
- event.returnValue = null;
- });
+/**
+ * Get the file base64 data from bilivideo.
+ *
+ * @param {string} url The URL to fetch.
+ * @returns {Promise
} The file base64 data.
+ */
+async function getBiliVideoFile(url) {
+ const axios = await import('axios').then(m => m.default);
+ const response = await axios.get(url, {
+ headers: {
+ Referer: 'https://www.bilibili.com/',
+ 'User-Agent': 'okhttp/3.4.1',
+ },
+ responseType: 'arraybuffer',
});
- ipcMain.on('close', e => {
- if (process.platform == 'darwin') {
- win.hide();
- exitAsk(e);
- return;
- }
+ const buffer = toBuffer(response.data);
+ const encodedData = buffer.toString('base64');
- let closeOpt = store.get('settings.closeAppOption');
- if (closeOpt === 'exit') {
- win = null;
- //app.quit();
- app.exit(); //exit()直接关闭客户端,不会执行quit();
- } else if (closeOpt === 'minimize' || closeOpt === 'minimizeToTray') {
- e.preventDefault(); //阻止默认行为
- win.minimize(); //调用 最小化实例方法
+ return encodedData;
+}
+
+/**
+ * Parse the source string (`a, b`) to source list `['a', 'b']`.
+ *
+ * @param {import("@unblockneteasemusic/rust-napi").Executor} executor
+ * @param {string} sourceString The source string.
+ * @returns {string[]} The source list.
+ */
+function parseSourceStringToList(executor, sourceString) {
+ const availableSource = executor.list();
+
+ return sourceString
+ .split(',')
+ .map(s => s.trim().toLowerCase())
+ .filter(s => {
+ const isAvailable = availableSource.includes(s);
+
+ if (!isAvailable) {
+ log(`This source is not one of the supported source: ${s}`);
+ }
+
+ return isAvailable;
+ });
+}
+
+export function initIpcMain(win, store, trayEventEmitter) {
+ // WIP: Do not enable logging as it has some issues in non-blocking I/O environment.
+ // UNM.enableLogging(UNM.LoggingType.ConsoleEnv);
+ const unmExecutor = new UNM.Executor();
+
+ ipcMain.handle(
+ 'unblock-music',
+ /**
+ *
+ * @param {*} _
+ * @param {string | null} sourceListString
+ * @param {Record} ncmTrack
+ * @param {UNM.Context} context
+ */
+ async (_, sourceListString, ncmTrack, context) => {
+ // Formt the track input
+ // FIXME: Figure out the structure of Track
+ const song = {
+ id: ncmTrack.id && ncmTrack.id.toString(),
+ name: ncmTrack.name,
+ duration: ncmTrack.dt,
+ album: ncmTrack.al && {
+ id: ncmTrack.al.id && ncmTrack.al.id.toString(),
+ name: ncmTrack.al.name,
+ },
+ artists: ncmTrack.ar
+ ? ncmTrack.ar.map(({ id, name }) => ({
+ id: id && id.toString(),
+ name,
+ }))
+ : [],
+ };
+
+ const sourceList =
+ typeof sourceListString === 'string'
+ ? parseSourceStringToList(unmExecutor, sourceListString)
+ : ['ytdl', 'bilibili', 'pyncm', 'kugou'];
+ log(`[UNM] using source: ${sourceList.join(', ')}`);
+ log(`[UNM] using configuration: ${JSON.stringify(context)}`);
+
+ try {
+ // TODO: tell users to install yt-dlp.
+ const matchedAudio = await unmExecutor.search(
+ sourceList,
+ song,
+ context
+ );
+ const retrievedSong = await unmExecutor.retrieve(matchedAudio, context);
+
+ // bilibili's audio file needs some special treatment
+ if (retrievedSong.url.includes('bilivideo.com')) {
+ retrievedSong.url = await getBiliVideoFile(retrievedSong.url);
+ }
+
+ log(`respond with retrieve song…`);
+ log(JSON.stringify(matchedAudio));
+ return retrievedSong;
+ } catch (err) {
+ const errorMessage = err instanceof Error ? `${err.message}` : `${err}`;
+ log(`UnblockNeteaseMusic failed: ${errorMessage}`);
+ return null;
+ }
+ }
+ );
+
+ ipcMain.on('close', e => {
+ if (isMac) {
+ win.hide();
+ exitAsk(e, win);
} else {
- exitAsk(e);
+ let closeOpt = store.get('settings.closeAppOption');
+ if (closeOpt === 'exit') {
+ win = null;
+ //app.quit();
+ app.exit(); //exit()直接关闭客户端,不会执行quit();
+ } else if (closeOpt === 'minimizeToTray') {
+ e.preventDefault();
+ win.hide();
+ } else {
+ exitAskWithoutMac(e, win);
+ }
}
});
@@ -61,9 +222,7 @@ export function initIpcMain(win, store) {
});
ipcMain.on('maximizeOrUnmaximize', () => {
- const isMaximized = win.isMaximized();
- isMaximized ? win.unmaximize() : win.maximize();
- win.webContents.send('isMaximized', isMaximized);
+ win.isMaximized() ? win.unmaximize() : win.maximize();
});
ipcMain.on('settings', (event, options) => {
@@ -81,7 +240,7 @@ export function initIpcMain(win, store) {
details: track.name + ' - ' + track.ar.map(ar => ar.name).join(','),
state: track.al.name,
endTimestamp: Date.now() + track.dt,
- largeImageKey: 'logo',
+ largeImageKey: track.al.picUrl,
largeImageText: 'Listening ' + track.name,
smallImageKey: 'play',
smallImageText: 'Playing',
@@ -93,7 +252,7 @@ export function initIpcMain(win, store) {
client.updatePresence({
details: track.name + ' - ' + track.ar.map(ar => ar.name).join(','),
state: track.al.name,
- largeImageKey: 'logo',
+ largeImageKey: track.al.picUrl,
largeImageText: 'YesPlayMusic',
smallImageKey: 'pause',
smallImageText: 'Pause',
@@ -150,29 +309,15 @@ export function initIpcMain(win, store) {
registerGlobalShortcut(win, store);
});
- const exitAsk = e => {
- e.preventDefault(); //阻止默认行为
- dialog
- .showMessageBox({
- type: 'info',
- title: 'Information',
- cancelId: 2,
- defaultId: 0,
- message: '确定要关闭吗?',
- buttons: ['最小化', '直接退出'],
- })
- .then(result => {
- if (result.response == 0) {
- e.preventDefault(); //阻止默认行为
- win.minimize(); //调用 最小化实例方法
- } else if (result.response == 1) {
- win = null;
- //app.quit();
- app.exit(); //exit()直接关闭客户端,不会执行quit();
- }
- })
- .catch(err => {
- log(err);
- });
- };
+ if (isCreateTray) {
+ ipcMain.on('updateTrayTooltip', (_, title) => {
+ trayEventEmitter.emit('updateTooltip', title);
+ });
+ ipcMain.on('updateTrayPlayState', (_, isPlaying) => {
+ trayEventEmitter.emit('updatePlayState', isPlaying);
+ });
+ ipcMain.on('updateTrayLikeState', (_, isLiked) => {
+ trayEventEmitter.emit('updateLikeState', isLiked);
+ });
+ }
}
diff --git a/src/electron/ipcRenderer.js b/src/electron/ipcRenderer.js
index da3ccb5..ea8faf9 100644
--- a/src/electron/ipcRenderer.js
+++ b/src/electron/ipcRenderer.js
@@ -36,7 +36,11 @@ export function ipcRenderer(vueInstance) {
});
ipcRenderer.on('next', () => {
- player.playNextTrack();
+ if (player.isPersonalFM) {
+ player.playNextFMTrack();
+ } else {
+ player.playNextTrack();
+ }
});
ipcRenderer.on('previous', () => {
@@ -76,4 +80,15 @@ export function ipcRenderer(vueInstance) {
ipcRenderer.on('nextUp', () => {
self.$refs.player.goToNextTracksPage();
});
+
+ ipcRenderer.on('rememberCloseAppOption', (event, value) => {
+ store.commit('updateSettings', {
+ key: 'closeAppOption',
+ value,
+ });
+ });
+
+ ipcRenderer.on('setPosition', (event, position) => {
+ player._howler.seek(position);
+ });
}
diff --git a/src/electron/mpris.js b/src/electron/mpris.js
new file mode 100644
index 0000000..c6cfeee
--- /dev/null
+++ b/src/electron/mpris.js
@@ -0,0 +1,94 @@
+import dbus from 'dbus-next';
+import { ipcMain, app } from 'electron';
+
+export function createMpris(window) {
+ const Player = require('mpris-service');
+ const renderer = window.webContents;
+
+ const player = Player({
+ name: 'yesplaymusic',
+ identity: 'YesPlayMusic',
+ });
+
+ player.on('next', () => renderer.send('next'));
+ player.on('previous', () => renderer.send('previous'));
+ player.on('playpause', () => renderer.send('play'));
+ player.on('play', () => renderer.send('play'));
+ player.on('pause', () => renderer.send('play'));
+ player.on('quit', () => app.exit());
+ player.on('position', args =>
+ renderer.send('setPosition', args.position / 1000 / 1000)
+ );
+ player.on('loopStatus', () => renderer.send('repeat'));
+ player.on('shuffle', () => renderer.send('shuffle'));
+
+ ipcMain.on('player', (e, { playing }) => {
+ player.playbackStatus = playing
+ ? Player.PLAYBACK_STATUS_PLAYING
+ : Player.PLAYBACK_STATUS_PAUSED;
+ });
+
+ ipcMain.on('metadata', (e, metadata) => {
+ // 更新 Mpris 状态前将位置设为0, 否则 OSDLyrics 获取到的进度是上首音乐切换时的进度
+ player.getPosition = () => 0;
+ player.metadata = {
+ 'mpris:trackid': player.objectPath('track/' + metadata.trackId),
+ 'mpris:artUrl': metadata.artwork[0].src,
+ 'mpris:length': metadata.length * 1000 * 1000,
+ 'xesam:title': metadata.title,
+ 'xesam:album': metadata.album,
+ 'xesam:artist': metadata.artist.split(','),
+ 'xesam:url': metadata.url,
+ };
+ });
+
+ ipcMain.on('playerCurrentTrackTime', (e, position) => {
+ player.getPosition = () => position * 1000 * 1000;
+ player.seeked(position * 1000 * 1000);
+ });
+
+ ipcMain.on('seeked', (e, position) => {
+ player.seeked(position * 1000 * 1000);
+ });
+
+ ipcMain.on('switchRepeatMode', (e, mode) => {
+ switch (mode) {
+ case 'off':
+ player.loopStatus = Player.LOOP_STATUS_NONE;
+ break;
+ case 'one':
+ player.loopStatus = Player.LOOP_STATUS_TRACK;
+ break;
+ case 'on':
+ player.loopStatus = Player.LOOP_STATUS_PLAYLIST;
+ break;
+ }
+ });
+
+ ipcMain.on('switchShuffle', (e, shuffle) => {
+ player.shuffle = shuffle;
+ });
+}
+
+export async function createDbus(window) {
+ const bus = dbus.sessionBus();
+ const Variant = dbus.Variant;
+
+ const osdService = await bus.getProxyObject(
+ 'org.osdlyrics.Daemon',
+ '/org/osdlyrics/Lyrics'
+ );
+
+ const osdInterface = osdService.getInterface('org.osdlyrics.Lyrics');
+
+ ipcMain.on('sendLyrics', async (e, { track, lyrics }) => {
+ const metadata = {
+ title: new Variant('s', track.name),
+ artist: new Variant('s', track.ar.map(ar => ar.name).join(', ')),
+ };
+
+ await osdInterface.SetLyricContent(metadata, Buffer.from(lyrics));
+
+ window.webContents.send('saveLyricFinished');
+ });
+}
diff --git a/src/electron/services.js b/src/electron/services.js
index fe611b3..3a1106f 100644
--- a/src/electron/services.js
+++ b/src/electron/services.js
@@ -1,63 +1,14 @@
-const express = require('express');
-const bodyParser = require('body-parser');
-const cache = require('../../netease_api/util/apicache').middleware;
-const fileUpload = require('express-fileupload');
-import routes from '../../netease_api/routes';
-const clc = require('cli-color');
+import clc from 'cli-color';
+import checkAuthToken from '../utils/checkAuthToken';
+import server from 'NeteaseCloudMusicApi/server';
-export function startNeteaseMusicApi() {
- // Integrate API
- const app = express();
+export async function startNeteaseMusicApi() {
+ // Let user know that the service is starting
+ console.log(`${clc.redBright('[NetEase API]')} initiating NCM API`);
- // 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());
-
- // 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 || 10754;
- const host = process.env.HOST || '127.0.0.1';
-
- app.server = app.listen(port, host, () => {
- console.log(
- `${clc.redBright('[NetEase API]')} server running @ http://${
- host ? host : 'localhost'
- }:${port}`
- );
+ // Load the NCM API.
+ await server.serveNcmApi({
+ port: 10754,
+ moduleDefs: require('../ncmModDef'),
});
}
diff --git a/src/electron/tray.js b/src/electron/tray.js
index 0981460..ed314f2 100644
--- a/src/electron/tray.js
+++ b/src/electron/tray.js
@@ -1,87 +1,216 @@
/* global __static */
import path from 'path';
-import { app, nativeImage, Tray, Menu } from 'electron';
+import { app, nativeImage, Tray, Menu, nativeTheme } from 'electron';
+import { isLinux } from '@/utils/platform';
+
+function createMenuTemplate(win) {
+ return [
+ {
+ label: '播放',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/play.png')
+ ),
+ click: () => {
+ win.webContents.send('play');
+ },
+ id: 'play',
+ },
+ {
+ label: '暂停',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/pause.png')
+ ),
+ click: () => {
+ win.webContents.send('play');
+ },
+ id: 'pause',
+ visible: false,
+ },
+ {
+ label: '上一首',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/left.png')
+ ),
+ accelerator: 'CmdOrCtrl+Left',
+ click: () => {
+ win.webContents.send('previous');
+ },
+ },
+ {
+ label: '下一首',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/right.png')
+ ),
+ accelerator: 'CmdOrCtrl+Right',
+ click: () => {
+ win.webContents.send('next');
+ },
+ },
+ {
+ label: '循环播放',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/repeat.png')
+ ),
+ accelerator: 'Alt+R',
+ click: () => {
+ win.webContents.send('repeat');
+ },
+ },
+ {
+ label: '加入喜欢',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/like.png')
+ ),
+ accelerator: 'CmdOrCtrl+L',
+ click: () => {
+ win.webContents.send('like');
+ },
+ id: 'like',
+ },
+ {
+ label: '取消喜欢',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/unlike.png')
+ ),
+ accelerator: 'CmdOrCtrl+L',
+ click: () => {
+ win.webContents.send('like');
+ },
+ id: 'unlike',
+ visible: false,
+ },
+ {
+ label: '退出',
+ icon: nativeImage.createFromPath(
+ path.join(__static, 'img/icons/exit.png')
+ ),
+ accelerator: 'CmdOrCtrl+W',
+ click: () => {
+ app.exit();
+ },
+ },
+ ];
+}
+
+// linux下托盘的实现方式比较迷惑
+// right-click无法在linux下使用
+// click在默认行为下会弹出一个contextMenu,里面的唯一选项才会调用click事件
+// setContextMenu应该是目前唯一能在linux下使用托盘菜单api
+// 但是无法区分鼠标左右键
+
+// 发现openSUSE KDE环境可以区分鼠标左右键
+// 添加左键支持
+// 2022.05.17
+class YPMTrayLinuxImpl {
+ constructor(tray, win, emitter) {
+ this.tray = tray;
+ this.win = win;
+ this.emitter = emitter;
+ this.template = undefined;
+ this.initTemplate();
+ this.contextMenu = Menu.buildFromTemplate(this.template);
+
+ this.tray.setContextMenu(this.contextMenu);
+ this.handleEvents();
+ }
+
+ initTemplate() {
+ //在linux下,鼠标左右键都会呼出contextMenu
+ //所以此处单独为linux添加一个 显示主面板 选项
+ this.template = [
+ {
+ label: '显示主面板',
+ click: () => {
+ this.win.show();
+ },
+ },
+ {
+ type: 'separator',
+ },
+ ].concat(createMenuTemplate(this.win));
+ }
+
+ handleEvents() {
+ this.tray.on('click', () => {
+ this.win.show();
+ });
+
+ this.emitter.on('updateTooltip', title => this.tray.setToolTip(title));
+ this.emitter.on('updatePlayState', isPlaying => {
+ this.contextMenu.getMenuItemById('play').visible = !isPlaying;
+ this.contextMenu.getMenuItemById('pause').visible = isPlaying;
+ this.tray.setContextMenu(this.contextMenu);
+ });
+ this.emitter.on('updateLikeState', isLiked => {
+ this.contextMenu.getMenuItemById('like').visible = !isLiked;
+ this.contextMenu.getMenuItemById('unlike').visible = isLiked;
+ this.tray.setContextMenu(this.contextMenu);
+ });
+ }
+}
+
+class YPMTrayWindowsImpl {
+ constructor(tray, win, emitter) {
+ this.tray = tray;
+ this.win = win;
+ this.emitter = emitter;
+ this.template = createMenuTemplate(win);
+ this.contextMenu = Menu.buildFromTemplate(this.template);
+
+ this.isPlaying = false;
+ this.curDisplayPlaying = false;
+
+ this.isLiked = false;
+ this.curDisplayLiked = false;
+
+ this.handleEvents();
+ }
+
+ handleEvents() {
+ this.tray.on('click', () => {
+ this.win.show();
+ });
+
+ this.tray.on('right-click', () => {
+ if (this.isPlaying !== this.curDisplayPlaying) {
+ this.curDisplayPlaying = this.isPlaying;
+ this.contextMenu.getMenuItemById('play').visible = !this.isPlaying;
+ this.contextMenu.getMenuItemById('pause').visible = this.isPlaying;
+ }
+
+ if (this.isLiked !== this.curDisplayLiked) {
+ this.curDisplayLiked = this.isLiked;
+ this.contextMenu.getMenuItemById('like').visible = !this.isLiked;
+ this.contextMenu.getMenuItemById('unlike').visible = this.isLiked;
+ }
+
+ this.tray.popUpContextMenu(this.contextMenu);
+ });
+
+ this.emitter.on('updateTooltip', title => this.tray.setToolTip(title));
+ this.emitter.on(
+ 'updatePlayState',
+ isPlaying => (this.isPlaying = isPlaying)
+ );
+ this.emitter.on('updateLikeState', isLiked => (this.isLiked = isLiked));
+ }
+}
+
+export function createTray(win, eventEmitter) {
+ // 感觉图标颜色应该不属于界面主题范畴,只需要跟随系统主题
+ let iconTheme = nativeTheme.shouldUseDarkColors ? 'light' : 'dark';
-export function createTray(win) {
let icon = nativeImage
- .createFromPath(path.join(__static, 'img/icons/menu@88.png'))
+ .createFromPath(path.join(__static, `img/icons/menu-${iconTheme}@88.png`))
.resize({
height: 20,
width: 20,
});
- let tray = new Tray(icon);
+ let tray = new Tray(icon);
tray.setToolTip('YesPlayMusic');
- tray.on('click', () => {
- win.show();
- });
-
- tray.on('right-click', () => {
- const contextMenu = Menu.buildFromTemplate([
- {
- label: '播放/暂停',
- icon: nativeImage.createFromPath(
- path.join(__static, 'img/icons/play.png')
- ),
- click: () => {
- win.webContents.send('play');
- },
- },
- {
- label: '上一首',
- icon: nativeImage.createFromPath(
- path.join(__static, 'img/icons/left.png')
- ),
- accelerator: 'CmdOrCtrl+Left',
- click: () => {
- win.webContents.send('previous');
- },
- },
- {
- label: '下一首',
- icon: nativeImage.createFromPath(
- path.join(__static, 'img/icons/right.png')
- ),
- accelerator: 'CmdOrCtrl+Right',
- click: () => {
- win.webContents.send('next');
- },
- },
- {
- label: '循环播放',
- icon: nativeImage.createFromPath(
- path.join(__static, 'img/icons/repeat.png')
- ),
- accelerator: 'Alt+R',
- click: () => {
- win.webContents.send('repeat');
- },
- },
- {
- label: '加入喜欢',
- icon: nativeImage.createFromPath(
- path.join(__static, 'img/icons/like.png')
- ),
- accelerator: 'CmdOrCtrl+L',
- click: () => {
- win.webContents.send('like');
- },
- },
- {
- label: '退出',
- icon: nativeImage.createFromPath(
- path.join(__static, 'img/icons/exit.png')
- ),
- accelerator: 'CmdOrCtrl+W',
- click: () => {
- app.exit();
- },
- },
- ]);
-
- tray.popUpContextMenu(contextMenu);
- });
-
- return tray;
+ return isLinux
+ ? new YPMTrayLinuxImpl(tray, win, eventEmitter)
+ : new YPMTrayWindowsImpl(tray, win, eventEmitter);
}
diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js
index f7e55d2..d880e32 100644
--- a/src/locale/lang/en.js
+++ b/src/locale/lang/en.js
@@ -28,7 +28,14 @@ export default {
albums: 'Albums',
artists: 'Artists',
mvs: 'MVs',
+ cloudDisk: 'Cloud Disk',
newPlayList: 'New Playlist',
+ uploadSongs: 'Upload Songs',
+ playHistory: {
+ title: 'Play History',
+ week: 'Latest Week',
+ all: 'All Time',
+ },
userProfileMenu: {
settings: 'Settings',
logout: 'Logout',
@@ -95,15 +102,19 @@ export default {
},
player: {
like: 'Like',
+ unlike: 'Unlike',
previous: 'Previous Song',
next: 'Next Song',
repeat: 'Repeat',
repeatTrack: 'Repeat Track',
shuffle: 'Shuffle',
+ reversed: 'Reversed',
play: 'Play',
pause: 'Pause',
mute: 'Mute',
nextUp: 'Next Up',
+ translationLyric: 'lyric (trans)',
+ PronunciationLyric: 'lyric (pronounce)',
},
modal: {
close: 'Close',
@@ -121,6 +132,17 @@ export default {
settings: 'Settings',
logout: 'LOGOUT',
language: 'Languages',
+ lyric: 'Lyric',
+ others: 'Others',
+ customization: 'Customization',
+ MusicGenrePreference: {
+ text: 'Music Language Preference',
+ none: 'No preferences',
+ mandarin: 'Mandarin',
+ western: 'Europe & America',
+ korean: 'Korean',
+ japanese: 'Japanese',
+ },
musicQuality: {
text: 'Music Quality',
low: 'Low',
@@ -154,7 +176,11 @@ export default {
showPlaylistsByAppleMusic: 'Show playlists by Apple Music',
enableDiscordRichPresence: 'Enable Discord Rich Presence',
enableGlobalShortcut: 'Enable Global Shortcut',
- showLibraryDefault: 'Show library default',
+ showLibraryDefault: 'Show Library after App Launched',
+ subTitleDefault: 'Show Alias for Subtitle by default',
+ enableReversedMode: 'Enable Reversed Mode (Experimental)',
+ enableCustomTitlebar: 'Enable custom title bar (Need restart)',
+ showLyricsTime: 'Display current time',
lyricsBackground: {
text: 'Show Lyrics Background',
off: 'Off',
@@ -165,9 +191,43 @@ export default {
text: 'Close App...',
ask: 'Ask',
exit: 'Exit',
- minimize: 'Minimize',
minimizeToTray: 'Minimize to tray',
},
+ enableOsdlyricsSupport: {
+ title: 'desktop lyrics support',
+ desc1:
+ 'Only takes effect under Linux. After enabled, it downloads the lyrics file to the local, and tries to launch OSDLyrics at startup.',
+ desc2:
+ 'Please ensure that you have installed OSDLyrics before turning on this.',
+ },
+ unm: {
+ enable: 'Enable',
+ audioSource: {
+ title: 'Audio Sources',
+ },
+ enableFlac: {
+ title: 'Enable FLAC Sources',
+ desc: 'To take effect, it may be required to clear the cache after enabling this function.',
+ },
+ searchMode: {
+ title: 'Audio Search Mode',
+ fast: 'Speed Priority',
+ order: 'Order Priority',
+ },
+ cookie: {
+ joox: 'Cookie for Joox use',
+ qq: 'Cookie for QQ use',
+ desc1: 'Click here for the configuration instruction. ',
+ desc2: 'Leave empty to pick up the default value',
+ },
+ ytdl: 'The youtube-dl Executable File for YtDl',
+ proxy: {
+ title: 'Proxy Server for UNM',
+ desc1:
+ 'The proxy server to use for requesting services such as YouTube',
+ desc2: 'Leave empty to pick up the default value',
+ },
+ },
},
contextMenu: {
play: 'Play',
@@ -179,9 +239,13 @@ export default {
addToPlaylist: 'Add to playlist',
searchInPlaylist: 'Search in playlist',
copyUrl: 'Copy URL',
+ openInBrowser: 'Open in Browser',
allPlaylists: 'All Playlists',
minePlaylists: 'My Playlists',
likedPlaylists: 'Liked Playlists',
+ cardiacMode: 'Cardiac Mode',
+ copyLyric: 'Copy Lyric',
+ copyLyricWithTranslation: 'Copy Lyric With Translation',
},
toast: {
savedToPlaylist: 'Saved to playlist',
diff --git a/src/locale/lang/tr.js b/src/locale/lang/tr.js
index a774b11..fda2939 100644
--- a/src/locale/lang/tr.js
+++ b/src/locale/lang/tr.js
@@ -28,7 +28,14 @@ export default {
albums: 'Albümler',
artists: 'Sanatçılar',
mvs: 'MVs',
+ cloudDisk: 'Cloud Disk',
newPlayList: 'Yeni Çalma Listesi',
+ uploadSongs: 'Upload Songs',
+ playHistory: {
+ title: 'Play History',
+ week: 'Latest Week',
+ all: 'All Time',
+ },
userProfileMenu: {
settings: 'Ayarlar',
logout: 'Çıkış Yap',
@@ -91,6 +98,7 @@ export default {
},
player: {
like: 'Beğen',
+ unlike: 'Aksine',
previous: 'Önceki Müzik',
next: 'Sonraki Müzik',
repeat: 'Tekrarla',
@@ -100,6 +108,8 @@ export default {
pause: 'Durdur',
mute: 'Sesi kapat',
nextUp: 'Sıradaki',
+ translationLyric: 'şarkı sözleri (çeviri)',
+ PronunciationLyric: 'şarkı sözleri (çeviri)',
},
modal: {
close: 'Kapat',
@@ -117,6 +127,17 @@ export default {
settings: 'Ayarlar',
logout: 'ÇIKIŞ YAP',
language: 'Diller',
+ lyric: 'Şarkı Sözleri',
+ others: 'Diğerleri',
+ customization: 'Özelleştirme',
+ MusicGenrePreference: {
+ text: 'Müzik Dili Tercihi',
+ none: 'Tercih yok',
+ mandarin: 'Çince dili',
+ western: 'Avrupa ve Amerika',
+ korean: 'Korece',
+ japanese: 'Japonca',
+ },
musicQuality: {
text: 'Müzik Kalitesi',
low: 'Düşük',
@@ -150,6 +171,9 @@ export default {
showPlaylistsByAppleMusic: "Apple Music'in Çalma Listelerini Göster",
enableDiscordRichPresence: 'Discord gösterimini aktifleştir',
showLibraryDefault: 'Kitaplık Varsayılanını göster',
+ subTitleDefault: 'Show Alias for Subtitle by default',
+ enableReversedMode: 'Enable Reversed Mode (Experimental)',
+ enableCustomTitlebar: 'Enable custom title bar (Need restart)',
lyricsBackground: {
text: 'Şarkı Sözleri Arka Planını Göster',
off: 'kapalı',
@@ -160,15 +184,54 @@ export default {
text: 'Close App...',
ask: 'Ask',
exit: 'Exit',
- minimize: 'Minimize',
minimizeToTray: 'Küçült',
},
+ unm: {
+ enable: 'Enable',
+ audioSource: {
+ title: 'Audio Sources',
+ },
+ enableFlac: {
+ title: 'Enable FLAC Sources',
+ desc: 'To take effect, it may be required to clear the cache after enabling this function.',
+ },
+ searchMode: {
+ title: 'Audio Search Mode',
+ fast: 'Speed Priority',
+ order: 'Order Priority',
+ },
+ cookie: {
+ joox: 'Cookie for Joox use',
+ qq: 'Cookie for QQ use',
+ desc1: 'Click here for the configuration instruction. ',
+ desc2: 'Leave empty to pick up the default value',
+ },
+ ytdl: 'The youtube-dl Executable File for YtDl',
+ proxy: {
+ title: 'Proxy Server for UNM',
+ desc1:
+ 'The proxy server to use for requesting services such as YouTube',
+ desc2: 'Leave empty to pick up the default value',
+ },
+ },
},
contextMenu: {
play: 'Oynat',
addToQueue: 'Sonrakini Oynat',
saveToMyLikedSongs: 'Beğendiğim Müziklere Kaydet',
removeFromMyLikedMüzikler: 'Beğendiğim Müziklerden Kaldır',
+ saveToLibrary: 'Save to library',
+ removeFromLibrary: 'Remove from library',
+ addToPlaylist: 'Add to playlist',
+ searchInPlaylist: 'Search in playlist',
+ copyUrl: 'Copy URL',
+ openInBrowser: 'Open in Browser',
+ allPlaylists: 'All Playlists',
+ minePlaylists: 'My Playlists',
+ likedPlaylists: 'Liked Playlists',
+ cardiacMode: 'Cardiac Mode',
+ copyLyric: 'Copy Lyric',
+ copyLyricWithTranslation: 'Copy Lyric With Translation',
},
toast: {
savedToMyLikedSongs: 'Beğendiğim Müziklere Kaydet',
diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js
index 2dfaaac..543132a 100644
--- a/src/locale/lang/zh-CN.js
+++ b/src/locale/lang/zh-CN.js
@@ -25,7 +25,14 @@ export default {
albums: '专辑',
artists: '艺人',
mvs: 'MV',
+ cloudDisk: '云盘',
newPlayList: '新建歌单',
+ uploadSongs: '上传歌曲',
+ playHistory: {
+ title: '听歌排行',
+ week: '最近一周',
+ all: '所有时间',
+ },
userProfileMenu: {
settings: '设置',
logout: '登出',
@@ -96,15 +103,19 @@ export default {
},
player: {
like: '喜欢',
+ unlike: '取消喜欢',
previous: '上一首',
next: '下一首',
repeat: '循环播放',
repeatTrack: '单曲循环',
shuffle: '随机播放',
+ reversed: '倒序播放',
play: '播放',
pause: '暂停',
mute: '静音',
nextUp: '播放列表',
+ translationLyric: '歌词(译)',
+ PronunciationLyric: '歌词(音)',
},
modal: {
close: '关闭',
@@ -122,6 +133,17 @@ export default {
settings: '设置',
logout: '登出',
language: '语言',
+ lyric: '歌词',
+ others: '其他',
+ customization: '自定义',
+ MusicGenrePreference: {
+ text: '音乐语种偏好',
+ none: '无偏好',
+ mandarin: '华语',
+ western: '欧美',
+ korean: '韩语',
+ japanese: '日语',
+ },
musicQuality: {
text: '音质选择',
low: '普通',
@@ -156,19 +178,55 @@ export default {
enableDiscordRichPresence: '启用 Discord Rich Presence',
enableGlobalShortcut: '启用全局快捷键',
showLibraryDefault: '启动后显示音乐库',
+ subTitleDefault: '副标题使用别名',
+ enableReversedMode: '启用倒序播放功能 (实验性功能)',
+ enableCustomTitlebar: '启用自定义标题栏 (重启后生效)',
lyricsBackground: {
text: '显示歌词背景',
off: '关闭',
on: '打开',
dynamic: '动态(GPU 占用较高)',
},
+ showLyricsTime: '显示当前时间',
closeAppOption: {
text: '关闭主面板时...',
ask: '询问',
exit: '退出',
- minimize: '最小化',
minimizeToTray: '最小化到托盘',
},
+ enableOsdlyricsSupport: {
+ title: '桌面歌词支持',
+ desc1:
+ '仅 Linux 下生效。启用后会将歌词文件下载到本地,并在开启播放器时尝试拉起 OSDLyrics。',
+ desc2: '请在开启之前确保您已经正确安装了 OSDLyrics。',
+ },
+ unm: {
+ enable: '启用',
+ audioSource: {
+ title: '备选音源',
+ },
+ enableFlac: {
+ title: '启用 FLAC',
+ desc: '启用后需要清除歌曲缓存才能生效',
+ },
+ searchMode: {
+ title: '音源搜索模式',
+ fast: '速度优先',
+ order: '顺序优先',
+ },
+ cookie: {
+ joox: 'Joox 引擎的 Cookie',
+ qq: 'QQ 引擎的 Cookie',
+ desc1: '设置说明请参见此处',
+ desc2: ',留空则不进行相关设置',
+ },
+ ytdl: 'YtDl 引擎要使用的 youtube-dl 可执行文件',
+ proxy: {
+ title: '用于 UNM 的代理服务器',
+ desc1: '请求如 YouTube 音源服务时要使用的代理服务器',
+ desc2: '留空则不进行相关设置',
+ },
+ },
},
contextMenu: {
play: '播放',
@@ -180,9 +238,13 @@ export default {
addToPlaylist: '添加到歌单',
searchInPlaylist: '歌单内搜索',
copyUrl: '复制链接',
+ openInBrowser: '在浏览器中打开',
allPlaylists: '全部歌单',
minePlaylists: '创建的歌单',
likedPlaylists: '收藏的歌单',
+ cardiacMode: '心动模式',
+ copyLyric: '复制歌词',
+ copyLyricWithTranslation: '复制歌词(含翻译)',
},
toast: {
savedToPlaylist: '已添加到歌单',
diff --git a/src/locale/lang/zh-TW.js b/src/locale/lang/zh-TW.js
index f506bf7..384a0cf 100644
--- a/src/locale/lang/zh-TW.js
+++ b/src/locale/lang/zh-TW.js
@@ -25,7 +25,14 @@ export default {
albums: '專輯',
artists: '藝人',
mvs: 'MV',
+ cloudDisk: '雲端硬碟',
newPlayList: '新增歌單',
+ uploadSongs: '上傳音樂',
+ playHistory: {
+ title: '聽歌排行',
+ week: '最近一周',
+ all: '所有時間',
+ },
userProfileMenu: {
settings: '設定',
logout: '登出',
@@ -57,14 +64,14 @@ export default {
search: '搜尋歌單內音樂',
},
login: {
- accessToAll: '可存取全部數據',
- loginText: '登入網易雲帳號',
- search: '搜尋網易雲帳號',
- readonly: '只能讀取帳號公開數據',
+ accessToAll: '可存取全部資料',
+ loginText: '登入網易雲帳戶',
+ search: '搜尋網易雲帳戶',
+ readonly: '只能讀取帳戶公開資料',
usernameLogin: '使用者名稱登入',
searchHolder: '請輸入您的網易雲使用者名稱',
enterTip: '按 Enter 搜尋',
- choose: '在選單中選擇你的帳號',
+ choose: '在選單中選擇你的帳戶',
confirm: '確認',
countryCode: '國際區碼',
phone: '手機號碼',
@@ -73,15 +80,15 @@ export default {
login: '登入',
loginWithEmail: '信箱登入',
loginWithPhone: '手機號碼登入',
- notice: `YesPlayMusic 承諾不會保存您的任何帳號資訊到雲端。
+ notice: `YesPlayMusic 承諾不會保存您的任何帳戶資訊到雲端。
您的密碼會在本地進行 MD5 加密後再傳輸到網易雲 API。
- YesPlayMusic 並非網易雲官方網站,輸入帳號資訊前請慎重考慮。 您也可以前往
+ YesPlayMusic 並非網易雲官方網站,輸入帳戶資訊前請慎重考慮。 您也可以前往
YesPlayMusic 的 GitHub 原始碼 Repo
自行編譯並使用自託管的網易雲 API。`,
noticeElectron: `您的密碼會在本地進行 MD5 加密後再傳輸到網易雲 API。
- YesPlayMusic 不會傳輸你的帳號數據到任何非網易雲音樂官方的伺服器。
`,
+ YesPlayMusic 不會傳輸你的帳戶資料到任何非網易雲音樂官方的伺服器。
`,
},
mv: {
moreVideo: '更多影片',
@@ -92,15 +99,19 @@ export default {
},
player: {
like: '喜歡',
+ unlike: '取消喜歡',
previous: '上一首',
next: '下一首',
repeat: '循環播放',
repeatTrack: '單曲循環',
shuffle: '隨機播放',
+ reversed: '倒序播放',
play: '播放',
pause: '暫停',
mute: '靜音',
nextUp: '播放清單',
+ translationLyric: '歌詞(譯)',
+ PronunciationLyric: '歌詞(音)',
},
modal: {
close: '關閉',
@@ -118,6 +129,17 @@ export default {
settings: '設定',
logout: '登出',
language: '語言',
+ lyric: '歌詞',
+ others: '其他',
+ customization: '自訂',
+ MusicGenrePreference: {
+ text: '音樂語種偏好',
+ none: '無偏好',
+ mandarin: '華語',
+ western: '歐美',
+ korean: '韓語',
+ japanese: '日語',
+ },
musicQuality: {
text: '音質選擇',
low: '普通',
@@ -148,11 +170,15 @@ export default {
clearSongsCache: '清除歌曲快取',
cacheCount: '已快取 {song} 首 ({size})',
showLyricsTranslation: '顯示歌詞翻譯',
- minimizeToTray: '最小化到系統列',
+ minimizeToTray: '最小化到工作列角落',
showPlaylistsByAppleMusic: '首頁顯示來自 Apple Music 的歌單',
enableDiscordRichPresence: '啟用 Discord Rich Presence',
enableGlobalShortcut: '啟用全域快捷鍵',
showLibraryDefault: '啟動後顯示音樂庫',
+ subTitleDefault: '副標題使用別名',
+ enableReversedMode: '啟用倒序播放功能 (實驗性功能)',
+ enableCustomTitlebar: '啟用自訂標題列(重新啟動後生效)',
+ showLyricsTime: '顯示目前時間',
lyricsBackground: {
text: '顯示歌詞背景',
off: '關閉',
@@ -163,8 +189,40 @@ export default {
text: '關閉主面板時...',
ask: '詢問',
exit: '退出',
- minimize: '最小化',
- minimizeToTray: '最小化到系統列',
+ minimizeToTray: '最小化到工作列角落',
+ },
+ enableOsdlyricsSupport: {
+ title: '桌面歌詞支援',
+ desc1:
+ '只在 Linux 環境下生效。啟用後會將歌詞檔案下載至本機位置,並在開啟播放器時嘗試連帶啟動 OSDLyrics。',
+ desc2: '請在開啟之前確保您已經正確安裝了 OSDLyrics。',
+ },
+ unm: {
+ enable: '啟用',
+ audioSource: {
+ title: '備選音源',
+ },
+ enableFlac: {
+ title: '啟用 FLAC',
+ desc: '啟用後需要清除歌曲快取才能生效',
+ },
+ searchMode: {
+ title: '音源搜尋模式',
+ fast: '速度優先',
+ order: '順序優先',
+ },
+ cookie: {
+ joox: 'Joox 引擎的 Cookie',
+ qq: 'QQ 引擎的 Cookie',
+ desc1: '設定說明請參見此處',
+ desc2: ',留空則不進行相關設定',
+ },
+ ytdl: 'YtDl 引擎要使用的 youtube-dl 執行檔',
+ proxy: {
+ title: '用於 UNM 的 Proxy 伺服器',
+ desc1: '請求如 YouTube 音源服務時要使用的 Proxy 伺服器',
+ desc2: '留空則不進行相關設定',
+ },
},
},
contextMenu: {
@@ -176,10 +234,14 @@ export default {
removeFromLibrary: '從音樂庫刪除',
addToPlaylist: '新增至歌單',
searchInPlaylist: '歌單內搜尋',
- copyUrl: '複製超連結',
+ openInBrowser: '在瀏覽器中打開',
+ copyUrl: '複製連結',
allPlaylists: '全部歌單',
minePlaylists: '我建立的歌單',
likedPlaylists: '收藏的歌單',
+ cardiacMode: '心動模式',
+ copyLyric: '複製歌詞',
+ copyLyricWithTranslation: '複製歌詞(含翻譯)',
},
toast: {
savedToPlaylist: '已新增至歌單',
@@ -188,6 +250,6 @@ export default {
removedFromMyLikedSongs: '已從喜歡的音樂中刪除',
copied: '已複製',
copyFailed: '複製失敗:',
- needToLogin: '此動作需要登入網易雲帳號',
+ needToLogin: '此動作需要登入網易雲帳戶',
},
};
diff --git a/src/main.js b/src/main.js
index 3903764..50d73a2 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import VueAnalytics from 'vue-analytics';
+import VueGtag from 'vue-gtag';
import App from './App.vue';
import router from './router';
import store from './store';
@@ -7,7 +7,6 @@ import i18n from '@/locale';
import '@/assets/icons';
import '@/utils/filters';
import './registerServiceWorker';
-import { dailyTask } from '@/utils/common';
import '@/assets/css/global.scss';
import NProgress from 'nprogress';
import '@/assets/css/nprogress.css';
@@ -28,14 +27,16 @@ console.log(
'background:unset;color:unset;'
);
-Vue.use(VueAnalytics, {
- id: 'UA-180189423-1',
- router,
-});
+Vue.use(
+ VueGtag,
+ {
+ config: { id: 'G-KMJJCFZDKF' },
+ },
+ router
+);
Vue.config.productionTip = false;
NProgress.configure({ showSpinner: false, trickleSpeed: 100 });
-dailyTask();
new Vue({
i18n,
diff --git a/src/ncmModDef.js b/src/ncmModDef.js
new file mode 100644
index 0000000..043ce28
--- /dev/null
+++ b/src/ncmModDef.js
@@ -0,0 +1,617 @@
+module.exports = [
+ {
+ identifier: 'user_update',
+ route: '/user/update',
+ module: require('NeteaseCloudMusicApi/module/user_update'),
+ },
+ {
+ identifier: 'user_subcount',
+ route: '/user/subcount',
+ module: require('NeteaseCloudMusicApi/module/user_subcount'),
+ },
+ {
+ identifier: 'user_replacephone',
+ route: '/user/replacephone',
+ module: require('NeteaseCloudMusicApi/module/user_replacephone'),
+ },
+ {
+ identifier: 'user_record',
+ route: '/user/record',
+ module: require('NeteaseCloudMusicApi/module/user_record'),
+ },
+ {
+ identifier: 'user_playlist',
+ route: '/user/playlist',
+ module: require('NeteaseCloudMusicApi/module/user_playlist'),
+ },
+ {
+ identifier: 'user_level',
+ route: '/user/level',
+ module: require('NeteaseCloudMusicApi/module/user_level'),
+ },
+ {
+ identifier: 'user_follows',
+ route: '/user/follows',
+ module: require('NeteaseCloudMusicApi/module/user_follows'),
+ },
+ {
+ identifier: 'user_followeds',
+ route: '/user/followeds',
+ module: require('NeteaseCloudMusicApi/module/user_followeds'),
+ },
+ {
+ identifier: 'user_event',
+ route: '/user/event',
+ module: require('NeteaseCloudMusicApi/module/user_event'),
+ },
+ {
+ identifier: 'user_dj',
+ route: '/user/dj',
+ module: require('NeteaseCloudMusicApi/module/user_dj'),
+ },
+ {
+ identifier: 'user_detail',
+ route: '/user/detail',
+ module: require('NeteaseCloudMusicApi/module/user_detail'),
+ },
+ {
+ identifier: 'user_cloud_detail',
+ route: '/user/cloud/detail',
+ module: require('NeteaseCloudMusicApi/module/user_cloud_detail'),
+ },
+ {
+ identifier: 'user_cloud_del',
+ route: '/user/cloud/del',
+ module: require('NeteaseCloudMusicApi/module/user_cloud_del'),
+ },
+ {
+ identifier: 'user_cloud',
+ route: '/user/cloud',
+ module: require('NeteaseCloudMusicApi/module/user_cloud'),
+ },
+ {
+ identifier: 'user_bindingcellphone',
+ route: '/user/bindingcellphone',
+ module: require('NeteaseCloudMusicApi/module/user_bindingcellphone'),
+ },
+ {
+ identifier: 'user_binding',
+ route: '/user/binding',
+ module: require('NeteaseCloudMusicApi/module/user_binding'),
+ },
+ {
+ identifier: 'user_audio',
+ route: '/user/audio',
+ module: require('NeteaseCloudMusicApi/module/user_audio'),
+ },
+ {
+ identifier: 'user_account',
+ route: '/user/account',
+ module: require('NeteaseCloudMusicApi/module/user_account'),
+ },
+ {
+ identifier: 'toplist_detail',
+ route: '/toplist/detail',
+ module: require('NeteaseCloudMusicApi/module/toplist_detail'),
+ },
+ {
+ identifier: 'toplist_artist',
+ route: '/toplist/artist',
+ module: require('NeteaseCloudMusicApi/module/toplist_artist'),
+ },
+ {
+ identifier: 'toplist',
+ route: '/toplist',
+ module: require('NeteaseCloudMusicApi/module/toplist'),
+ },
+ {
+ identifier: 'topic_sublist',
+ route: '/topic/sublist',
+ module: require('NeteaseCloudMusicApi/module/topic_sublist'),
+ },
+ {
+ identifier: 'topic_detail_event_hot',
+ route: '/topic/detail/event/hot',
+ module: require('NeteaseCloudMusicApi/module/topic_detail_event_hot'),
+ },
+ {
+ identifier: 'topic_detail',
+ route: '/topic/detail',
+ module: require('NeteaseCloudMusicApi/module/topic_detail'),
+ },
+ {
+ identifier: 'top_song',
+ route: '/top/song',
+ module: require('NeteaseCloudMusicApi/module/top_song'),
+ },
+ {
+ identifier: 'top_playlist_highquality',
+ route: '/top/playlist/highquality',
+ module: require('NeteaseCloudMusicApi/module/top_playlist_highquality'),
+ },
+ {
+ identifier: 'top_playlist',
+ route: '/top/playlist',
+ module: require('NeteaseCloudMusicApi/module/top_playlist'),
+ },
+ {
+ identifier: 'top_mv',
+ route: '/top/mv',
+ module: require('NeteaseCloudMusicApi/module/top_mv'),
+ },
+ {
+ identifier: 'top_list',
+ route: '/top/list',
+ module: require('NeteaseCloudMusicApi/module/top_list'),
+ },
+ {
+ identifier: 'top_artists',
+ route: '/top/artists',
+ module: require('NeteaseCloudMusicApi/module/top_artists'),
+ },
+ {
+ identifier: 'top_album',
+ route: '/top/album',
+ module: require('NeteaseCloudMusicApi/module/top_album'),
+ },
+ {
+ identifier: 'song_url',
+ route: '/song/url',
+ module: require('NeteaseCloudMusicApi/module/song_url'),
+ },
+ {
+ identifier: 'song_download_url',
+ route: '/song/download/url',
+ module: require('NeteaseCloudMusicApi/module/song_download_url'),
+ },
+ {
+ identifier: 'song_detail',
+ route: '/song/detail',
+ module: require('NeteaseCloudMusicApi/module/song_detail'),
+ },
+ {
+ identifier: 'simi_mv',
+ route: '/simi/mv',
+ module: require('NeteaseCloudMusicApi/module/simi_mv'),
+ },
+ {
+ identifier: 'simi_artist',
+ route: '/simi/artist',
+ module: require('NeteaseCloudMusicApi/module/simi_artist'),
+ },
+ {
+ identifier: 'search',
+ route: '/search',
+ module: require('NeteaseCloudMusicApi/module/search'),
+ },
+ {
+ identifier: 'scrobble',
+ route: '/scrobble',
+ module: require('NeteaseCloudMusicApi/module/scrobble'),
+ },
+ {
+ identifier: 'recommend_songs',
+ route: '/recommend/songs',
+ module: require('NeteaseCloudMusicApi/module/recommend_songs'),
+ },
+ {
+ identifier: 'recommend_resource',
+ route: '/recommend/resource',
+ module: require('NeteaseCloudMusicApi/module/recommend_resource'),
+ },
+ {
+ identifier: 'playmode_intelligence_list',
+ route: '/playmode/intelligence/list',
+ module: require('NeteaseCloudMusicApi/module/playmode_intelligence_list'),
+ },
+ {
+ identifier: 'playlist_video_recent',
+ route: '/playlist/video/recent',
+ module: require('NeteaseCloudMusicApi/module/playlist_video_recent'),
+ },
+ {
+ identifier: 'playlist_update',
+ route: '/playlist/update',
+ module: require('NeteaseCloudMusicApi/module/playlist_update'),
+ },
+ {
+ identifier: 'playlist_tracks',
+ route: '/playlist/tracks',
+ module: require('NeteaseCloudMusicApi/module/playlist_tracks'),
+ },
+ {
+ identifier: 'playlist_track_delete',
+ route: '/playlist/track/delete',
+ module: require('NeteaseCloudMusicApi/module/playlist_track_delete'),
+ },
+ {
+ identifier: 'playlist_track_all',
+ route: '/playlist/track/all',
+ module: require('NeteaseCloudMusicApi/module/playlist_track_all'),
+ },
+ {
+ identifier: 'playlist_track_add',
+ route: '/playlist/track/add',
+ module: require('NeteaseCloudMusicApi/module/playlist_track_add'),
+ },
+ {
+ identifier: 'playlist_tags_update',
+ route: '/playlist/tags/update',
+ module: require('NeteaseCloudMusicApi/module/playlist_tags_update'),
+ },
+ {
+ identifier: 'playlist_subscribers',
+ route: '/playlist/subscribers',
+ module: require('NeteaseCloudMusicApi/module/playlist_subscribers'),
+ },
+ {
+ identifier: 'playlist_subscribe',
+ route: '/playlist/subscribe',
+ module: require('NeteaseCloudMusicApi/module/playlist_subscribe'),
+ },
+ {
+ identifier: 'playlist_privacy',
+ route: '/playlist/privacy',
+ module: require('NeteaseCloudMusicApi/module/playlist_privacy'),
+ },
+ {
+ identifier: 'playlist_order_update',
+ route: '/playlist/order/update',
+ module: require('NeteaseCloudMusicApi/module/playlist_order_update'),
+ },
+ {
+ identifier: 'playlist_name_update',
+ route: '/playlist/name/update',
+ module: require('NeteaseCloudMusicApi/module/playlist_name_update'),
+ },
+ {
+ identifier: 'playlist_mylike',
+ route: '/playlist/mylike',
+ module: require('NeteaseCloudMusicApi/module/playlist_mylike'),
+ },
+ {
+ identifier: 'playlist_hot',
+ route: '/playlist/hot',
+ module: require('NeteaseCloudMusicApi/module/playlist_hot'),
+ },
+ {
+ identifier: 'playlist_highquality_tags',
+ route: '/playlist/highquality/tags',
+ module: require('NeteaseCloudMusicApi/module/playlist_highquality_tags'),
+ },
+ {
+ identifier: 'playlist_detail_dynamic',
+ route: '/playlist/detail/dynamic',
+ module: require('NeteaseCloudMusicApi/module/playlist_detail_dynamic'),
+ },
+ {
+ identifier: 'playlist_detail',
+ route: '/playlist/detail',
+ module: require('NeteaseCloudMusicApi/module/playlist_detail'),
+ },
+ {
+ identifier: 'playlist_desc_update',
+ route: '/playlist/desc/update',
+ module: require('NeteaseCloudMusicApi/module/playlist_desc_update'),
+ },
+ {
+ identifier: 'playlist_delete',
+ route: '/playlist/delete',
+ module: require('NeteaseCloudMusicApi/module/playlist_delete'),
+ },
+ {
+ identifier: 'playlist_create',
+ route: '/playlist/create',
+ module: require('NeteaseCloudMusicApi/module/playlist_create'),
+ },
+ {
+ identifier: 'playlist_cover_update',
+ route: '/playlist/cover/update',
+ module: require('NeteaseCloudMusicApi/module/playlist_cover_update'),
+ },
+ {
+ identifier: 'playlist_catlist',
+ route: '/playlist/catlist',
+ module: require('NeteaseCloudMusicApi/module/playlist_catlist'),
+ },
+ {
+ identifier: 'personalized',
+ route: '/personalized',
+ module: require('NeteaseCloudMusicApi/module/personalized'),
+ },
+ {
+ identifier: 'personal_fm',
+ route: '/personal_fm',
+ module: require('NeteaseCloudMusicApi/module/personal_fm'),
+ },
+ {
+ identifier: 'mv_url',
+ route: '/mv/url',
+ module: require('NeteaseCloudMusicApi/module/mv_url'),
+ },
+ {
+ identifier: 'mv_sublist',
+ route: '/mv/sublist',
+ module: require('NeteaseCloudMusicApi/module/mv_sublist'),
+ },
+ {
+ identifier: 'mv_sub',
+ route: '/mv/sub',
+ module: require('NeteaseCloudMusicApi/module/mv_sub'),
+ },
+ {
+ identifier: 'mv_first',
+ route: '/mv/first',
+ module: require('NeteaseCloudMusicApi/module/mv_first'),
+ },
+ {
+ identifier: 'mv_exclusive_rcmd',
+ route: '/mv/exclusive/rcmd',
+ module: require('NeteaseCloudMusicApi/module/mv_exclusive_rcmd'),
+ },
+ {
+ identifier: 'mv_detail_info',
+ route: '/mv/detail/info',
+ module: require('NeteaseCloudMusicApi/module/mv_detail_info'),
+ },
+ {
+ identifier: 'mv_detail',
+ route: '/mv/detail',
+ module: require('NeteaseCloudMusicApi/module/mv_detail'),
+ },
+ {
+ identifier: 'mv_all',
+ route: '/mv/all',
+ module: require('NeteaseCloudMusicApi/module/mv_all'),
+ },
+ {
+ identifier: 'lyric',
+ route: '/lyric',
+ module: require('NeteaseCloudMusicApi/module/lyric'),
+ },
+ {
+ identifier: 'logout',
+ route: '/logout',
+ module: require('NeteaseCloudMusicApi/module/logout'),
+ },
+ {
+ identifier: 'login_status',
+ route: '/login/status',
+ module: require('NeteaseCloudMusicApi/module/login_status'),
+ },
+ {
+ identifier: 'login_refresh',
+ route: '/login/refresh',
+ module: require('NeteaseCloudMusicApi/module/login_refresh'),
+ },
+ {
+ identifier: 'login_qr_key',
+ route: '/login/qr/key',
+ module: require('NeteaseCloudMusicApi/module/login_qr_key'),
+ },
+ {
+ identifier: 'login_qr_create',
+ route: '/login/qr/create',
+ module: require('NeteaseCloudMusicApi/module/login_qr_create'),
+ },
+ {
+ identifier: 'login_qr_check',
+ route: '/login/qr/check',
+ module: require('NeteaseCloudMusicApi/module/login_qr_check'),
+ },
+ {
+ identifier: 'login_cellphone',
+ route: '/login/cellphone',
+ module: require('NeteaseCloudMusicApi/module/login_cellphone'),
+ },
+ {
+ identifier: 'login',
+ route: '/login',
+ module: require('NeteaseCloudMusicApi/module/login'),
+ },
+ {
+ identifier: 'likelist',
+ route: '/likelist',
+ module: require('NeteaseCloudMusicApi/module/likelist'),
+ },
+ {
+ identifier: 'like',
+ route: '/like',
+ module: require('NeteaseCloudMusicApi/module/like'),
+ },
+ {
+ identifier: 'follow',
+ route: '/follow',
+ module: require('NeteaseCloudMusicApi/module/follow'),
+ },
+ {
+ identifier: 'fm_trash',
+ route: '/fm_trash',
+ module: require('NeteaseCloudMusicApi/module/fm_trash'),
+ },
+ {
+ identifier: 'daily_signin',
+ route: '/daily_signin',
+ module: require('NeteaseCloudMusicApi/module/daily_signin'),
+ },
+ {
+ identifier: 'cloudsearch',
+ route: '/cloudsearch',
+ module: require('NeteaseCloudMusicApi/module/cloudsearch'),
+ },
+ {
+ identifier: 'cloud',
+ route: '/cloud',
+ module: require('NeteaseCloudMusicApi/module/cloud'),
+ },
+ {
+ identifier: 'check_music',
+ route: '/check/music',
+ module: require('NeteaseCloudMusicApi/module/check_music'),
+ },
+ {
+ identifier: 'cellphone_existence_check',
+ route: '/cellphone/existence/check',
+ module: require('NeteaseCloudMusicApi/module/cellphone_existence_check'),
+ },
+ {
+ identifier: 'captcha_verify',
+ route: '/captcha/verify',
+ module: require('NeteaseCloudMusicApi/module/captcha_verify'),
+ },
+ {
+ identifier: 'captcha_sent',
+ route: '/captcha/sent',
+ module: require('NeteaseCloudMusicApi/module/captcha_sent'),
+ },
+ {
+ identifier: 'calendar',
+ route: '/calendar',
+ module: require('NeteaseCloudMusicApi/module/calendar'),
+ },
+ {
+ identifier: 'batch',
+ route: '/batch',
+ module: require('NeteaseCloudMusicApi/module/batch'),
+ },
+ {
+ identifier: 'banner',
+ route: '/banner',
+ module: require('NeteaseCloudMusicApi/module/banner'),
+ },
+ {
+ identifier: 'avatar_upload',
+ route: '/avatar/upload',
+ module: require('NeteaseCloudMusicApi/module/avatar_upload'),
+ },
+ {
+ identifier: 'audio_match',
+ route: '/audio/match',
+ module: require('NeteaseCloudMusicApi/module/audio_match'),
+ },
+ {
+ identifier: 'artists',
+ route: '/artists',
+ module: require('NeteaseCloudMusicApi/module/artists'),
+ },
+ {
+ identifier: 'artist_video',
+ route: '/artist/video',
+ module: require('NeteaseCloudMusicApi/module/artist_video'),
+ },
+ {
+ identifier: 'artist_top_song',
+ route: '/artist/top/song',
+ module: require('NeteaseCloudMusicApi/module/artist_top_song'),
+ },
+ {
+ identifier: 'artist_sublist',
+ route: '/artist/sublist',
+ module: require('NeteaseCloudMusicApi/module/artist_sublist'),
+ },
+ {
+ identifier: 'artist_sub',
+ route: '/artist/sub',
+ module: require('NeteaseCloudMusicApi/module/artist_sub'),
+ },
+ {
+ identifier: 'artist_songs',
+ route: '/artist/songs',
+ module: require('NeteaseCloudMusicApi/module/artist_songs'),
+ },
+ {
+ identifier: 'artist_new_song',
+ route: '/artist/new/song',
+ module: require('NeteaseCloudMusicApi/module/artist_new_song'),
+ },
+ {
+ identifier: 'artist_new_mv',
+ route: '/artist/new/mv',
+ module: require('NeteaseCloudMusicApi/module/artist_new_mv'),
+ },
+ {
+ identifier: 'artist_mv',
+ route: '/artist/mv',
+ module: require('NeteaseCloudMusicApi/module/artist_mv'),
+ },
+ {
+ identifier: 'artist_list',
+ route: '/artist/list',
+ module: require('NeteaseCloudMusicApi/module/artist_list'),
+ },
+ {
+ identifier: 'artist_fans',
+ route: '/artist/fans',
+ module: require('NeteaseCloudMusicApi/module/artist_fans'),
+ },
+ {
+ identifier: 'artist_detail',
+ route: '/artist/detail',
+ module: require('NeteaseCloudMusicApi/module/artist_detail'),
+ },
+ {
+ identifier: 'artist_desc',
+ route: '/artist/desc',
+ module: require('NeteaseCloudMusicApi/module/artist_desc'),
+ },
+ {
+ identifier: 'artist_album',
+ route: '/artist/album',
+ module: require('NeteaseCloudMusicApi/module/artist_album'),
+ },
+ {
+ identifier: 'album_sublist',
+ route: '/album/sublist',
+ module: require('NeteaseCloudMusicApi/module/album_sublist'),
+ },
+ {
+ identifier: 'album_sub',
+ route: '/album/sub',
+ module: require('NeteaseCloudMusicApi/module/album_sub'),
+ },
+ {
+ identifier: 'album_songsaleboard',
+ route: '/album/songsaleboard',
+ module: require('NeteaseCloudMusicApi/module/album_songsaleboard'),
+ },
+ {
+ identifier: 'album_newest',
+ route: '/album/newest',
+ module: require('NeteaseCloudMusicApi/module/album_newest'),
+ },
+ {
+ identifier: 'album_new',
+ route: '/album/new',
+ module: require('NeteaseCloudMusicApi/module/album_new'),
+ },
+ {
+ identifier: 'album_list_style',
+ route: '/album/list/style',
+ module: require('NeteaseCloudMusicApi/module/album_list_style'),
+ },
+ {
+ identifier: 'album_list',
+ route: '/album/list',
+ module: require('NeteaseCloudMusicApi/module/album_list'),
+ },
+ {
+ identifier: 'album_detail_dynamic',
+ route: '/album/detail/dynamic',
+ module: require('NeteaseCloudMusicApi/module/album_detail_dynamic'),
+ },
+ {
+ identifier: 'album_detail',
+ route: '/album/detail',
+ module: require('NeteaseCloudMusicApi/module/album_detail'),
+ },
+ {
+ identifier: 'album',
+ route: '/album',
+ module: require('NeteaseCloudMusicApi/module/album'),
+ },
+ {
+ identifier: 'activate_init_profile',
+ route: '/activate/init/profile',
+ module: require('NeteaseCloudMusicApi/module/activate_init_profile'),
+ },
+];
diff --git a/src/store/actions.js b/src/store/actions.js
index d29eb88..83c0666 100644
--- a/src/store/actions.js
+++ b/src/store/actions.js
@@ -5,6 +5,7 @@ import { getPlaylistDetail } from '@/api/playlist';
import { getTrackDetail } from '@/api/track';
import {
userPlaylist,
+ userPlayHistory,
userLikedSongsIDs,
likedAlbums,
likedArtists,
@@ -100,7 +101,7 @@ export default {
if (!isLooseLoggedIn()) return;
if (isAccountLoggedIn()) {
return userPlaylist({
- uid: state.data.user.userId,
+ uid: state.data.user?.userId,
limit: 2000, // 最多只加载2000个歌单(等有用户反馈问题再修)
timestamp: new Date().getTime(),
}).then(result => {
@@ -155,7 +156,8 @@ export default {
},
fetchCloudDisk: ({ commit }) => {
if (!isAccountLoggedIn()) return;
- return cloudDisk().then(result => {
+ // FIXME: #1242
+ return cloudDisk({ limit: 1000 }).then(result => {
if (result.data) {
commit('updateLikedXXX', {
name: 'cloudDisk',
@@ -164,6 +166,30 @@ export default {
}
});
},
+ fetchPlayHistory: ({ state, commit }) => {
+ if (!isAccountLoggedIn()) return;
+ return Promise.all([
+ userPlayHistory({ uid: state.data.user?.userId, type: 0 }),
+ userPlayHistory({ uid: state.data.user?.userId, type: 1 }),
+ ]).then(result => {
+ const data = {};
+ const dataType = { 0: 'allData', 1: 'weekData' };
+ if (result[0] && result[1]) {
+ for (let i = 0; i < result.length; i++) {
+ const songData = result[i][dataType[i]].map(item => {
+ const song = item.song;
+ song.playCount = item.playCount;
+ return song;
+ });
+ data[[dataType[i]]] = songData;
+ }
+ commit('updateLikedXXX', {
+ name: 'playHistory',
+ data: data,
+ });
+ }
+ });
+ },
fetchUserProfile: ({ commit }) => {
if (!isAccountLoggedIn()) return;
return userAccount().then(result => {
diff --git a/src/store/initLocalStorage.js b/src/store/initLocalStorage.js
index 7e642a2..9540efb 100644
--- a/src/store/initLocalStorage.js
+++ b/src/store/initLocalStorage.js
@@ -19,19 +19,25 @@ let localStorage = {
enableUnblockNeteaseMusic: true,
automaticallyCacheSongs: true,
cacheLimit: 8192,
+ enableReversedMode: false,
nyancatStyle: false,
showLyricsTranslation: true,
lyricsBackground: true,
+ enableOsdlyricsSupport: false,
closeAppOption: 'ask',
enableDiscordRichPresence: false,
enableGlobalShortcut: true,
showLibraryDefault: false,
+ subTitleDefault: false,
+ linuxEnableCustomTitlebar: false,
enabledPlaylistCategories,
proxyConfig: {
protocol: 'noProxy',
server: '',
port: null,
},
+ enableRealIP: false,
+ realIP: null,
shortcuts: shortcuts,
},
data: {
diff --git a/src/store/mutations.js b/src/store/mutations.js
index 42c3c8e..d6a4b3b 100644
--- a/src/store/mutations.js
+++ b/src/store/mutations.js
@@ -31,9 +31,8 @@ export default {
c => c === name
);
if (index !== -1) {
- state.settings.enabledPlaylistCategories = state.settings.enabledPlaylistCategories.filter(
- c => c !== name
- );
+ state.settings.enabledPlaylistCategories =
+ state.settings.enabledPlaylistCategories.filter(c => c !== name);
} else {
state.settings.enabledPlaylistCategories.push(name);
}
@@ -73,4 +72,7 @@ export default {
enableScrolling(state, status = null) {
state.enableScrolling = status ? status : !state.enableScrolling;
},
+ updateTitle(state, title) {
+ state.title = title;
+ },
};
diff --git a/src/store/state.js b/src/store/state.js
index 4de913a..827bee0 100644
--- a/src/store/state.js
+++ b/src/store/state.js
@@ -13,6 +13,7 @@ updateApp();
export default {
showLyrics: false,
enableScrolling: true,
+ title: 'YesPlayMusic',
liked: {
songs: [],
songsWithDetails: [], // 只有前12首
@@ -21,6 +22,10 @@ export default {
artists: [],
mvs: [],
cloudDisk: [],
+ playHistory: {
+ weekData: [],
+ allData: [],
+ },
},
contextMenu: {
clickObjectID: 0,
diff --git a/src/utils/Player.js b/src/utils/Player.js
index 20ff303..11af73a 100644
--- a/src/utils/Player.js
+++ b/src/utils/Player.js
@@ -1,19 +1,61 @@
-import { getTrackDetail, scrobble, getMP3 } from '@/api/track';
-import shuffle from 'lodash/shuffle';
-import { Howler, Howl } from 'howler';
-import { cacheTrackSource, getTrackSource } from '@/utils/db';
import { getAlbum } from '@/api/album';
-import { getPlaylistDetail } from '@/api/playlist';
import { getArtist } from '@/api/artist';
-import { personalFM, fmTrash } from '@/api/others';
+import { trackScrobble, trackUpdateNowPlaying } from '@/api/lastfm';
+import { fmTrash, personalFM } from '@/api/others';
+import { getPlaylistDetail, intelligencePlaylist } from '@/api/playlist';
+import { getLyric, getMP3, getTrackDetail } from '@/api/track';
import store from '@/store';
import { isAccountLoggedIn } from '@/utils/auth';
-import { trackUpdateNowPlaying, trackScrobble } from '@/api/lastfm';
+import { cacheTrackSource, getTrackSource } from '@/utils/db';
+import { isCreateMpris, isCreateTray } from '@/utils/platform';
+import { Howl, Howler } from 'howler';
+import shuffle from 'lodash/shuffle';
+import { decode as base642Buffer } from '@/utils/base64';
+
+const PLAY_PAUSE_FADE_DURATION = 200;
+
+const INDEX_IN_PLAY_NEXT = -1;
+
+/**
+ * @readonly
+ * @enum {string}
+ */
+const UNPLAYABLE_CONDITION = {
+ PLAY_NEXT_TRACK: 'playNextTrack',
+ PLAY_PREV_TRACK: 'playPrevTrack',
+};
const electron =
process.env.IS_ELECTRON === true ? window.require('electron') : null;
const ipcRenderer =
process.env.IS_ELECTRON === true ? electron.ipcRenderer : null;
+const delay = ms =>
+ new Promise(resolve => {
+ setTimeout(() => {
+ resolve('');
+ }, ms);
+ });
+const excludeSaveKeys = [
+ '_playing',
+ '_personalFMLoading',
+ '_personalFMNextLoading',
+];
+
+function setTitle(track) {
+ document.title = track
+ ? `${track.name} · ${track.ar[0].name} - YesPlayMusic`
+ : 'YesPlayMusic';
+ if (isCreateTray) {
+ ipcRenderer?.send('updateTrayTooltip', document.title);
+ }
+ store.commit('updateTitle', document.title);
+}
+
+function setTrayLikeState(isLiked) {
+ if (isCreateTray) {
+ ipcRenderer?.send('updateTrayLikeState', isLiked);
+ }
+}
export default class {
constructor() {
@@ -23,8 +65,11 @@ export default class {
this._enabled = false; // 是否启用Player
this._repeatMode = 'off'; // off | on | one
this._shuffle = false; // true | false
+ this._reversed = false;
this._volume = 1; // 0 to 1
this._volumeBeforeMuted = 1; // 用于保存静音前的音量
+ this._personalFMLoading = false; // 是否正在私人FM中加载新的track
+ this._personalFMNextLoading = false; // 是否正在缓存私人FM的下一首歌曲
// 播放信息
this._list = []; // 播放列表
@@ -36,7 +81,17 @@ export default class {
this._playNextList = []; // 当这个list不为空时,会优先播放这个list的歌
this._isPersonalFM = false; // 是否是私人FM模式
this._personalFMTrack = { id: 0 }; // 私人FM当前歌曲
- this._personalFMNextTrack = { id: 0 }; // 私人FM下一首歌曲信息(为了快速加载下一首)
+ this._personalFMNextTrack = {
+ id: 0,
+ }; // 私人FM下一首歌曲信息(为了快速加载下一首)
+
+ /**
+ * The blob records for cleanup.
+ *
+ * @private
+ * @type {string[]}
+ */
+ this.createdBlobRecords = [];
// howler (https://github.com/goldfire/howler.js)
this._howler = null;
@@ -75,13 +130,27 @@ export default class {
if (shuffle) {
this._shuffleTheList();
}
+ // 同步当前歌曲在列表中的下标
+ this.current = this.list.indexOf(this.currentTrackID);
+ }
+ get reversed() {
+ return this._reversed;
+ }
+ set reversed(reversed) {
+ if (this._isPersonalFM) return;
+ if (reversed !== true && reversed !== false) {
+ console.warn('reversed: invalid args, must be Boolean');
+ return;
+ }
+ console.log('changing reversed to:', reversed);
+ this._reversed = reversed;
}
get volume() {
return this._volume;
}
set volume(volume) {
this._volume = volume;
- Howler.volume(volume);
+ this._howler?.volume(volume);
}
get list() {
return this.shuffle ? this._shuffledList : this._list;
@@ -108,6 +177,9 @@ export default class {
get currentTrack() {
return this._currentTrack;
}
+ get currentTrackID() {
+ return this._currentTrack?.id ?? 0;
+ }
get playlistSource() {
return this._playlistSource;
}
@@ -131,6 +203,9 @@ export default class {
set progress(value) {
if (this._howler) {
this._howler.seek(value);
+ if (isCreateMpris) {
+ ipcRenderer?.send('seeked', this._howler.seek());
+ }
}
}
get isCurrentTrackLiked() {
@@ -139,13 +214,11 @@ export default class {
_init() {
this._loadSelfFromLocalStorage();
- Howler.autoUnlock = false;
- Howler.usingWebAudio = true;
- Howler.volume(this.volume);
+ this._howler?.volume(this.volume);
if (this._enabled) {
// 恢复当前播放歌曲
- this._replaceCurrentTrack(this._currentTrack.id, false).then(() => {
+ this._replaceCurrentTrack(this.currentTrackID, false).then(() => {
this._howler?.seek(localStorage.getItem('playerCurrentTrackTime') ?? 0);
}); // update audio source and init howler
this._initMediaSession();
@@ -154,7 +227,11 @@ export default class {
this._setIntervals();
// 初始化私人FM
- if (this._personalFMTrack.id === 0 || this._personalFMNextTrack.id === 0) {
+ if (
+ this._personalFMTrack.id === 0 ||
+ this._personalFMNextTrack.id === 0 ||
+ this._personalFMTrack.id === this._personalFMNextTrack.id
+ ) {
personalFM().then(result => {
this._personalFMTrack = result.data[0];
this._personalFMNextTrack = result.data[1];
@@ -162,39 +239,65 @@ export default class {
});
}
}
+ _setPlaying(isPlaying) {
+ this._playing = isPlaying;
+ if (isCreateTray) {
+ ipcRenderer?.send('updateTrayPlayState', this._playing);
+ }
+ }
_setIntervals() {
// 同步播放进度
- // TODO: 如果 _progress 在别的地方被改变了,这个定时器会覆盖之前改变的值,是bug
+ // TODO: 如果 _progress 在别的地方被改变了,
+ // 这个定时器会覆盖之前改变的值,是bug
setInterval(() => {
if (this._howler === null) return;
this._progress = this._howler.seek();
localStorage.setItem('playerCurrentTrackTime', this._progress);
+ if (isCreateMpris) {
+ ipcRenderer?.send('playerCurrentTrackTime', this._progress);
+ }
}, 1000);
}
_getNextTrack() {
+ const next = this._reversed ? this.current - 1 : this.current + 1;
+
if (this._playNextList.length > 0) {
- let trackID = this._playNextList.shift();
- return [trackID, this.current];
+ let trackID = this._playNextList[0];
+ return [trackID, INDEX_IN_PLAY_NEXT];
}
- // 当歌曲是列表最后一首 && 循环模式开启
- if (this.list.length === this.current + 1 && this.repeatMode === 'on') {
- return [this.list[0], 0];
+ // 循环模式开启,则重新播放当前模式下的相对的下一首
+ if (this.repeatMode === 'on') {
+ if (this._reversed && this.current === 0) {
+ // 倒序模式,当前歌曲是第一首,则重新播放列表最后一首
+ return [this.list[this.list.length - 1], this.list.length - 1];
+ } else if (this.list.length === this.current + 1) {
+ // 正序模式,当前歌曲是最后一首,则重新播放第一首
+ return [this.list[0], 0];
+ }
}
// 返回 [trackID, index]
- return [this.list[this.current + 1], this.current + 1];
+ return [this.list[next], next];
}
_getPrevTrack() {
- // 当歌曲是列表第一首 && 循环模式开启
- if (this.current === 0 && this.repeatMode === 'on') {
- return [this.list[this.list.length - 1], this.list.length - 1];
+ const next = this._reversed ? this.current + 1 : this.current - 1;
+
+ // 循环模式开启,则重新播放当前模式下的相对的下一首
+ if (this.repeatMode === 'on') {
+ if (this._reversed && this.current === 0) {
+ // 倒序模式,当前歌曲是最后一首,则重新播放列表第一首
+ return [this.list[0], 0];
+ } else if (this.list.length === this.current + 1) {
+ // 正序模式,当前歌曲是第一首,则重新播放列表最后一首
+ return [this.list[this.list.length - 1], this.list.length - 1];
+ }
}
// 返回 [trackID, index]
- return [this.list[this.current - 1], this.current - 1];
+ return [this.list[next], next];
}
- async _shuffleTheList(firstTrackID = this._currentTrack.id) {
+ async _shuffleTheList(firstTrackID = this.currentTrackID) {
let list = this._list.filter(tid => tid !== firstTrackID);
if (firstTrackID === 'first') list = this._list;
this._shuffledList = shuffle(list);
@@ -206,11 +309,6 @@ export default class {
);
const trackDuration = ~~(track.dt / 1000);
time = completed ? trackDuration : ~~time;
- scrobble({
- id: track.id,
- sourceid: this.playlistSource.id,
- time,
- });
if (
store.state.lastfm.key !== undefined &&
(time >= trackDuration / 2 || time >= 240)
@@ -231,22 +329,65 @@ export default class {
this._howler = new Howl({
src: [source],
html5: true,
+ preload: true,
format: ['mp3', 'flac'],
+ onend: () => {
+ this._nextTrackCallback();
+ },
+ });
+ this._howler.on('loaderror', (_, errCode) => {
+ // https://developer.mozilla.org/en-US/docs/Web/API/MediaError/code
+ // code 3: MEDIA_ERR_DECODE
+ if (errCode === 3) {
+ this._playNextTrack(this._isPersonalFM);
+ } else if (errCode === 4) {
+ // code 4: MEDIA_ERR_SRC_NOT_SUPPORTED
+ store.dispatch('showToast', `无法播放: 不支持的音频格式`);
+ this._playNextTrack(this._isPersonalFM);
+ } else {
+ const t = this.progress;
+ this._replaceCurrentTrackAudio(this.currentTrack, false, false).then(
+ replaced => {
+ // 如果 replaced 为 false,代表当前的 track 已经不是这里想要替换的track
+ // 此时则不修改当前的歌曲进度
+ if (replaced) {
+ this._howler?.seek(t);
+ this.play();
+ }
+ }
+ );
+ }
});
if (autoplay) {
this.play();
- document.title = `${this._currentTrack.name} · ${this._currentTrack.ar[0].name} - YesPlayMusic`;
+ if (this._currentTrack.name) {
+ setTitle(this._currentTrack);
+ }
+ setTrayLikeState(store.state.liked.songs.includes(this.currentTrack.id));
}
this.setOutputDevice();
- this._howler.once('end', () => {
- this._nextTrackCallback();
- });
+ }
+ _getAudioSourceBlobURL(data) {
+ // Create a new object URL.
+ const source = URL.createObjectURL(new Blob([data]));
+
+ // Clean up the previous object URLs since we've created a new one.
+ // Revoke object URLs can release the memory taken by a Blob,
+ // which occupied a large proportion of memory.
+ for (const url in this.createdBlobRecords) {
+ URL.revokeObjectURL(url);
+ }
+
+ // Then, we replace the createBlobRecords with new one with
+ // our newly created object URL.
+ this.createdBlobRecords = [source];
+
+ return source;
}
_getAudioSourceFromCache(id) {
return getTrackSource(id).then(t => {
if (!t) return null;
- const source = URL.createObjectURL(new Blob([t.source]));
- return source;
+ return this._getAudioSourceBlobURL(t.source);
});
}
_getAudioSourceFromNetease(track) {
@@ -267,20 +408,73 @@ export default class {
});
}
}
- _getAudioSourceFromUnblockMusic(track) {
+ async _getAudioSourceFromUnblockMusic(track) {
console.debug(`[debug][Player.js] _getAudioSourceFromUnblockMusic`);
+
if (
process.env.IS_ELECTRON !== true ||
store.state.settings.enableUnblockNeteaseMusic === false
) {
return null;
}
- const source = ipcRenderer.sendSync('unblock-music', track);
- if (store.state.settings.automaticallyCacheSongs && source?.url) {
- // TODO: 将unblockMusic字样换成真正的来源(比如酷我咪咕等)
- cacheTrackSource(track, source.url, 128000, 'unblockMusic');
+
+ /**
+ *
+ * @param {string=} searchMode
+ * @returns {import("@unblockneteasemusic/rust-napi").SearchMode}
+ */
+ const determineSearchMode = searchMode => {
+ /**
+ * FastFirst = 0
+ * OrderFirst = 1
+ */
+ switch (searchMode) {
+ case 'fast-first':
+ return 0;
+ case 'order-first':
+ return 1;
+ default:
+ return 0;
+ }
+ };
+
+ const retrieveSongInfo = await ipcRenderer.invoke(
+ 'unblock-music',
+ store.state.settings.unmSource,
+ track,
+ {
+ enableFlac: store.state.settings.unmEnableFlac || null,
+ proxyUri: store.state.settings.unmProxyUri || null,
+ searchMode: determineSearchMode(store.state.settings.unmSearchMode),
+ config: {
+ 'joox:cookie': store.state.settings.unmJooxCookie || null,
+ 'qq:cookie': store.state.settings.unmQQCookie || null,
+ 'ytdl:exe': store.state.settings.unmYtDlExe || null,
+ },
+ }
+ );
+
+ if (store.state.settings.automaticallyCacheSongs && retrieveSongInfo?.url) {
+ // 对于来自 bilibili 的音源
+ // retrieveSongInfo.url 是音频数据的base64编码
+ // 其他音源为实际url
+ const url =
+ retrieveSongInfo.source === 'bilibili'
+ ? `data:application/octet-stream;base64,${retrieveSongInfo.url}`
+ : retrieveSongInfo.url;
+ cacheTrackSource(track, url, 128000, `unm:${retrieveSongInfo.source}`);
}
- return source?.url;
+
+ if (!retrieveSongInfo) {
+ return null;
+ }
+
+ if (retrieveSongInfo.source !== 'bilibili') {
+ return retrieveSongInfo.url;
+ }
+
+ const buffer = base642Buffer(retrieveSongInfo.url);
+ return this._getAudioSourceBlobURL(buffer);
}
_getAudioSource(track) {
return this._getAudioSourceFromCache(String(track.id))
@@ -294,32 +488,66 @@ export default class {
_replaceCurrentTrack(
id,
autoplay = true,
- ifUnplayableThen = 'playNextTrack'
+ ifUnplayableThen = UNPLAYABLE_CONDITION.PLAY_NEXT_TRACK
) {
if (autoplay && this._currentTrack.name) {
this._scrobble(this.currentTrack, this._howler?.seek());
}
return getTrackDetail(id).then(data => {
- let track = data.songs[0];
+ const track = data.songs[0];
this._currentTrack = track;
this._updateMediaSessionMetaData(track);
- return this._getAudioSource(track).then(source => {
- if (source) {
+ return this._replaceCurrentTrackAudio(
+ track,
+ autoplay,
+ true,
+ ifUnplayableThen
+ );
+ });
+ }
+ /**
+ * @returns 是否成功加载音频,并使用加载完成的音频替换了howler实例
+ */
+ _replaceCurrentTrackAudio(
+ track,
+ autoplay,
+ isCacheNextTrack,
+ ifUnplayableThen = UNPLAYABLE_CONDITION.PLAY_NEXT_TRACK
+ ) {
+ return this._getAudioSource(track).then(source => {
+ if (source) {
+ let replaced = false;
+ if (track.id === this.currentTrackID) {
this._playAudioSource(source, autoplay);
- this._cacheNextTrack();
- return source;
- } else {
- store.dispatch('showToast', `无法播放 ${track.name}`);
- ifUnplayableThen === 'playNextTrack'
- ? this.playNextTrack()
- : this.playPrevTrack();
+ replaced = true;
}
- });
+ if (isCacheNextTrack) {
+ this._cacheNextTrack();
+ }
+ return replaced;
+ } else {
+ store.dispatch('showToast', `无法播放 ${track.name}`);
+ switch (ifUnplayableThen) {
+ case UNPLAYABLE_CONDITION.PLAY_NEXT_TRACK:
+ this._playNextTrack(this.isPersonalFM);
+ break;
+ case UNPLAYABLE_CONDITION.PLAY_PREV_TRACK:
+ this.playPrevTrack();
+ break;
+ default:
+ store.dispatch(
+ 'showToast',
+ `undefined Unplayable condition: ${ifUnplayableThen}`
+ );
+ break;
+ }
+ return false;
+ }
});
}
_cacheNextTrack() {
let nextTrackID = this._isPersonalFM
- ? this._personalFMNextTrack.id
+ ? this._personalFMNextTrack?.id ?? 0
: this._getNextTrack()[0];
if (!nextTrackID) return;
if (this._personalFMTrack.id == nextTrackID) return;
@@ -347,7 +575,7 @@ export default class {
this.playPrevTrack();
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
- this.playNextTrack();
+ this._playNextTrack(this.isPersonalFM);
});
navigator.mediaSession.setActionHandler('stop', () => {
this.pause();
@@ -371,17 +599,51 @@ export default class {
return;
}
let artists = track.ar.map(a => a.name);
- navigator.mediaSession.metadata = new window.MediaMetadata({
+ const metadata = {
title: track.name,
artist: artists.join(','),
album: track.al.name,
artwork: [
+ {
+ src: track.al.picUrl + '?param=224y224',
+ type: 'image/jpg',
+ sizes: '224x224',
+ },
{
src: track.al.picUrl + '?param=512y512',
type: 'image/jpg',
sizes: '512x512',
},
],
+ length: this.currentTrackDuration,
+ trackId: this.current,
+ url: '/trackid/' + track.id,
+ };
+
+ navigator.mediaSession.metadata = new window.MediaMetadata(metadata);
+ if (isCreateMpris) {
+ this._updateMprisState(track, metadata);
+ }
+ }
+ // OSDLyrics 会检测 Mpris 状态并寻找对应歌词文件,所以要在更新 Mpris 状态之前保证歌词下载完成
+ async _updateMprisState(track, metadata) {
+ if (!store.state.settings.enableOsdlyricsSupport) {
+ return ipcRenderer?.send('metadata', metadata);
+ }
+
+ let lyricContent = await getLyric(track.id);
+
+ if (!lyricContent.lrc || !lyricContent.lrc.lyric) {
+ return ipcRenderer?.send('metadata', metadata);
+ }
+
+ ipcRenderer.send('sendLyrics', {
+ track,
+ lyrics: lyricContent.lrc.lyric,
+ });
+
+ ipcRenderer.on('saveLyricFinished', () => {
+ ipcRenderer?.send('metadata', metadata);
});
}
_updateMediaSessionPositionState() {
@@ -399,17 +661,32 @@ export default class {
_nextTrackCallback() {
this._scrobble(this._currentTrack, 0, true);
if (!this.isPersonalFM && this.repeatMode === 'one') {
- this._replaceCurrentTrack(this._currentTrack.id);
+ this._replaceCurrentTrack(this.currentTrackID);
} else {
- this.playNextTrack();
+ this._playNextTrack(this.isPersonalFM);
}
}
_loadPersonalFMNextTrack() {
- return personalFM().then(result => {
- this._personalFMNextTrack = result.data[0];
- this._cacheNextTrack(); // cache next track
- return this._personalFMNextTrack;
- });
+ if (this._personalFMNextLoading) {
+ return [false, undefined];
+ }
+ this._personalFMNextLoading = true;
+ return personalFM()
+ .then(result => {
+ if (!result || !result.data) {
+ this._personalFMNextTrack = undefined;
+ } else {
+ this._personalFMNextTrack = result.data[0];
+ this._cacheNextTrack(); // cache next track
+ }
+ this._personalFMNextLoading = false;
+ return [true, this._personalFMNextTrack];
+ })
+ .catch(() => {
+ this._personalFMNextTrack = undefined;
+ this._personalFMNextLoading = false;
+ return [false, this._personalFMNextTrack];
+ });
}
_playDiscordPresence(track, seekTime = 0) {
if (
@@ -420,7 +697,7 @@ export default class {
}
let copyTrack = { ...track };
copyTrack.dt -= seekTime * 1000;
- ipcRenderer.send('playDiscordPresence', copyTrack);
+ ipcRenderer?.send('playDiscordPresence', copyTrack);
}
_pauseDiscordPresence(track) {
if (
@@ -429,46 +706,96 @@ export default class {
) {
return null;
}
- ipcRenderer.send('pauseDiscordPresence', track);
+ ipcRenderer?.send('pauseDiscordPresence', track);
+ }
+ _playNextTrack(isPersonal) {
+ if (isPersonal) {
+ this.playNextFMTrack();
+ } else {
+ this.playNextTrack();
+ }
}
- currentTrackID() {
- const { list, current } = this._getListAndCurrent();
- return list[current];
- }
appendTrack(trackID) {
this.list.append(trackID);
}
- playNextTrack(isFM = false) {
- if (this._isPersonalFM || isFM === true) {
- this._isPersonalFM = true;
- this._personalFMTrack = this._personalFMNextTrack;
- this._replaceCurrentTrack(this._personalFMTrack.id);
- this._loadPersonalFMNextTrack();
- return true;
- }
+ playNextTrack() {
// TODO: 切换歌曲时增加加载中的状态
const [trackID, index] = this._getNextTrack();
if (trackID === undefined) {
this._howler?.stop();
- this._playing = false;
+ this._setPlaying(false);
return false;
}
- this.current = index;
+ let next = index;
+ if (index === INDEX_IN_PLAY_NEXT) {
+ this._playNextList.shift();
+ next = this.current;
+ }
+ this.current = next;
this._replaceCurrentTrack(trackID);
return true;
}
+ async playNextFMTrack() {
+ if (this._personalFMLoading) {
+ return false;
+ }
+
+ this._isPersonalFM = true;
+ if (!this._personalFMNextTrack) {
+ this._personalFMLoading = true;
+ let result = null;
+ let retryCount = 5;
+ for (; retryCount >= 0; retryCount--) {
+ result = await personalFM().catch(() => null);
+ if (!result) {
+ this._personalFMLoading = false;
+ store.dispatch('showToast', 'personal fm timeout');
+ return false;
+ }
+ if (result.data?.length > 0) {
+ break;
+ } else if (retryCount > 0) {
+ await delay(1000);
+ }
+ }
+ this._personalFMLoading = false;
+
+ if (retryCount < 0) {
+ let content = '获取私人FM数据时重试次数过多,请手动切换下一首';
+ store.dispatch('showToast', content);
+ console.log(content);
+ return false;
+ }
+ // 这里只能拿到一条数据
+ this._personalFMTrack = result.data[0];
+ } else {
+ if (this._personalFMNextTrack.id === this._personalFMTrack.id) {
+ return false;
+ }
+ this._personalFMTrack = this._personalFMNextTrack;
+ }
+ if (this._isPersonalFM) {
+ this._replaceCurrentTrack(this._personalFMTrack.id);
+ }
+ this._loadPersonalFMNextTrack();
+ return true;
+ }
playPrevTrack() {
const [trackID, index] = this._getPrevTrack();
if (trackID === undefined) return false;
this.current = index;
- this._replaceCurrentTrack(trackID, true, 'playPrevTrack');
+ this._replaceCurrentTrack(
+ trackID,
+ true,
+ UNPLAYABLE_CONDITION.PLAY_PREV_TRACK
+ );
return true;
}
saveSelfToLocalStorage() {
let player = {};
for (let [key, value] of Object.entries(this)) {
- if (key === '_playing') continue;
+ if (excludeSaveKeys.includes(key)) continue;
player[key] = value;
}
@@ -476,26 +803,41 @@ export default class {
}
pause() {
- this._howler?.pause();
- this._playing = false;
- document.title = 'YesPlayMusic';
- this._pauseDiscordPresence(this._currentTrack);
+ this._howler?.fade(this.volume, 0, PLAY_PAUSE_FADE_DURATION);
+
+ this._howler?.once('fade', () => {
+ this._howler?.pause();
+ this._setPlaying(false);
+ setTitle(null);
+ this._pauseDiscordPresence(this._currentTrack);
+ });
}
play() {
if (this._howler?.playing()) return;
+
this._howler?.play();
- this._playing = true;
- document.title = `${this._currentTrack.name} · ${this._currentTrack.ar[0].name} - YesPlayMusic`;
- this._playDiscordPresence(this._currentTrack, this.seek());
- if (store.state.lastfm.key !== undefined) {
- trackUpdateNowPlaying({
- artist: this.currentTrack.ar[0].name,
- track: this.currentTrack.name,
- album: this.currentTrack.al.name,
- trackNumber: this.currentTrack.no,
- duration: ~~(this.currentTrack.dt / 1000),
- });
- }
+
+ this._howler?.once('play', () => {
+ this._howler?.fade(0, this.volume, PLAY_PAUSE_FADE_DURATION);
+
+ // 播放时确保开启player.
+ // 避免因"忘记设置"导致在播放时播放器不显示的Bug
+ this._enabled = true;
+ this._setPlaying(true);
+ if (this._currentTrack.name) {
+ setTitle(this._currentTrack);
+ }
+ this._playDiscordPresence(this._currentTrack, this.seek());
+ if (store.state.lastfm.key !== undefined) {
+ trackUpdateNowPlaying({
+ artist: this.currentTrack.ar[0].name,
+ track: this.currentTrack.name,
+ album: this.currentTrack.al.name,
+ trackNumber: this.currentTrack.no,
+ duration: ~~(this.currentTrack.dt / 1000),
+ });
+ }
+ });
}
playOrPause() {
if (this._howler?.playing()) {
@@ -504,11 +846,14 @@ export default class {
this.play();
}
}
- seek(time = null) {
+ seek(time = null, sendMpris = true) {
+ if (isCreateMpris && sendMpris && time) {
+ ipcRenderer?.send('seeked', time);
+ }
if (time !== null) {
this._howler?.seek(time);
if (this._playing)
- this._playDiscordPresence(this._currentTrack, this.seek());
+ this._playDiscordPresence(this._currentTrack, this.seek(null, false));
}
return this._howler === null ? 0 : this._howler.seek();
}
@@ -534,7 +879,6 @@ export default class {
autoPlayTrackID = 'first'
) {
this._isPersonalFM = false;
- if (!this._enabled) this._enabled = true;
this.list = trackIDs;
this.current = 0;
this._playlistSource = {
@@ -545,7 +889,7 @@ export default class {
if (autoPlayTrackID === 'first') {
this._replaceCurrentTrack(this.list[0]);
} else {
- this.current = trackIDs.indexOf(autoPlayTrackID);
+ this.current = this.list.indexOf(autoPlayTrackID);
this._replaceCurrentTrack(autoPlayTrackID);
}
}
@@ -576,33 +920,48 @@ export default class {
}
this._replaceCurrentTrack(id);
}
+ playIntelligenceListById(id, trackID = 'first', noCache = false) {
+ getPlaylistDetail(id, noCache).then(data => {
+ const randomId = Math.floor(
+ Math.random() * (data.playlist.trackIds.length + 1)
+ );
+ const songId = data.playlist.trackIds[randomId].id;
+ intelligencePlaylist({ id: songId, pid: id }).then(result => {
+ let trackIDs = result.data.map(t => t.id);
+ this.replacePlaylist(trackIDs, id, 'playlist', trackID);
+ });
+ });
+ }
addTrackToPlayNext(trackID, playNow = false) {
this._playNextList.push(trackID);
- if (playNow) this.playNextTrack();
+ if (playNow) {
+ this.playNextTrack();
+ }
}
playPersonalFM() {
this._isPersonalFM = true;
- if (!this._enabled) this._enabled = true;
- if (this._currentTrack.id !== this._personalFMTrack.id) {
- this._replaceCurrentTrack(this._personalFMTrack.id).then(() =>
- this.playOrPause()
- );
+ if (this.currentTrackID !== this._personalFMTrack.id) {
+ this._replaceCurrentTrack(this._personalFMTrack.id, true);
} else {
this.playOrPause();
}
}
- moveToFMTrash() {
+ async moveToFMTrash() {
this._isPersonalFM = true;
- this.playNextTrack();
- fmTrash(this._personalFMTrack.id);
+ let id = this._personalFMTrack.id;
+ if (await this.playNextFMTrack()) {
+ fmTrash(id);
+ }
}
sendSelfToIpcMain() {
if (process.env.IS_ELECTRON !== true) return false;
- ipcRenderer.send('player', {
+ let liked = store.state.liked.songs.includes(this.currentTrack.id);
+ ipcRenderer?.send('player', {
playing: this.playing,
- likedCurrentTrack: store.state.liked.songs.includes(this.currentTrack.id),
+ likedCurrentTrack: liked,
});
+ setTrayLikeState(liked);
}
switchRepeatMode() {
@@ -613,9 +972,18 @@ export default class {
} else {
this.repeatMode = 'on';
}
+ if (isCreateMpris) {
+ ipcRenderer?.send('switchRepeatMode', this.repeatMode);
+ }
}
switchShuffle() {
this.shuffle = !this.shuffle;
+ if (isCreateMpris) {
+ ipcRenderer?.send('switchShuffle', this.shuffle);
+ }
+ }
+ switchReversed() {
+ this.reversed = !this.reversed;
}
clearPlayNextList() {
diff --git a/src/utils/base64.js b/src/utils/base64.js
new file mode 100644
index 0000000..99ac23c
--- /dev/null
+++ b/src/utils/base64.js
@@ -0,0 +1,67 @@
+// https://github.com/niklasvh/base64-arraybuffer/blob/master/src/index.ts
+// Copyright (c) 2012 Niklas von Hertzen Licensed under the MIT license.
+
+const chars =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+// Use a lookup table to find the index.
+const lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
+for (let i = 0; i < chars.length; i++) {
+ lookup[chars.charCodeAt(i)] = i;
+}
+
+export const encode = arraybuffer => {
+ let bytes = new Uint8Array(arraybuffer),
+ i,
+ len = bytes.length,
+ base64 = '';
+
+ for (i = 0; i < len; i += 3) {
+ base64 += chars[bytes[i] >> 2];
+ base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
+ base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
+ base64 += chars[bytes[i + 2] & 63];
+ }
+
+ if (len % 3 === 2) {
+ base64 = base64.substring(0, base64.length - 1) + '=';
+ } else if (len % 3 === 1) {
+ base64 = base64.substring(0, base64.length - 2) + '==';
+ }
+
+ return base64;
+};
+
+export const decode = base64 => {
+ let bufferLength = base64.length * 0.75,
+ len = base64.length,
+ i,
+ p = 0,
+ encoded1,
+ encoded2,
+ encoded3,
+ encoded4;
+
+ if (base64[base64.length - 1] === '=') {
+ bufferLength--;
+ if (base64[base64.length - 2] === '=') {
+ bufferLength--;
+ }
+ }
+
+ const arraybuffer = new ArrayBuffer(bufferLength),
+ bytes = new Uint8Array(arraybuffer);
+
+ for (i = 0; i < len; i += 4) {
+ encoded1 = lookup[base64.charCodeAt(i)];
+ encoded2 = lookup[base64.charCodeAt(i + 1)];
+ encoded3 = lookup[base64.charCodeAt(i + 2)];
+ encoded4 = lookup[base64.charCodeAt(i + 3)];
+
+ bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
+ bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
+ bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
+ }
+
+ return arraybuffer;
+};
diff --git a/src/utils/checkAuthToken.js b/src/utils/checkAuthToken.js
new file mode 100644
index 0000000..1086521
--- /dev/null
+++ b/src/utils/checkAuthToken.js
@@ -0,0 +1,8 @@
+import os from 'os';
+import fs from 'fs';
+import path from 'path';
+
+// extract from NeteasyCloudMusicAPI/generateConfig.js and avoid bugs in there (generateConfig require main.js but the main.js has bugs)
+if (!fs.existsSync(path.resolve(os.tmpdir(), 'anonymous_token'))) {
+ fs.writeFileSync(path.resolve(os.tmpdir(), 'anonymous_token'), '', 'utf-8');
+}
diff --git a/src/utils/common.js b/src/utils/common.js
index b7f2355..a89d500 100644
--- a/src/utils/common.js
+++ b/src/utils/common.js
@@ -9,6 +9,9 @@ export function isTrackPlayable(track) {
playable: true,
reason: '',
};
+ if (track?.privilege?.pl > 0) {
+ return result;
+ }
// cloud storage judgement logic
if (isAccountLoggedIn() && track?.privilege?.cs) {
return result;
@@ -218,7 +221,7 @@ export function bytesToSize(bytes) {
export function formatTrackTime(value) {
if (!value) return '';
- let min = ~~((value / 60) % 60);
+ let min = ~~(value / 60);
let sec = (~~(value % 60)).toString().padStart(2, '0');
return `${min}:${sec}`;
}
diff --git a/src/utils/lyrics.js b/src/utils/lyrics.js
index f0ed888..b883f46 100644
--- a/src/utils/lyrics.js
+++ b/src/utils/lyrics.js
@@ -1,33 +1,113 @@
-// copy from https://github.com/sl1673495/vue-netease-music/blob/master/src/utils/lrcparse.js
-
export function lyricParser(lrc) {
return {
lyric: parseLyric(lrc?.lrc?.lyric || ''),
tlyric: parseLyric(lrc?.tlyric?.lyric || ''),
+ romalyric: parseLyric(lrc?.romalrc?.lyric || ''),
lyricuser: lrc.lyricUser,
transuser: lrc.transUser,
};
}
-export function parseLyric(lrc) {
- const lyrics = lrc.split('\n');
- const lrcObj = [];
- for (let i = 0; i < lyrics.length; i++) {
- const lyric = lyrics[i];
- const timeReg = /\[\d*:\d*((\.|:)\d*)*\]/g;
- const timeRegExpArr = lyric.match(timeReg);
- if (!timeRegExpArr) continue;
- const content = lyric.replace(timeReg, '');
- for (let k = 0, h = timeRegExpArr.length; k < h; k++) {
- const t = timeRegExpArr[k];
- const min = Number(String(t.match(/\[\d*/i)).slice(1));
- const sec = Number(String(t.match(/:\d*/i)).slice(1));
- const ms = Number(t.match(/\d*\]/i)[0].slice(0, 2)) / 100;
- const time = min * 60 + sec + ms;
- if (content !== '') {
- lrcObj.push({ time: time, rawTime: timeRegExpArr[0], content });
+// regexr.com/6e52n
+const extractLrcRegex =
+ /^(?(?:\[.+?\])+)(?!\[)(?.+)$/gm;
+const extractTimestampRegex =
+ /\[(?\d+):(?\d+)(?:\.|:)*(?\d+)*\]/g;
+
+/**
+ * @typedef {{time: number, rawTime: string, content: string}} ParsedLyric
+ */
+
+/**
+ * Parse the lyric string.
+ *
+ * @param {string} lrc The `lrc` input.
+ * @returns {ParsedLyric[]} The parsed lyric.
+ * @example parseLyric("[00:00.00] Hello, World!\n[00:00.10] Test\n");
+ */
+function parseLyric(lrc) {
+ /**
+ * A sorted list of parsed lyric and its timestamp.
+ *
+ * @type {ParsedLyric[]}
+ * @see binarySearch
+ */
+ const parsedLyrics = [];
+
+ /**
+ * Find the appropriate index to push our parsed lyric.
+ * @param {ParsedLyric} lyric
+ */
+ const binarySearch = lyric => {
+ let time = lyric.time;
+
+ let low = 0;
+ let high = parsedLyrics.length - 1;
+
+ while (low <= high) {
+ const mid = Math.floor((low + high) / 2);
+ const midTime = parsedLyrics[mid].time;
+ if (midTime === time) {
+ return mid;
+ } else if (midTime < time) {
+ low = mid + 1;
+ } else {
+ high = mid - 1;
}
}
+
+ return low;
+ };
+
+ for (const line of lrc.trim().matchAll(extractLrcRegex)) {
+ const { lyricTimestamps, content } = line.groups;
+
+ for (const timestamp of lyricTimestamps.matchAll(extractTimestampRegex)) {
+ const { min, sec, ms } = timestamp.groups;
+ const rawTime = timestamp[0];
+ const time = Number(min) * 60 + Number(sec) + Number(ms ?? 0) * 0.001;
+
+ /** @type {ParsedLyric} */
+ const parsedLyric = { rawTime, time, content: trimContent(content) };
+ parsedLyrics.splice(binarySearch(parsedLyric), 0, parsedLyric);
+ }
+ }
+
+ return parsedLyrics;
+}
+
+/**
+ * @param {string} content
+ * @returns {string}
+ */
+function trimContent(content) {
+ let t = content.trim();
+ return t.length < 1 ? content : t;
+}
+
+/**
+ * @param {string} lyric
+ */
+export async function copyLyric(lyric) {
+ const textToCopy = lyric;
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ try {
+ await navigator.clipboard.writeText(textToCopy);
+ } catch (err) {
+ alert('复制失败,请手动复制!');
+ }
+ } else {
+ const tempInput = document.createElement('textarea');
+ tempInput.value = textToCopy;
+ tempInput.style.position = 'absolute';
+ tempInput.style.left = '-9999px';
+ document.body.appendChild(tempInput);
+ tempInput.select();
+ try {
+ document.execCommand('copy');
+ } catch (err) {
+ alert('复制失败,请手动复制!');
+ }
+ document.body.removeChild(tempInput);
}
- return lrcObj;
}
diff --git a/src/utils/nativeAlert.js b/src/utils/nativeAlert.js
index 64e716b..123cc70 100644
--- a/src/utils/nativeAlert.js
+++ b/src/utils/nativeAlert.js
@@ -13,14 +13,12 @@
*/
const nativeAlert = (() => {
if (process.env.IS_ELECTRON === true) {
- const {
- remote: { dialog },
- } = require('electron');
+ const { dialog } = require('electron');
if (dialog) {
return message => {
var options = {
type: 'warning',
- detail: message,
+ message,
};
dialog.showMessageBoxSync(null, options);
};
diff --git a/src/utils/platform.js b/src/utils/platform.js
new file mode 100644
index 0000000..c386d8a
--- /dev/null
+++ b/src/utils/platform.js
@@ -0,0 +1,7 @@
+export const isWindows = process.platform === 'win32';
+export const isMac = process.platform === 'darwin';
+export const isLinux = process.platform === 'linux';
+export const isDevelopment = process.env.NODE_ENV === 'development';
+
+export const isCreateTray = isWindows || isLinux || isDevelopment;
+export const isCreateMpris = isLinux;
diff --git a/src/utils/playList.js b/src/utils/playList.js
new file mode 100644
index 0000000..d135fc3
--- /dev/null
+++ b/src/utils/playList.js
@@ -0,0 +1,61 @@
+import router from '../router';
+import state from '../store/state';
+import {
+ recommendPlaylist,
+ dailyRecommendPlaylist,
+ getPlaylistDetail,
+} from '@/api/playlist';
+import { isAccountLoggedIn } from '@/utils/auth';
+
+export function hasListSource() {
+ return !state.player.isPersonalFM && state.player.playlistSource.id !== 0;
+}
+
+export function goToListSource() {
+ router.push({ path: getListSourcePath() });
+}
+
+export function getListSourcePath() {
+ if (state.player.playlistSource.id === state.data.likedSongPlaylistID) {
+ return '/library/liked-songs';
+ } else if (state.player.playlistSource.type === 'url') {
+ return state.player.playlistSource.id;
+ } else if (state.player.playlistSource.type === 'cloudDisk') {
+ return '/library';
+ } else {
+ return `/${state.player.playlistSource.type}/${state.player.playlistSource.id}`;
+ }
+}
+
+export async function getRecommendPlayList(limit, removePrivateRecommand) {
+ if (isAccountLoggedIn()) {
+ const playlists = await Promise.all([
+ dailyRecommendPlaylist(),
+ recommendPlaylist({ limit }),
+ ]);
+ let recommend = playlists[0].recommend ?? [];
+ if (recommend.length) {
+ if (removePrivateRecommand) recommend = recommend.slice(1);
+ await replaceRecommendResult(recommend);
+ }
+ return recommend.concat(playlists[1].result).slice(0, limit);
+ } else {
+ const response = await recommendPlaylist({ limit });
+ return response.result;
+ }
+}
+
+async function replaceRecommendResult(recommend) {
+ for (let r of recommend) {
+ if (specialPlaylist.indexOf(r.id) > -1) {
+ const data = await getPlaylistDetail(r.id, true);
+ const playlist = data.playlist;
+ if (playlist) {
+ r.name = playlist.name;
+ r.picUrl = playlist.coverImgUrl;
+ }
+ }
+ }
+}
+
+const specialPlaylist = [3136952023, 2829883282, 2829816518, 2829896389];
diff --git a/src/utils/request.js b/src/utils/request.js
index 6eae75c..6ac7bc3 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -1,5 +1,6 @@
+import router from '@/router';
+import { doLogout, getCookie } from '@/utils/auth';
import axios from 'axios';
-import { getCookie } from '@/utils/auth';
let baseURL = '';
// Web 和 Electron 跑在不同端口避免同时启动时冲突
@@ -21,14 +22,33 @@ const service = axios.create({
service.interceptors.request.use(function (config) {
if (!config.params) config.params = {};
- if (baseURL[0] !== '/' && !process.env.IS_ELECTRON) {
- config.params.cookie = `MUSIC_U=${getCookie('MUSIC_U')};`;
+ if (baseURL.length) {
+ if (
+ baseURL[0] !== '/' &&
+ !process.env.IS_ELECTRON &&
+ getCookie('MUSIC_U') !== null
+ ) {
+ config.params.cookie = `MUSIC_U=${getCookie('MUSIC_U')};`;
+ }
+ } else {
+ console.error("You must set up the baseURL in the service's config");
}
if (!process.env.IS_ELECTRON && !config.url.includes('/login')) {
config.params.realIP = '211.161.244.70';
}
+ // Force real_ip
+ const enableRealIP = JSON.parse(
+ localStorage.getItem('settings')
+ ).enableRealIP;
+ const realIP = JSON.parse(localStorage.getItem('settings')).realIP;
+ if (process.env.VUE_APP_REAL_IP) {
+ config.params.realIP = process.env.VUE_APP_REAL_IP;
+ } else if (enableRealIP) {
+ config.params.realIP = realIP;
+ }
+
const proxy = JSON.parse(localStorage.getItem('settings')).proxyConfig;
if (['HTTP', 'HTTPS'].includes(proxy.protocol)) {
config.params.proxy = `${proxy.protocol}://${proxy.server}:${proxy.port}`;
@@ -42,8 +62,37 @@ service.interceptors.response.use(
const res = response.data;
return res;
},
- error => {
- return Promise.reject(error);
+ async error => {
+ /** @type {import('axios').AxiosResponse | null} */
+ let response;
+ let data;
+ if (error === 'TypeError: baseURL is undefined') {
+ response = error;
+ data = error;
+ console.error("You must set up the baseURL in the service's config");
+ } else if (error.response) {
+ response = error.response;
+ data = response.data;
+ }
+
+ if (
+ response &&
+ typeof data === 'object' &&
+ data.code === 301 &&
+ data.msg === '需要登录'
+ ) {
+ console.warn('Token has expired. Logout now!');
+
+ // 登出帳戶
+ doLogout();
+
+ // 導向登入頁面
+ if (process.env.IS_ELECTRON === true) {
+ router.push({ name: 'loginAccount' });
+ } else {
+ router.push({ name: 'login' });
+ }
+ }
}
);
diff --git a/src/views/album.vue b/src/views/album.vue
index cebd8df..acc8a40 100644
--- a/src/views/album.vue
+++ b/src/views/album.vue
@@ -28,7 +28,9 @@
Compilation by Various Artists
-
{{
@@ -71,12 +73,12 @@
-
-
-
Disc {{ cd }}
+
+
+
Disc {{ item.disc }}
@@ -96,9 +98,7 @@
{{ $t('album.released') }}
{{ album.publishTime | formatDate('MMMM D, YYYY') }}
-
- © {{ album.company }}
-
+
© {{ album.company }}
@@ -137,6 +137,9 @@
{{
$t('contextMenu.copyUrl')
}}
+
{{
+ $t('contextMenu.openInBrowser')
+ }}
@@ -150,7 +153,7 @@ import locale from '@/locale';
import { splitSoundtrackAlbumTitle, splitAlbumTitle } from '@/utils/common';
import NProgress from 'nprogress';
import { isAccountLoggedIn } from '@/utils/auth';
-import { groupBy } from 'lodash';
+import { groupBy, toPairs, sortBy } from 'lodash';
import ExplicitSymbol from '@/components/ExplicitSymbol.vue';
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
@@ -219,7 +222,12 @@ export default {
}
},
tracksByDisc() {
- return groupBy(this.tracks, 'cd');
+ if (this.tracks.length <= 1) return [];
+ const pairs = toPairs(groupBy(this.tracks, 'cd'));
+ return sortBy(pairs, p => p[0]).map(items => ({
+ disc: items[0],
+ tracks: items[1],
+ }));
},
},
created() {
@@ -305,7 +313,7 @@ export default {
},
copyUrl(id) {
let showToast = this.showToast;
- this.$copyText('https://music.163.com/#/album?id=' + id)
+ this.$copyText(`https://music.163.com/#/album?id=${id}`)
.then(function () {
showToast(locale.t('toast.copied'));
})
@@ -313,6 +321,10 @@ export default {
showToast(`${locale.t('toast.copyFailed')}${error}`);
});
},
+ openInBrowser(id) {
+ const url = `https://music.163.com/#/album?id=${id}`;
+ window.open(url);
+ },
},
};
@@ -378,6 +390,9 @@ export default {
}
}
}
+.disc {
+ color: var(--color-text);
+}
.explicit-symbol {
opacity: 0.28;
diff --git a/src/views/artist.vue b/src/views/artist.vue
index 0f0721d..d825436 100644
--- a/src/views/artist.vue
+++ b/src/views/artist.vue
@@ -2,7 +2,7 @@
-
![]()
+
{{ artist.name }}
@@ -75,7 +75,7 @@
@mouseleave="mvHover = false"
@click="goToMv(latestMV.id)"
>
-
![]()
+
MVs
- {{
+ {{
$t('home.seeMore')
}}
@@ -169,6 +169,9 @@
{{
$t('contextMenu.copyUrl')
}}
+
{{
+ $t('contextMenu.openInBrowser')
+ }}
@@ -182,6 +185,7 @@ import {
followAArtist,
similarArtists,
} from '@/api/artist';
+import { getTrackDetail } from '@/api/track';
import locale from '@/locale';
import { isAccountLoggedIn } from '@/utils/auth';
import NProgress from 'nprogress';
@@ -238,7 +242,9 @@ export default {
computed: {
...mapState(['player']),
albums() {
- return this.albumsData.filter(a => a.type === '专辑');
+ return this.albumsData.filter(
+ a => a.type === '专辑' || a.type === '精选集'
+ );
},
eps() {
return this.albumsData.filter(a =>
@@ -273,7 +279,7 @@ export default {
this.$parent.$refs.main.scrollTo({ top: 0 });
getArtist(id).then(data => {
this.artist = data.artist;
- this.popularTracks = data.hotSongs;
+ this.setPopularTracks(data.hotSongs);
if (next !== undefined) next();
NProgress.done();
this.show = true;
@@ -286,8 +292,16 @@ export default {
this.mvs = data.mvs;
this.hasMoreMV = data.hasMore;
});
- similarArtists(id).then(data => {
- this.similarArtists = data.artists;
+ if (isAccountLoggedIn()) {
+ similarArtists(id).then(data => {
+ this.similarArtists = data.artists;
+ });
+ }
+ },
+ setPopularTracks(hotSongs) {
+ const trackIDs = hotSongs.map(t => t.id);
+ getTrackDetail(trackIDs.join(',')).then(data => {
+ this.popularTracks = data.songs;
});
},
goToAlbum(id) {
@@ -339,7 +353,7 @@ export default {
},
copyUrl(id) {
let showToast = this.showToast;
- this.$copyText('https://music.163.com/#/artist?id=' + id)
+ this.$copyText(`https://music.163.com/#/artist?id=${id}`)
.then(function () {
showToast(locale.t('toast.copied'));
})
@@ -347,6 +361,10 @@ export default {
showToast(`${locale.t('toast.copyFailed')}${error}`);
});
},
+ openInBrowser(id) {
+ const url = `https://music.163.com/#/artist?id=${id}`;
+ window.open(url);
+ },
},
};
diff --git a/src/views/artistMV.vue b/src/views/artistMV.vue
index 69a7f35..ba0a8c1 100644
--- a/src/views/artistMV.vue
+++ b/src/views/artistMV.vue
@@ -1,9 +1,11 @@
-
{{
- artist.name
- }}'s Music Videos
+
{{ artist.name }}'s Music Videos
diff --git a/src/views/explore.vue b/src/views/explore.vue
index b41b0a3..90624d0 100644
--- a/src/views/explore.vue
+++ b/src/views/explore.vue
@@ -66,13 +66,9 @@
@@ -470,6 +762,20 @@ export default {
z-index: 1;
+ .date {
+ max-width: 54vh;
+ margin: 24px 0;
+ color: var(--color-text);
+ text-align: center;
+ font-size: 4rem;
+ font-weight: 600;
+ opacity: 0.88;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 1;
+ overflow: hidden;
+ }
+
.controls {
max-width: 54vh;
margin-top: 24px;
@@ -500,17 +806,31 @@ export default {
display: flex;
justify-content: space-between;
- .buttons {
+ .top-right {
display: flex;
- align-items: center;
+ justify-content: space-between;
- button {
- margin: 0 0 0 4px;
+ .volume-control {
+ margin: 0 10px;
+ display: flex;
+ align-items: center;
+ .volume-bar {
+ width: 84px;
+ }
}
- .svg-icon {
- height: 18px;
- width: 18px;
+ .buttons {
+ display: flex;
+ align-items: center;
+
+ button {
+ margin: 0 0 0 4px;
+ }
+
+ .svg-icon {
+ height: 18px;
+ width: 18px;
+ }
}
}
}
@@ -575,6 +895,12 @@ export default {
width: 22px;
}
}
+ .lyric-switch-icon {
+ color: var(--color-text);
+ font-size: 14px;
+ line-height: 14px;
+ opacity: 0.88;
+ }
}
}
}
@@ -622,19 +948,35 @@ export default {
max-width: 460px;
overflow-y: auto;
transition: 0.5s;
+ scrollbar-width: none; // firefox
.line {
- padding: 18px;
- transition: 0.2s;
+ margin: 2px 0;
+ padding: 12px 18px;
+ transition: 0.5s;
border-radius: 12px;
&:hover {
background: var(--color-secondary-bg-for-transparent);
}
- span {
- opacity: 0.28;
- cursor: default;
+ .content {
+ transform-origin: center left;
+ transform: scale(0.95);
+ transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ user-select: none;
+
+ span {
+ opacity: 0.28;
+ cursor: default;
+ font-size: 1em;
+ transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ }
+
+ span.translation {
+ opacity: 0.2;
+ font-size: 0.925em;
+ }
}
}
@@ -642,9 +984,20 @@ export default {
background: unset;
}
- .highlight span {
- opacity: 0.98;
- transition: 0.5s;
+ .translation {
+ margin-top: 0.1em;
+ }
+
+ .highlight div.content {
+ transform: scale(1);
+ span {
+ opacity: 0.98;
+ display: inline-block;
+ }
+
+ span.translation {
+ opacity: 0.65;
+ }
}
}
@@ -706,6 +1059,12 @@ export default {
}
}
+@media screen and (min-width: 1200px) {
+ .right-side .lyrics-container {
+ max-width: 600px;
+ }
+}
+
.slide-up-enter-active,
.slide-up-leave-active {
transition: all 0.4s;
diff --git a/src/views/mv.vue b/src/views/mv.vue
index c060df7..54dd544 100644
--- a/src/views/mv.vue
+++ b/src/views/mv.vue
@@ -11,11 +11,14 @@
}}
-
{{ mv.data.name }}
-
@@ -28,6 +31,14 @@
{{ $t('mv.moreVideo') }}
+
+ {{
+ $t('contextMenu.copyUrl')
+ }}
+ {{
+ $t('contextMenu.openInBrowser')
+ }}
+
@@ -40,6 +51,7 @@ import '@/assets/css/plyr.css';
import Plyr from 'plyr';
import ButtonIcon from '@/components/ButtonIcon.vue';
+import ContextMenu from '@/components/ContextMenu.vue';
import MvRow from '@/components/MvRow.vue';
import { mapActions } from 'vuex';
@@ -48,6 +60,7 @@ export default {
components: {
MvRow,
ButtonIcon,
+ ContextMenu,
},
beforeRouteUpdate(to, from, next) {
this.getData(to.params.id);
@@ -127,6 +140,23 @@ export default {
if (data.code === 200) this.mv.subed = !this.mv.subed;
});
},
+ openMenu(e) {
+ this.$refs.mvMenu.openMenu(e);
+ },
+ copyUrl(id) {
+ let showToast = this.showToast;
+ this.$copyText(`https://music.163.com/#/mv?id=${id}`)
+ .then(function () {
+ showToast(locale.t('toast.copied'));
+ })
+ .catch(error => {
+ showToast(`${locale.t('toast.copyFailed')}${error}`);
+ });
+ },
+ openInBrowser(id) {
+ const url = `https://music.163.com/#/mv?id=${id}`;
+ window.open(url);
+ },
},
};
@@ -181,8 +211,11 @@ export default {
}
}
-.like-button {
+.buttons {
display: inline-block;
+ .button {
+ display: inline-block;
+ }
.svg-icon {
height: 18px;
width: 18px;
diff --git a/src/views/next.vue b/src/views/next.vue
index 3dacf03..0f31462 100644
--- a/src/views/next.vue
+++ b/src/views/next.vue
@@ -57,7 +57,9 @@ export default {
this.player.current + 1,
this.player.current + 100
);
- return this.tracks.filter(t => trackIDs.includes(t.id));
+ return trackIDs
+ .map(tid => this.tracks.find(t => t.id === tid))
+ .filter(t => t);
},
playNextList() {
return this.player.playNextList;
diff --git a/src/views/playlist.vue b/src/views/playlist.vue
index 53b04d4..f735b84 100644
--- a/src/views/playlist.vue
+++ b/src/views/playlist.vue
@@ -27,11 +27,7 @@
-
{{
- data.user.nickname
- }}{{ $t('library.sLikedSongs') }}
+
+ {{ data.user.nickname }}{{ $t('library.sLikedSongs') }}
@@ -319,6 +318,10 @@ const specialPlaylist = {
name: '一周原创发现',
gradient: 'gradient-blue-purple',
},
+ 2829883282: {
+ name: '华语私人雷达',
+ gradient: 'gradient-yellow-red',
+ },
3136952023: {
name: '私人雷达',
gradient: 'gradient-radar',
diff --git a/src/views/settings.vue b/src/views/settings.vue
index eaf6a0b..2fb0063 100644
--- a/src/views/settings.vue
+++ b/src/views/settings.vue
@@ -3,7 +3,7 @@
-
![]()
+