qqmusic-api-enhanced 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,4 +16,5 @@ export default function search(query?: {
16
16
  limit?: number;
17
17
  cookie?: any;
18
18
  searchid?: string;
19
+ platform?: string;
19
20
  }, req?: typeof request): Promise<ApiResponse>;
package/module/search.js CHANGED
@@ -21,6 +21,7 @@ export default async function search(query = {}, req = request) {
21
21
  const page = Math.max(Number(query.page) || 1, 1);
22
22
  const limit = Math.min(Math.max(Number(query.limit) || 20, 1), 100);
23
23
  const searchId = query.searchid || getSearchId();
24
+ const platform = query.platform || "desktop";
24
25
  const cgiRes = await req("music.search.SearchCgiService", "DoSearchForQQMusicMobile", {
25
26
  query: keyword,
26
27
  search_type: searchType,
@@ -30,13 +31,18 @@ export default async function search(query = {}, req = request) {
30
31
  highlight: 1,
31
32
  }, {
32
33
  cookie: query.cookie,
33
- platform: "android",
34
+ platform,
34
35
  });
36
+ const rawBody = cgiRes.body || {};
37
+ const dataBody = rawBody.body || rawBody.data?.body || rawBody.data || rawBody;
38
+ const songItems = dataBody.item_song || dataBody.song?.list || dataBody.songs || [];
39
+ const songs = Array.isArray(songItems) ? songItems : (songItems.items || []);
35
40
  return {
36
41
  status: cgiRes.status,
37
42
  body: {
38
43
  code: cgiRes.body?.code ?? 200,
39
44
  data: cgiRes.body,
45
+ songs,
40
46
  },
41
47
  cookie: cgiRes.cookie,
42
48
  };
package/module/search.ts CHANGED
@@ -19,6 +19,7 @@ export default async function search(
19
19
  limit?: number;
20
20
  cookie?: any;
21
21
  searchid?: string;
22
+ platform?: string;
22
23
  } = {},
23
24
  req = request
24
25
  ): Promise<ApiResponse> {
@@ -34,6 +35,7 @@ export default async function search(
34
35
  const page = Math.max(Number(query.page) || 1, 1);
35
36
  const limit = Math.min(Math.max(Number(query.limit) || 20, 1), 100);
36
37
  const searchId = query.searchid || getSearchId();
38
+ const platform = query.platform || "desktop";
37
39
 
38
40
  const cgiRes = await req(
39
41
  "music.search.SearchCgiService",
@@ -48,15 +50,21 @@ export default async function search(
48
50
  },
49
51
  {
50
52
  cookie: query.cookie,
51
- platform: "android",
53
+ platform,
52
54
  }
53
55
  );
54
56
 
57
+ const rawBody = cgiRes.body || {};
58
+ const dataBody = rawBody.body || rawBody.data?.body || rawBody.data || rawBody;
59
+ const songItems = dataBody.item_song || dataBody.song?.list || dataBody.songs || [];
60
+ const songs = Array.isArray(songItems) ? songItems : (songItems.items || []);
61
+
55
62
  return {
56
63
  status: cgiRes.status,
57
64
  body: {
58
65
  code: cgiRes.body?.code ?? 200,
59
66
  data: cgiRes.body,
67
+ songs,
60
68
  },
61
69
  cookie: cgiRes.cookie,
62
70
  };
@@ -83,11 +83,10 @@ export function deriveVipInfo(body, now = Date.now()) {
83
83
  svipExpire = parseDateMs(vipData.starend);
84
84
  else if (vipData.ystarend)
85
85
  svipExpire = parseDateMs(vipData.ystarend);
86
+ else if (vipData.send)
87
+ svipExpire = parseDateMs(vipData.send);
86
88
  else if (identity.SvipEnd || identity.svip_end)
87
89
  svipExpire = parseDateMs(identity.SvipEnd || identity.svip_end);
88
- else if (svip > 0 && Number(vipData.userinfo?.expire || 0) > 0) {
89
- svipExpire = parseDateMs(vipData.userinfo.expire);
90
- }
91
90
  // 2. 分别提取普通 VIP / 豪华绿钻专有到期时间
92
91
  let vipExpire = undefined;
93
92
  if (identity.HugeVipEnd)
@@ -100,8 +99,24 @@ export function deriveVipInfo(body, now = Date.now()) {
100
99
  vipExpire = parseDateMs(identity.overdate);
101
100
  else if (vipData.mygreen)
102
101
  vipExpire = parseDateMs(vipData.mygreen);
103
- else if (svip === 0 && Number(vipData.userinfo?.expire || 0) > 0) {
104
- vipExpire = parseDateMs(vipData.userinfo.expire);
102
+ // 3. 通用 userinfo.expire 归集
103
+ const userinfoExpire = Number(vipData.userinfo?.expire || 0) > 0 ? parseDateMs(vipData.userinfo.expire) : undefined;
104
+ if (userinfoExpire !== undefined) {
105
+ if (svipExpire === undefined && vipExpire === undefined) {
106
+ if (svip > 0 && userinfoExpire > now) {
107
+ svipExpire = userinfoExpire;
108
+ }
109
+ else {
110
+ vipExpire = userinfoExpire;
111
+ }
112
+ }
113
+ else if (vipExpire === undefined) {
114
+ // 若已解析出 svipExpire(如已过期的 starend/send),则通用的 userinfo.expire 归属于绿钻 vipExpire
115
+ vipExpire = userinfoExpire;
116
+ }
117
+ else if (svipExpire === undefined && svip > 0) {
118
+ svipExpire = userinfoExpire;
119
+ }
105
120
  }
106
121
  const isSvipExpired = svipExpire !== undefined && svipExpire <= now;
107
122
  const isVipExpired = vipExpire !== undefined && vipExpire <= now;
@@ -137,14 +152,11 @@ export function deriveVipInfo(body, now = Date.now()) {
137
152
  vipTier = iconVip.vipTier;
138
153
  vipLevel = iconVip.vipLevel;
139
154
  vipYear = iconVip.vipYear;
140
- if (iconVip.vipTier === "vip" && vipExpire && vipExpire > now) {
141
- vipExpireTime = vipExpire;
155
+ if (iconVip.vipTier === "vip") {
156
+ vipExpireTime = vipExpire && vipExpire > now ? vipExpire : (userinfoExpire && userinfoExpire > now ? userinfoExpire : undefined);
142
157
  }
143
- else if (iconVip.vipTier === "svip" && svipExpire && svipExpire > now) {
144
- vipExpireTime = svipExpire;
145
- }
146
- else {
147
- vipExpireTime = undefined;
158
+ else if (iconVip.vipTier === "svip") {
159
+ vipExpireTime = svipExpire && svipExpire > now ? svipExpire : (userinfoExpire && userinfoExpire > now ? userinfoExpire : undefined);
148
160
  }
149
161
  }
150
162
  }
@@ -89,10 +89,8 @@ export function deriveVipInfo(body: any, now = Date.now()): NormalizedVipInfo {
89
89
  let svipExpire: number | undefined = undefined;
90
90
  if (vipData.starend) svipExpire = parseDateMs(vipData.starend);
91
91
  else if (vipData.ystarend) svipExpire = parseDateMs(vipData.ystarend);
92
+ else if (vipData.send) svipExpire = parseDateMs(vipData.send);
92
93
  else if (identity.SvipEnd || identity.svip_end) svipExpire = parseDateMs(identity.SvipEnd || identity.svip_end);
93
- else if (svip > 0 && Number(vipData.userinfo?.expire || 0) > 0) {
94
- svipExpire = parseDateMs(vipData.userinfo.expire);
95
- }
96
94
 
97
95
  // 2. 分别提取普通 VIP / 豪华绿钻专有到期时间
98
96
  let vipExpire: number | undefined = undefined;
@@ -101,8 +99,22 @@ export function deriveVipInfo(body: any, now = Date.now()): NormalizedVipInfo {
101
99
  else if (identity.eightEnd) vipExpire = parseDateMs(identity.eightEnd);
102
100
  else if (identity.overdate) vipExpire = parseDateMs(identity.overdate);
103
101
  else if (vipData.mygreen) vipExpire = parseDateMs(vipData.mygreen);
104
- else if (svip === 0 && Number(vipData.userinfo?.expire || 0) > 0) {
105
- vipExpire = parseDateMs(vipData.userinfo.expire);
102
+
103
+ // 3. 通用 userinfo.expire 归集
104
+ const userinfoExpire = Number(vipData.userinfo?.expire || 0) > 0 ? parseDateMs(vipData.userinfo.expire) : undefined;
105
+ if (userinfoExpire !== undefined) {
106
+ if (svipExpire === undefined && vipExpire === undefined) {
107
+ if (svip > 0 && userinfoExpire > now) {
108
+ svipExpire = userinfoExpire;
109
+ } else {
110
+ vipExpire = userinfoExpire;
111
+ }
112
+ } else if (vipExpire === undefined) {
113
+ // 若已解析出 svipExpire(如已过期的 starend/send),则通用的 userinfo.expire 归属于绿钻 vipExpire
114
+ vipExpire = userinfoExpire;
115
+ } else if (svipExpire === undefined && svip > 0) {
116
+ svipExpire = userinfoExpire;
117
+ }
106
118
  }
107
119
 
108
120
  const isSvipExpired = svipExpire !== undefined && svipExpire <= now;
@@ -141,12 +153,10 @@ export function deriveVipInfo(body: any, now = Date.now()): NormalizedVipInfo {
141
153
  vipTier = iconVip.vipTier;
142
154
  vipLevel = iconVip.vipLevel;
143
155
  vipYear = iconVip.vipYear;
144
- if (iconVip.vipTier === "vip" && vipExpire && vipExpire > now) {
145
- vipExpireTime = vipExpire;
146
- } else if (iconVip.vipTier === "svip" && svipExpire && svipExpire > now) {
147
- vipExpireTime = svipExpire;
148
- } else {
149
- vipExpireTime = undefined;
156
+ if (iconVip.vipTier === "vip") {
157
+ vipExpireTime = vipExpire && vipExpire > now ? vipExpire : (userinfoExpire && userinfoExpire > now ? userinfoExpire : undefined);
158
+ } else if (iconVip.vipTier === "svip") {
159
+ vipExpireTime = svipExpire && svipExpire > now ? svipExpire : (userinfoExpire && userinfoExpire > now ? userinfoExpire : undefined);
150
160
  }
151
161
  }
152
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qqmusic-api-enhanced",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "QQ音乐增强版API,支持扫码登录/凭证刷新/直链提取/歌词解密/歌单歌手检索 || QQ Music Enhanced API for Node.js & Bun",
5
5
  "type": "module",
6
6
  "main": "main.js",