favorite.js
1 import { cli, Strategy } from '@jackwener/opencli/registry'; 2 import { apiGet, payloadData, getSelfUid } from './utils.js'; 3 cli({ 4 site: 'bilibili', 5 name: 'favorite', 6 description: '我的收藏夹', 7 domain: 'www.bilibili.com', 8 strategy: Strategy.COOKIE, 9 args: [ 10 { name: 'fid', type: 'int', required: false, help: 'Favorite folder ID (defaults to first folder)' }, 11 { name: 'limit', type: 'int', default: 20, help: 'Number of results' }, 12 { name: 'page', type: 'int', default: 1, help: 'Page number' }, 13 ], 14 columns: ['rank', 'title', 'author', 'plays', 'url'], 15 func: async (page, kwargs) => { 16 const { fid: favoriteId, limit = 20, page: pageNum = 1 } = kwargs; 17 let fid; 18 if (favoriteId) { 19 fid = Number(favoriteId); 20 } else { 21 // Fall back to the default (first) favorite folder 22 const uid = await getSelfUid(page); 23 const foldersPayload = await apiGet(page, '/x/v3/fav/folder/created/list-all', { 24 params: { up_mid: uid }, 25 signed: true, 26 }); 27 const folders = payloadData(foldersPayload)?.list ?? []; 28 if (!folders.length) 29 return []; 30 fid = folders[0].id; 31 } 32 // Fetch favorite items 33 const payload = await apiGet(page, '/x/v3/fav/resource/list', { 34 params: { media_id: fid, pn: pageNum, ps: Math.min(Number(limit), 40) }, 35 signed: true, 36 }); 37 const medias = payloadData(payload)?.medias ?? []; 38 return medias.slice(0, Number(limit)).map((item, i) => ({ 39 rank: i + 1, 40 title: item.title ?? '', 41 author: item.upper?.name ?? '', 42 plays: item.cnt_info?.play ?? 0, 43 url: item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : '', 44 })); 45 }, 46 });