diff --git a/.github/workflows/docs-search-index.yml b/.github/workflows/docs-search-index.yml index 4895ad0d26f8ca..613389171e36ab 100644 --- a/.github/workflows/docs-search-index.yml +++ b/.github/workflows/docs-search-index.yml @@ -6,6 +6,7 @@ on: - master paths: - '.github/workflows/docs-search-index.yml' + - 'scripts/docs-scraper/docs.rsshub.app.json' - 'website/**' workflow_dispatch: ~ schedule: diff --git a/lib/config.js b/lib/config.js index 317b316f17054e..4e76cf06d8118f 100644 --- a/lib/config.js +++ b/lib/config.js @@ -10,6 +10,7 @@ const calculateValue = () => { const email_config = {}; const discuz_cookies = {}; const medium_cookies = {}; + const discourse_config = {}; for (const name in envs) { if (name.startsWith('BILIBILI_COOKIE_')) { @@ -27,6 +28,9 @@ const calculateValue = () => { } else if (name.startsWith('MEDIUM_COOKIE_')) { const username = name.slice(14).toLowerCase(); medium_cookies[username] = envs[name]; + } else if (name.startsWith('DISCOURSE_CONFIG_')) { + const id = name.slice('DISCOURSE_CONFIG_'.length); + discourse_config[id] = JSON.parse(envs[name]); } } @@ -136,6 +140,9 @@ const calculateValue = () => { discord: { authorization: envs.DISCORD_AUTHORIZATION, }, + discourse: { + config: discourse_config, + }, discuz: { cookies: discuz_cookies, }, @@ -275,6 +282,9 @@ const calculateValue = () => { telegram: { token: envs.TELEGRAM_TOKEN, }, + tophub: { + cookie: envs.TOPHUB_COOKIE, + }, twitter: { consumer_key: envs.TWITTER_CONSUMER_KEY, consumer_secret: envs.TWITTER_CONSUMER_SECRET, diff --git a/lib/radar.js b/lib/radar.js index 0766e3ab9d652b..09f24e6e8e99f4 100644 --- a/lib/radar.js +++ b/lib/radar.js @@ -3,7 +3,8 @@ const fs = require('fs'); const toSource = require('tosource'); const { join } = require('path'); -const allowNamespace = ['ehentai', 'test']; +// Namespaces that do not require radar.js +const allowNamespace = ['discourse', 'ehentai', 'test']; // Check if a radar.js file is exist under each folder of dirname for (const dir of fs.readdirSync(dirname)) { const dirPath = join(dirname, dir); diff --git a/lib/router.js b/lib/router.js index 1c199d0925b264..87bf2f261c5534 100644 --- a/lib/router.js +++ b/lib/router.js @@ -770,8 +770,8 @@ router.get('/blogs/wordpress/:domain/:https?', lazyloadRouteHandler('./routes/bl // 西祠胡同 router.get('/xici/:id?', lazyloadRouteHandler('./routes/xici')); -// 今日热榜 -router.get('/tophub/:id', lazyloadRouteHandler('./routes/tophub')); +// 今日热榜 migrated to v2 +// router.get('/tophub/:id', lazyloadRouteHandler('./routes/tophub')); // 游戏时光 router.get('/vgtime/news', lazyloadRouteHandler('./routes/vgtime/news.js')); diff --git a/lib/v2/baidu/maintainer.js b/lib/v2/baidu/maintainer.js index 8e0f88c0fd9a37..71e0b2ead05b92 100644 --- a/lib/v2/baidu/maintainer.js +++ b/lib/v2/baidu/maintainer.js @@ -1,7 +1,7 @@ module.exports = { '/gushitong/index': ['CaoMeiYouRen'], - '/tieba/forum/:kw': ['u3u'], - '/tieba/forum/good/:kw/:cid?': ['u3u'], + '/tieba/forum/good/:kw/:cid?/:sortBy?': ['u3u'], + '/tieba/forum/:kw/:sortBy?': ['u3u'], '/tieba/post/:id': ['u3u'], '/tieba/post/lz/:id': ['u3u'], '/tieba/user/:uid': ['igxlin', 'nczitzk'], diff --git a/lib/v2/baidu/router.js b/lib/v2/baidu/router.js index f01ef64f9c7d75..0fde58e4e0dd6c 100644 --- a/lib/v2/baidu/router.js +++ b/lib/v2/baidu/router.js @@ -1,7 +1,7 @@ module.exports = (router) => { router.get('/gushitong/index', require('./gushitong')); - router.get('/tieba/forum/:kw', require('./tieba/forum')); - router.get('/tieba/forum/good/:kw/:cid?', require('./tieba/forum')); + router.get('/tieba/forum/good/:kw/:cid?/:sortBy?', require('./tieba/forum')); + router.get('/tieba/forum/:kw/:sortBy?', require('./tieba/forum')); router.get('/tieba/post/:id', require('./tieba/post')); router.get('/tieba/post/lz/:id', require('./tieba/post')); router.get('/tieba/user/:uid', require('./tieba/user')); diff --git a/lib/v2/baidu/tieba/forum.js b/lib/v2/baidu/tieba/forum.js index 23bcf059e6b01a..33a479bfc46e59 100644 --- a/lib/v2/baidu/tieba/forum.js +++ b/lib/v2/baidu/tieba/forum.js @@ -6,7 +6,8 @@ const { art } = require('@/utils/render'); const path = require('path'); module.exports = async (ctx) => { - const { kw, cid } = ctx.params; + // sortBy: created, replied + const { kw, cid = '0', sortBy = 'created' } = ctx.params; // PC端:https://tieba.baidu.com/f?kw=${encodeURIComponent(kw)} // 移动端接口:https://tieba.baidu.com/mo/q/m?kw=${encodeURIComponent(kw)}&lp=5024&forum_recommend=1&lm=0&cid=0&has_url_param=1&pn=0&is_ajax=1 @@ -31,7 +32,7 @@ module.exports = async (ctx) => { .map((element) => { const item = $(element); const { id, author_name } = item.data('field'); - const time = item.find('.threadlist_reply_date').text().trim(); + const time = sortBy === 'created' ? item.find('.is_show_create_time').text().trim() : item.find('.threadlist_reply_date').text().trim(); const title = item.find('a.j_th_tit').text().trim(); const details = item.find('.threadlist_abs').text().trim(); const medias = item @@ -50,7 +51,7 @@ module.exports = async (ctx) => { medias, author_name, }), - pubDate: timezone(parseDate(time, ['HH:mm', 'M-D'], true), +8), + pubDate: timezone(parseDate(time, ['HH:mm', 'M-D', 'YYYY-MM'], true), +8), link: `https://tieba.baidu.com/p/${id}`, }; }); diff --git a/lib/v2/discourse/maintainer.js b/lib/v2/discourse/maintainer.js new file mode 100644 index 00000000000000..6d6c640d8ec69f --- /dev/null +++ b/lib/v2/discourse/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:configId/posts': ['dzx-dzx'], +}; diff --git a/lib/v2/discourse/posts.js b/lib/v2/discourse/posts.js new file mode 100644 index 00000000000000..0dc8317be9b5e9 --- /dev/null +++ b/lib/v2/discourse/posts.js @@ -0,0 +1,28 @@ +const config = require('@/config').value; +const got = require('@/utils/got'); +const RSSParser = require('@/utils/rss-parser'); + +module.exports = async (ctx) => { + if (!config.discourse.config[ctx.params.configId]) { + throw Error('Discourse RSS is disabled due to the lack of relevant config'); + } + const { link, key } = config.discourse.config[ctx.params.configId]; + + const feed = await RSSParser.parseString( + ( + await got(`${link}/posts.rss`, { + headers: { + 'User-Api-Key': key, + }, + }) + ).data + ); + + feed.items = feed.items.map((e) => ({ + description: e.content, + author: e.creator, + ...e, + })); + + ctx.state.data = { item: feed.items, ...feed }; +}; diff --git a/lib/v2/discourse/router.js b/lib/v2/discourse/router.js new file mode 100644 index 00000000000000..b59d0004f6d806 --- /dev/null +++ b/lib/v2/discourse/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:configId/posts', require('./posts')); +}; diff --git a/lib/v2/dlnews/category.js b/lib/v2/dlnews/category.js new file mode 100644 index 00000000000000..3b7f5d6744add2 --- /dev/null +++ b/lib/v2/dlnews/category.js @@ -0,0 +1,81 @@ +const cheerio = require('cheerio'); +const got = require('@/utils/got'); +const { getData, getList } = require('./utils'); +const { art } = require('@/utils/render'); +const path = require('path'); +const asyncPool = require('tiny-async-pool'); + +const _website = 'dlnews'; +const topics = { + defi: 'DeFi', + fintech: 'Fintech/VC/Deals', + 'llama-u': 'Llama U', + markets: 'Markets', + 'people-culture': 'People & Culture', + regulation: 'Regulation', + snapshot: 'Snapshot', + web3: 'Web3', +}; +const extractArticle = (ctx, item) => + ctx.cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + const scriptTagContent = $('script#fusion-metadata').text(); + const jsonData = JSON.parse(scriptTagContent.match(/Fusion\.globalContent=({.*?});Fusion\.globalContentConfig/)[1]).content_elements; + const filteredData = []; + for (const v of jsonData) { + if (v.type === 'header' && v.content.includes('What we’re reading')) { + break; + } else if (v.type === 'custom_embed' && Boolean(v.embed.config.text)) { + filteredData.push({ type: v.type, data: v.embed.config.text }); + } else if (v.type === 'text' && !v.content.includes('NOW READ: ')) { + filteredData.push({ type: v.type, data: v.content }); + } else if (v.type === 'header') { + filteredData.push({ type: v.type, data: v.content }); + } else if (v.type === 'list') { + filteredData.push({ type: v.type, list_type: v.list_type, items: v.items }); + } else if (v.type === 'image') { + filteredData.push({ type: v.type, src: v.url, alt: v.alt_text, caption: v.subtitle }); + } + } + item.description = art(path.resolve(__dirname, 'templates/description.art'), filteredData); + return item; + }); + +module.exports = async (ctx) => { + const { category } = ctx.params; + const baseUrl = 'https://www.dlnews.com'; + const apiPath = '/pf/api/v3/content/fetch/articles-api'; + let vertical; + if (category) { + vertical = category; + } else { + vertical = ''; + } + + const query = { + author: '', + date: 'now-1y/d', + offset: 0, + query: '', + size: 15, + sort: 'display_date:desc', + vertical, + }; + const data = await getData(`${baseUrl}${apiPath}?query=${encodeURIComponent(JSON.stringify(query))}&_website=${_website}`); + const list = getList(data); + const items = []; + for await (const data of asyncPool(3, list, (item) => extractArticle(ctx, item))) { + items.push(data); + } + + ctx.state.data = { + title: topics.hasOwnProperty(category) ? `${topics[category]} : DL News` : 'DL News', + link: baseUrl, + item: items, + description: topics.hasOwnProperty(category) ? `${topics[category]} : News on dlnews.com` : 'Latest News on dlnews.com', + logo: 'https://www.dlnews.com/pf/resources/favicon.ico?d=284', + icon: 'https://www.dlnews.com/pf/resources/favicon.ico?d=284', + language: 'en-us', + }; +}; diff --git a/lib/v2/dlnews/maintainer.js b/lib/v2/dlnews/maintainer.js new file mode 100644 index 00000000000000..7b13511df55667 --- /dev/null +++ b/lib/v2/dlnews/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:category?': ['Rjnishant530'], +}; diff --git a/lib/v2/dlnews/radar.js b/lib/v2/dlnews/radar.js new file mode 100644 index 00000000000000..c5946409cd16ae --- /dev/null +++ b/lib/v2/dlnews/radar.js @@ -0,0 +1,19 @@ +module.exports = { + 'dlnews.com': { + _name: 'DL NEWS', + '.': [ + { + title: 'All Articles', + docs: 'https://docs.rsshub.app/routes/finance#dl-news', + source: ['/articles/'], + target: '/dlnews/', + }, + { + title: 'Topic', + docs: 'https://docs.rsshub.app/routes/finance#dl-news', + source: ['/articles/:category'], + target: '/dlnews/:category', + }, + ], + }, +}; diff --git a/lib/v2/dlnews/router.js b/lib/v2/dlnews/router.js new file mode 100644 index 00000000000000..7eece4711efcad --- /dev/null +++ b/lib/v2/dlnews/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:category?', require('./category')); +}; diff --git a/lib/v2/dlnews/templates/description.art b/lib/v2/dlnews/templates/description.art new file mode 100644 index 00000000000000..bcfe4d7245bc5b --- /dev/null +++ b/lib/v2/dlnews/templates/description.art @@ -0,0 +1,24 @@ +{{ each $data d }} + {{ if d.type == 'custom_embed' }} + + {{ else if d.type == 'header' }} +

{{@ d.data }}

+ {{ else if d.type == 'list' }} + {{ if d.list_type == 'unordered' }}{{ else }}{{ /if }} + {{ else if d.type == 'image' }} +
+ {{ d.alt }} +
{{@ d.caption }}
+
+ {{ else if d.type == 'text' }} +

{{@ d.data }}

+ {{ /if }} +{{ /each }} \ No newline at end of file diff --git a/lib/v2/dlnews/utils.js b/lib/v2/dlnews/utils.js new file mode 100644 index 00000000000000..4a820ab2ad4ab9 --- /dev/null +++ b/lib/v2/dlnews/utils.js @@ -0,0 +1,22 @@ +const got = require('@/utils/got'); +const { parseDate } = require('@/utils/parse-date'); + +const baseUrl = 'https://www.dlnews.com'; +const getData = async (url) => (await got.get(url).json()).content_elements; + +const getList = (data) => + data.map((value) => { + const { _id, headlines, description, publish_date, website_url, taxonomy, credits, promo_items } = value; + return { + id: _id, + title: headlines.basic, + link: `${baseUrl}${website_url}`, + description: description.basic, + author: credits.by.map((v) => v.name).join(', '), + itunes_item_image: promo_items.basic.url, + pubDate: parseDate(publish_date), + category: taxonomy.sections.map((v) => v.name).join(', '), + }; + }); + +module.exports = { getData, getList }; diff --git a/lib/v2/latepost/index.js b/lib/v2/latepost/index.js index 492c4bf6e25402..4329f04bef9cc3 100644 --- a/lib/v2/latepost/index.js +++ b/lib/v2/latepost/index.js @@ -3,60 +3,114 @@ const cheerio = require('cheerio'); const timezone = require('@/utils/timezone'); const { parseDate, parseRelativeDate } = require('@/utils/parse-date'); -const titles = { - '': '最新报道', - 1: '晚点独家', - 2: '人物访谈', - 3: '晚点早知道', - 4: '长报道', -}; +/** + * Convert an array into a dictionary object. + * The keys of the dictionary object are the `id` properties of the elements in the array, + * and the values are the remaining properties of each element. + * @param {Array} arr - The array to be converted. + * @returns {Object} - The converted dictionary object. + */ +const arrayToDictionary = (arr) => + arr.reduce( + (dictionary, { id, ...rest }) => ({ + ...dictionary, + [id]: { + ...rest, + }, + }), + {} + ); module.exports = async (ctx) => { - const proma = ctx.params.proma ?? ''; + const { proma } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 5; + + const title = '晚点'; + const defaultTitle = '最新报道'; + const exclusiveCategory = '晚点独家'; const rootUrl = 'https://www.latepost.com'; - const currentUrl = `${rootUrl}/${proma ? 'site/index' : 'news/get-news-data'}`; + const currentUrl = new URL(proma ? `news/index?proma=${proma}` : '', rootUrl).href; + + const apiColumnUrl = new URL('site/get-column', rootUrl).href; + const apiCommentUrl = new URL('news/get-comment', rootUrl).href; + const apiUrl = new URL(proma ? 'site/index' : 'news/get-news-data', rootUrl).href; - const response = await got({ - method: 'post', - url: currentUrl, - page: 1, - programa: proma, + const { data: columnResponse } = await got(apiColumnUrl); + const columns = arrayToDictionary(columnResponse?.data ?? []); + + const { data: response } = await got.post(apiUrl, { + json: { + page: 1, + limit, + programa: parseInt(proma, 10), + }, }); - let items = response.data.data.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 25).map((item) => ({ + let items = response.data.slice(0, limit).map((item) => ({ title: item.title, - link: `${rootUrl}${item.detail_url}`, - category: item.label.map((l) => l.label), + link: new URL(item.detail_url, rootUrl).href, + category: [item.is_dj ? exclusiveCategory : undefined, item.programa ? columns[item.programa].title : undefined, ...item.label.map((c) => c.label)], + guid: item.id, + pubDate: parseDate(item.release_time, ['MM月DD日', 'YYYY年MM月DD日']), })); items = await Promise.all( items.map((item) => ctx.cache.tryGet(item.link, async () => { - const detailResponse = await got({ - method: 'get', - url: item.link, + const { data: detailResponse } = await got(item.link); + + const { data: commentResponse } = await got.post(apiCommentUrl, { + news_id: item.guid, + page: 1, + limit: Infinity, + sort: 1, + delete_num: 0, }); - const content = cheerio.load(detailResponse.data); + const content = cheerio.load(detailResponse); - content('br').each(function () { - content(this).parent().remove(); - }); + item.title = item.title ?? content('div.article-header-title').text(); + item.description = content('#select-main') + .html() + .replace(/


<\/p>/g, ''); + item.author = content('div.article-header-author div.author-link a.label').first().text(); + item.category = item.category.filter((c) => c); + item.guid = `latepost-${item.guid}`; - const pubDate = content('.article-header-date').text(); - item.pubDate = timezone(/月|日/.test(pubDate) ? parseDate((/年/.test(pubDate) ? pubDate : `${new Date().getFullYear()}-${pubDate}`).replace(/年|月/g, '-').replace(/日/g, '')) : parseRelativeDate(pubDate), +8); + const pubDate = content('div.article-header-date').text(); - item.description = content('#select-main').html(); + if (pubDate) { + if (/\d+月\d+日/.test(pubDate)) { + item.pubDate = parseDate(pubDate, ['MM月DD日 HH:mm', 'YYYY年MM月DD日 HH:mm']); + } else { + item.pubDate = parseRelativeDate(pubDate); + } + } + + item.pubDate = timezone(item.pubDate, +8); + item.comments = commentResponse.data?.length() ?? 0; return item; }) ) ); + const icon = new URL('favicon.ico', rootUrl).href; + + const { data: currentResponse } = await got(currentUrl); + + const $ = cheerio.load(currentResponse); + ctx.state.data = { - title: `${titles[proma]} - 晚点`, - link: currentUrl, item: items, + title: `${title} - ${proma ? columns[proma].title : defaultTitle}`, + link: currentUrl, + description: $('div.logo-txt').first().text(), + language: 'zh-cn', + image: new URL($('div.logo-txt img').prop('src'), rootUrl).href, + icon, + logo: icon, + author: title, }; }; diff --git a/lib/v2/latepost/radar.js b/lib/v2/latepost/radar.js index 024874786ae2f7..6634bb61bc7830 100644 --- a/lib/v2/latepost/radar.js +++ b/lib/v2/latepost/radar.js @@ -6,7 +6,12 @@ module.exports = { title: '报道', docs: 'https://docs.rsshub.app/routes/new-media#wan-dian-latepost-bao-dao', source: '/', - target: (params, url) => `/latepost/${new URL(url).searchParams.get('proma')}`, + target: (params, url) => { + url = new URL(url); + const proma = url.searchParams.get('proma'); + + return `/latepost${proma ? `/${proma}` : ''}`; + }, }, ], }, diff --git a/lib/v2/latepost/router.js b/lib/v2/latepost/router.js index f0db9cf0e72522..9146b4202b1cec 100644 --- a/lib/v2/latepost/router.js +++ b/lib/v2/latepost/router.js @@ -1,3 +1,3 @@ module.exports = function (router) { - router.get('/:proma?', require('./index')); + router.get('/:proma?', require('./')); }; diff --git a/lib/v2/leetcode/articles.js b/lib/v2/leetcode/articles.js index 0ae6395b91b358..08055c20c14906 100644 --- a/lib/v2/leetcode/articles.js +++ b/lib/v2/leetcode/articles.js @@ -62,7 +62,7 @@ module.exports = async (ctx) => { const converter = new showdown.Converter(); const solution = converter.makeHtml(questionNote.data.question.solution.content); - info.description = questionData.data.question.content.trim() + solution; + info.description = questionData.data.question.content?.trim() + solution; info.pubDate = parseDate(info.pubDate); return info; diff --git a/lib/v2/newzmz/index.js b/lib/v2/newzmz/index.js index 2caaf1753c4c7c..1731b23f75a8ea 100644 --- a/lib/v2/newzmz/index.js +++ b/lib/v2/newzmz/index.js @@ -1,90 +1,66 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); -const { art } = require('@/utils/render'); -const path = require('path'); + +const { rootUrl, getItems, getItemInfo, processItems } = require('./util'); module.exports = async (ctx) => { - const category = ctx.params.category ? parseInt(ctx.params.category) : 1; + const { id = '1', downLinkType = '磁力链' } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 50; + + // If the id is not composed solely of digits, + // then consider it as the id of a movie or TV show; + // otherwise, consider it as the id for the category. + + const isCategory = !isNaN(id); - const rootUrl = 'http://newzmz.com'; - const rootSUrl = 'http://s.newzmz.com'; - const currentUrl = `${rootUrl}/index.html`; + const currentUrl = new URL(isCategory ? 'index.html' : `details-${id}.html`, rootUrl).href; - const response = await got({ - method: 'get', - url: currentUrl, + const response = await ctx.cache.tryGet(currentUrl, async () => { + const { data: response } = await got(currentUrl); + + return response; }); - const $ = cheerio.load(response.data); - - const items = []; - - const target = $('div.rowMod').eq(category); - - await Promise.all( - target - .find('ul.slides li a') - .toArray() - .map((item) => { - item = $(item); - - return { - title: item.text(), - link: `${rootSUrl}/view/${item.attr('href').split('/details-').pop()}`, - }; - }) - .map((item) => - ctx.cache.tryGet(item.link, async () => { - const detailResponse = await got({ - method: 'get', - url: item.link, - }); - - const content = cheerio.load(detailResponse.data); - - const title = content('.page-header-content').text(); - - items.push( - ...content('div.team-con-area') - .toArray() - .map((a) => { - a = content(a); - - const episode = a - .find('span.up') - .text() - .trim() - .replace(/第 (\d+) /g, '第$1'); - - return { - link: item.link, - guid: `${item.link}#${episode.replace(/\s*/g, '')}`, - title: `${title} ${episode}`, - category: a - .find('div.item-label a') - .toArray() - .map((l) => content(l).text()), - description: art(path.join(__dirname, 'templates/description.art'), { - links: a - .find('ul.team-icons li') - .toArray() - .map((i) => ({ - name: content(i).find('p').text(), - link: content(i).find('a').attr('href'), - })), - }), - enclosure_type: 'application/x-bittorrent', - enclosure_url: a.find('a[title="磁力链下载"]').attr('href'), - }; - }) - ); - }) - ) - ); + const $ = cheerio.load(response); + + // If a category id is specified, + // retrieve all movies and TV shows from that category + // and add them to the "to be processed" array. + // Otherwise, if only a specific TV show or movie ID is provided, + // add that item alone to the "to be processed" array. + + let items = isCategory + ? await getItems(ctx.cache.tryGet, currentUrl, id, 'div.rowMod', 'ul.slides li a') + : [ + { + link: currentUrl, + }, + ]; + + items = await Promise.all(items.slice(0, limit).map((item) => getItemInfo(ctx.cache.tryGet, item.link))); + + // If the link of the entry is "#", + // it indicates that there are currently no relevant resources available for that specific item. + + items = await Promise.all(items.filter((item) => item.link !== '#').map((i) => processItems(i, downLinkType, 'div.team-con-area', 'div.item-label a', 'ul.team-icons li'))); + + items = [].concat(...items); + + const headerTitle = isCategory ? $('div.rowMod').eq(parseInt(id, 10)).find('h2.row-header-title').text() : ''; + const title = `${$('title').text()}${headerTitle ? ` - ${headerTitle}` : ''}`; + const icon = $('link[rel="shortcut icon"]').prop('href'); ctx.state.data = { - title: `NEW字幕组 - ${target.find('.row-header-title').text()}`, + item: isCategory ? items : items.slice(0, limit), + title, link: currentUrl, - item: items, + description: $('meta[name="description"]').prop('content'), + language: 'zh-cn', + image: $('img.logo-img').prop('src'), + icon, + logo: icon, + subtitle: $('meta[name="keywords"]').prop('content'), + author: title, + allowEmpty: true, }; }; diff --git a/lib/v2/newzmz/maintainer.js b/lib/v2/newzmz/maintainer.js index b39b0bddcc811f..873c4f40e37437 100644 --- a/lib/v2/newzmz/maintainer.js +++ b/lib/v2/newzmz/maintainer.js @@ -1,4 +1,4 @@ module.exports = { - '/:category?': ['nczitzk'], - '/:id?': ['nczitzk'], + '/:category?/:downLinkType?': ['nczitzk'], + '/:id?/:downLinkType?': ['nczitzk'], }; diff --git a/lib/v2/newzmz/router.js b/lib/v2/newzmz/router.js index 81adfde3bacfd4..ec2e677cfcf6ea 100644 --- a/lib/v2/newzmz/router.js +++ b/lib/v2/newzmz/router.js @@ -1,5 +1,3 @@ module.exports = (router) => { - router.get(/\/(\d+)?/, require('./index')); - router.get('/view/:id', require('./view')); - router.get('/:id', require('./view')); + router.get('/:id?/:downLinkType?', require('./')); }; diff --git a/lib/v2/newzmz/templates/description.art b/lib/v2/newzmz/templates/description.art index 7ff8be92dad15c..6ea2ee5821c999 100644 --- a/lib/v2/newzmz/templates/description.art +++ b/lib/v2/newzmz/templates/description.art @@ -1,7 +1,59 @@ -{{ if links }} -

-{{ /if }} \ No newline at end of file +{{ if image }} +
+ {{ nameZh }}{{ if nameEn }} - {{ nameEn }}{{ /if }} +
+{{ /if }} + + + {{ if nameZh }} + + + + + {{ /if }} + {{ if nameEn }} + + + + + {{ /if }} + {{ if alias }} + + + + + {{ /if }} + {{ if update }} + + + + + {{ /if }} + {{ if links }} + {{ each links link }} + + + + + {{ /each }} + {{ /if }} + {{ if categories }} + + + + + {{ /if }} + {{ if downLinks }} + {{ each downLinks link }} + + + + + {{ /each }} + {{ /if }} + +
中文名{{ nameZh }}
英文名{{ nameEn }}
又名{{ alias.join(' / ') }}
更新频率{{ update }}
{{ link.title }} + {{ link.link }} +
标签{{ categories.join(' / ') }}
{{ link.title }} + {{ link.link }} +
\ No newline at end of file diff --git a/lib/v2/newzmz/util.js b/lib/v2/newzmz/util.js new file mode 100644 index 00000000000000..e936f038b4d185 --- /dev/null +++ b/lib/v2/newzmz/util.js @@ -0,0 +1,166 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const rootUrl = 'https://nzmz.xyz'; + +/** + * Retrieve all movies and TV shows under a specified category on the homepage and obtain their detail links. + * @param {function} tryGet - ctx.cache.tryGet + * @param {string} homeUrl - Homepage URL + * @param {string} id - Category id + * @param {string} modSelector - Selector for mods + * @param {string} itemSelector - Selector for items + * @returns {Array} An array containing the links in the map. + */ +const getItems = async (tryGet, homeUrl, id, modSelector, itemSelector) => { + const response = await tryGet(homeUrl, async () => { + const { data: response } = await got(homeUrl); + + return response; + }); + + const $ = cheerio.load(response); + + return $(modSelector) + .eq(parseInt(id, 10)) + .find(itemSelector) + .toArray() + .map((item) => { + item = $(item); + + return { + link: new URL(item.prop('href'), rootUrl).href, + }; + }); +}; + +/** + * Obtain the information corresponding to a given movie or TV show item based on the provided URL. + * @param {function} tryGet - ctx.cache.tryGet + * @param {string} itemUrl - Item URL + * @returns {Object} An object containing information of the item. + */ +const getItemInfo = (tryGet, itemUrl) => + tryGet(`newzmz#${itemUrl.match(/details-(.*?)\.html/)[1]}`, async () => { + const { data: detailResponse } = await got(itemUrl); + + const content = cheerio.load(detailResponse); + + const nameZh = content('div.chsname').text(); + const nameEn = content('div.engname').text(); + const alias = content('div.aliasname') + .text() + .replace(/又名:/, '') + .split('/') + .map((a) => a.trim()) + .filter((a) => a); + + const link = content('a.addgz').prop('href'); + + return { + link, + pubDate: parseDate( + content('span.duration') + .first() + .text() + .match(/(\d{4}-\d{2}-\d{2})/)[1] + ), + description: { + image: content('div.details-bg img').prop('src'), + nameZh, + nameEn, + alias, + update: content('span.upday').text(), + links: content('div.ep-infos a[title]') + .toArray() + .map((a) => { + a = content(a); + + return { + title: a.prop('title'), + link: a.prop('href'), + }; + }), + }, + author: content('ul.sws-list') + .first() + .find('h5.title') + .toArray() + .map((a) => content(a).text()) + .join(' / '), + category: [].concat(nameZh, nameEn, alias), + }; + }); + +/** + * Retrieve all the episode items from the corresponding download page of a movie or TV show. + * @param {Object} i - Preprocessed item object + * @param {string} downLinkType - Type of download link, with the default value being `磁力链`. The website provides various types of download links, including but not limited to `磁力链`, `百度网盘`, `阿里云盘`, `夸克网盘`, `UC网盘`, and more. If the specified download link type cannot be found, the first download link will be returned instead. + * @param {string} itemSelector - Selector for items + * @param {string} categorySelector - Selector for categories + * @param {string} downLinkSelector - Selector for download links + * @returns {Array} An array containing RSS feed objects in the map. + */ +const processItems = async (i, downLinkType, itemSelector, categorySelector, downLinkSelector) => { + const { data: detailResponse } = await got(i.link); + + const content = cheerio.load(detailResponse); + + return content(itemSelector) + .toArray() + .map((item) => { + item = content(item); + + const categories = item + .find(categorySelector) + .toArray() + .map((c) => content(c).text()); + + const downLinks = item + .find(downLinkSelector) + .toArray() + .map((downLink) => { + downLink = content(downLink); + + return { + title: downLink.find('p.link-name').text(), + link: downLink.find('a[title]').prop('href'), + }; + }); + + const subtitle = item + .find('span.up') + .text() + .replace(/[\s-]+/g, ''); + const title = `${i.description.nameZh || i.description.nameEn}|${subtitle}`; + const guid = `newzmz#${i.link.match(/view\/(.*?)\.html/)[1]}-${subtitle}`; + + return { + guid, + title, + link: i.link, + description: art(path.join(__dirname, 'templates/description.art'), { + ...i.description, + ...{ + categories, + downLinks, + }, + }), + author: i.author, + category: [...i.category, ...categories].filter((c) => c), + pubDate: i.pubDate, + enclosure_url: downLinks.filter((l) => l.title === downLinkType).pop()?.link ?? downLinks[0].link, + enclosure_type: 'application/x-bittorrent', + }; + }); +}; + +module.exports = { + rootUrl, + getItems, + getItemInfo, + processItems, +}; diff --git a/lib/v2/newzmz/view.js b/lib/v2/newzmz/view.js deleted file mode 100644 index 48f9d0753b0db0..00000000000000 --- a/lib/v2/newzmz/view.js +++ /dev/null @@ -1,57 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { art } = require('@/utils/render'); -const path = require('path'); - -module.exports = async (ctx) => { - const id = ctx.params.id; - - const rootUrl = `https://s.newzmz.com`; - const currentUrl = `${rootUrl}/view/${id}.html`; - - const response = await got({ - method: 'get', - url: currentUrl, - }); - - const $ = cheerio.load(response.data); - - const items = $('div.team-con-area') - .toArray() - .map((item) => { - item = $(item); - - const episode = item - .find('span.up') - .text() - .trim() - .replace(/第 (\d+) /g, '第$1'); - - return { - link: currentUrl, - guid: `${currentUrl}#${episode.replace(/\s*/g, '')}`, - title: episode, - category: item - .find('div.item-label a') - .toArray() - .map((l) => $(l).text()), - description: art(path.join(__dirname, 'templates/description.art'), { - links: item - .find('ul.team-icons li') - .toArray() - .map((i) => ({ - name: $(i).find('p').text(), - link: $(i).find('a').attr('href'), - })), - }), - enclosure_type: 'application/x-bittorrent', - enclosure_url: item.find('a[title="磁力链下载"]').attr('href'), - }; - }); - - ctx.state.data = { - title: `NEW字幕组 - ${$('.page-header-content').text()}`, - link: currentUrl, - item: items, - }; -}; diff --git a/lib/routes/tophub/index.js b/lib/v2/tophub/index.js similarity index 56% rename from lib/routes/tophub/index.js rename to lib/v2/tophub/index.js index 114703b9954b5b..c00a3e7fce6eb3 100644 --- a/lib/routes/tophub/index.js +++ b/lib/v2/tophub/index.js @@ -1,24 +1,30 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); +const config = require('@/config').value; module.exports = async (ctx) => { const id = ctx.params.id; const link = `https://tophub.today/n/${id}`; - const response = await got.get(link); + const response = await got.get(link, { + headers: { + Referer: 'https://tophub.today', + Cookie: config.tophub.cookie, + }, + }); const $ = cheerio.load(response.data); const title = $('div.Xc-ec-L.b-L').text().trim(); const out = $('div.Zd-p-Sc > div:nth-child(1) tr') - .map(function () { + .toArray() + .map((e) => { const info = { - title: $(this).find('td.al a').text(), - link: $(this).find('td.al a').attr('href'), + title: $(e).find('td.al a').text(), + link: $(e).find('td.al a').attr('href'), }; return info; - }) - .get(); + }); ctx.state.data = { title, diff --git a/lib/v2/tophub/maintainer.js b/lib/v2/tophub/maintainer.js new file mode 100644 index 00000000000000..fdeacdedf4ddd9 --- /dev/null +++ b/lib/v2/tophub/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:id': ['LogicJake'], +}; diff --git a/lib/v2/tophub/radar.js b/lib/v2/tophub/radar.js new file mode 100644 index 00000000000000..0b03042245bb19 --- /dev/null +++ b/lib/v2/tophub/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'tophub.today': { + _name: '今日热榜', + '.': [ + { + title: '榜单', + docs: 'https://docs.rsshub.app/routes/new-media#jin-ri-re-bang-bang-dan', + source: ['/n/:id'], + target: '/tophub/:id', + }, + ], + }, +}; diff --git a/lib/v2/tophub/router.js b/lib/v2/tophub/router.js new file mode 100644 index 00000000000000..b0440f0cdbf7c9 --- /dev/null +++ b/lib/v2/tophub/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:id', require('./')); +}; diff --git a/lib/v2/zhihu/maintainer.js b/lib/v2/zhihu/maintainer.js index 4464fafd0bb68a..b7071060b10780 100644 --- a/lib/v2/zhihu/maintainer.js +++ b/lib/v2/zhihu/maintainer.js @@ -15,6 +15,9 @@ module.exports = { '/timeline': ['SeanChao'], '/topic/:topicId': ['xyqfer'], '/weekly': ['LogicJake'], + '/xhu/collection/:id': ['JimenezLi'], + '/xhu/question/:questionId/:sortBy?': ['JimenezLi'], '/xhu/topic/:topicId': ['JimenezLi'], + '/xhu/zhuanlan/:id': ['JimenezLi'], '/zhuanlan/:id': ['DIYgod'], }; diff --git a/lib/v2/zhihu/radar.js b/lib/v2/zhihu/radar.js index 58ee8010483ded..ed051f7cb117c4 100644 --- a/lib/v2/zhihu/radar.js +++ b/lib/v2/zhihu/radar.js @@ -80,12 +80,30 @@ module.exports = { source: '/column/:id', target: '/zhihu/zhuanlan/:id', }, + { + title: 'xhu - 收藏夹', + docs: 'https://docs.rsshub.app/routes/social-media#zhi-hu', + source: '/collection/:id', + target: '/zhihu/xhu/collection/:id', + }, + { + title: 'xhu - 问题', + docs: 'https://docs.rsshub.app/routes/social-media#zhi-hu', + source: '/question/:questionId', + target: '/zhihu/xhu/question/:questionId', + }, { title: 'xhu - 话题', docs: 'https://docs.rsshub.app/routes/social-media#zhi-hu', source: '/topic/:topicId/:type', target: '/zhihu/xhu/topic/:topicId', }, + { + title: 'xhu - 专栏', + docs: 'https://docs.rsshub.app/routes/social-media#zhi-hu', + source: '/column/:id', + target: '/zhihu/xhu/zhuanlan/:id', + }, ], zhuanlan: [ { diff --git a/lib/v2/zhihu/router.js b/lib/v2/zhihu/router.js index 293704cbacb576..4e09cd9f79ffaf 100644 --- a/lib/v2/zhihu/router.js +++ b/lib/v2/zhihu/router.js @@ -15,6 +15,9 @@ module.exports = (router) => { router.get('/timeline', require('./timeline')); router.get('/topic/:topicId', require('./topic')); router.get('/weekly', require('./weekly')); + router.get('/xhu/collection/:id', require('./xhu/collection')); + router.get('/xhu/question/:questionId/:sortBy?', require('./xhu/question')); router.get('/xhu/topic/:topicId', require('./xhu/topic')); + router.get('/xhu/zhuanlan/:id', require('./xhu/zhuanlan')); router.get('/zhuanlan/:id', require('./zhuanlan')); }; diff --git a/lib/v2/zhihu/xhu/collection.js b/lib/v2/zhihu/xhu/collection.js new file mode 100644 index 00000000000000..1047cd870bede5 --- /dev/null +++ b/lib/v2/zhihu/xhu/collection.js @@ -0,0 +1,64 @@ +const got = require('@/utils/got'); +const auth = require('./auth'); +const { generateData } = require('../pin/utils'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const xhuCookie = await auth.getCookie(ctx); + const id = ctx.params.id; + const link = `https://www.zhihu.com/collection/${id}`; + + const titleResponse = await got({ + method: 'get', + url: `https://api.zhihuvvv.workers.dev/collections/${id}`, + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: xhuCookie, + }, + }); + + const contentResponse = await got({ + method: 'get', + url: `https://api.zhihuvvv.workers.dev/collections/${id}/contents?limit=20&offset=0`, + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: xhuCookie, + }, + }); + const listRes = contentResponse.data.data; + + ctx.state.data = { + title: `知乎收藏夹-${titleResponse.data.title}`, + description: titleResponse.data.description, + link, + item: listRes.map((item) => { + const link = item.url; + const author = item.author.name; + const pubDate = parseDate(item.collect_time * 1000); + let title = ''; + let description = ''; + + // This API gets only article, answer and pin, not zvideo + if (item.type === 'article') { + title = item.title; + description = item.excerpt; + } else if (item.type === 'answer') { + title = item.question.title; + description = item.excerpt; + } else if (item.type === 'pin') { + const pinItem = generateData([item])[0]; + title = pinItem.title; + description = pinItem.description; + } + + return { + title: `收藏了内容:${title}`, + description, + author, + pubDate, + guid: link, + link, + }; + }), + }; +}; diff --git a/lib/v2/zhihu/xhu/question.js b/lib/v2/zhihu/xhu/question.js new file mode 100644 index 00000000000000..5cd94b2962dc15 --- /dev/null +++ b/lib/v2/zhihu/xhu/question.js @@ -0,0 +1,44 @@ +const got = require('@/utils/got'); +const auth = require('./auth'); +const utils = require('../utils'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const xhuCookie = await auth.getCookie(ctx); + const { + questionId, + sortBy = 'default', // default,created,updated + } = ctx.params; + const link = `https://www.zhihu.com/question/${questionId}`; + const url = `https://api.zhihuvvv.workers.dev/questions/${questionId}/answers?limit=20&offest=0&order_by=${sortBy}`; + + const response = await got({ + method: 'get', + url, + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: xhuCookie, + }, + }); + const listRes = response.data.data; + + ctx.state.data = { + title: `知乎-${listRes[0].question.title}`, + link, + item: listRes.map((item) => { + const link = `https://www.zhihu.com/question/${questionId}/answer/${item.id}`; + const author = item.author.name; + const title = `${author}的回答:${item.excerpt}`; + const description = `${author}的回答

${utils.ProcessImage(item.excerpt)}`; + + return { + title, + description, + author, + pubDate: parseDate(item.updated_time * 1000), + guid: link, + link, + }; + }), + }; +}; diff --git a/lib/v2/zhihu/xhu/topic.js b/lib/v2/zhihu/xhu/topic.js index b9ccd767fafa6a..47c6125206df5a 100644 --- a/lib/v2/zhihu/xhu/topic.js +++ b/lib/v2/zhihu/xhu/topic.js @@ -7,15 +7,11 @@ module.exports = async (ctx) => { const xhuCookie = await auth.getCookie(ctx); const { topicId } = ctx.params; const link = `https://www.zhihu.com/topic/${topicId}/newest`; - const url = `https://api.zhihuvvv.workers.dev/topics/${topicId}/feeds/timeline_activity`; + const url = `https://api.zhihuvvv.workers.dev/topics/${topicId}/feeds/timeline_activity?before_id=0&limit=20`; const response = await got({ method: 'get', url, - searchParams: { - before_id: 0, - limit: 20, - }, headers: { Referer: 'https://api.zhihuvvv.workers.dev', Cookie: xhuCookie, diff --git a/lib/v2/zhihu/xhu/zhuanlan.js b/lib/v2/zhihu/xhu/zhuanlan.js new file mode 100644 index 00000000000000..edb65fc213f417 --- /dev/null +++ b/lib/v2/zhihu/xhu/zhuanlan.js @@ -0,0 +1,83 @@ +const got = require('@/utils/got'); +const auth = require('./auth'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const xhuCookie = await auth.getCookie(ctx); + const id = ctx.params.id; + const link = `https://www.zhihu.com/column/${id}`; + + const titleResponse = await got({ + method: 'get', + url: `https://api.zhihuvvv.workers.dev/columns/${id}`, + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: xhuCookie, + }, + }); + + const contentResponse = await got({ + method: 'get', + url: `https://api.zhihuvvv.workers.dev/columns/${id}/articles?limit=20&offest=0`, + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: xhuCookie, + }, + }); + + const listRes = contentResponse.data.data; + + ctx.state.data = { + title: `知乎专栏-${titleResponse.data.title}`, + description: titleResponse.data.description, + link, + item: listRes.map((item) => { + let description = ''; + if (item.content) { + const $ = cheerio.load(item.content); + $('img').css('max-width', '100%'); + description = $.html(); + } + + let title = ''; + let link = ''; + let author = ''; + let pubDate; + + // The xhu api only get items of type article. + if (item.type === 'article') { + title = item.title; + link = item.url; + author = item.author.name; + pubDate = parseDate(item.created * 1000); + } else if (item.type === 'answer') { + title = item.question.title; + author = item.question.author ? item.question.author.name : ''; + link = `https://www.zhihu.com/question/${item.question.id}/answer/${item.id}`; + pubDate = parseDate(item.created_time * 1000); + } else if (item.type === 'zvideo') { + // 如果类型是zvideo,id即为视频地址参数 + title = item.title; + link = `https://www.zhihu.com/zvideo/${item.id}`; + author = item.author.name; + pubDate = parseDate(item.created_at * 1000); + // 判断是否存在视频简介 + if (item.description) { + description = `${item.description}

视频内容请跳转至原页面观看`; + } else { + description = `视频内容请跳转至原页面观看`; + } + } + + return { + title, + description, + author, + pubDate, + guid: link, + link, + }; + }), + }; +}; diff --git a/package.json b/package.json index 794cac2145267d..843844fd3e4615 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "art-template": "4.13.2", "bbcodejs": "0.0.4", "cheerio": "1.0.0-rc.12", - "chrono-node": "2.6.4", + "chrono-node": "2.6.5", "city-timezones": "1.2.1", "crypto-js": "4.1.1", "currency-symbol-map": "5.1.0", @@ -134,7 +134,7 @@ "puppeteer-extra-plugin-user-preferences": "2.4.1", "query-string": "7.1.3", "rand-user-agent": "1.0.109", - "re2js": "0.3.2", + "re2js": "0.3.3", "require-all": "3.0.0", "rfc4648": "1.5.2", "rss-parser": "3.13.0", @@ -154,14 +154,14 @@ "cross-env": "7.0.3", "eslint": "8.47.0", "eslint-config-prettier": "9.0.0", - "eslint-plugin-n": "16.0.1", + "eslint-plugin-n": "16.0.2", "eslint-plugin-prettier": "5.0.0", "eslint-plugin-yml": "1.8.0", "fs-extra": "11.1.1", "husky": "8.0.3", - "jest": "29.6.2", + "jest": "29.6.3", "jest-junit": "16.0.0", - "lint-staged": "14.0.0", + "lint-staged": "14.0.1", "mockdate": "3.0.5", "nock": "13.3.3", "nodemon": "3.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44fc9d4215389c..c77f9ac33ab62f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,8 +30,8 @@ dependencies: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 chrono-node: - specifier: 2.6.4 - version: 2.6.4 + specifier: 2.6.5 + version: 2.6.5 city-timezones: specifier: 1.2.1 version: 1.2.1 @@ -159,8 +159,8 @@ dependencies: specifier: 1.0.109 version: 1.0.109 re2js: - specifier: 0.3.2 - version: 0.3.2 + specifier: 0.3.3 + version: 0.3.3 require-all: specifier: 3.0.0 version: 3.0.0 @@ -215,8 +215,8 @@ devDependencies: specifier: 9.0.0 version: 9.0.0(eslint@8.47.0) eslint-plugin-n: - specifier: 16.0.1 - version: 16.0.1(eslint@8.47.0) + specifier: 16.0.2 + version: 16.0.2(eslint@8.47.0) eslint-plugin-prettier: specifier: 5.0.0 version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.47.0)(prettier@3.0.2) @@ -230,14 +230,14 @@ devDependencies: specifier: 8.0.3 version: 8.0.3 jest: - specifier: 29.6.2 - version: 29.6.2 + specifier: 29.6.3 + version: 29.6.3 jest-junit: specifier: 16.0.0 version: 16.0.0 lint-staged: - specifier: 14.0.0 - version: 14.0.0 + specifier: 14.0.1 + version: 14.0.1 mockdate: specifier: 3.0.5 version: 3.0.5 @@ -662,8 +662,8 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp@4.6.2: - resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} + /@eslint-community/regexpp@4.7.0: + resolution: {integrity: sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true @@ -674,7 +674,7 @@ packages: ajv: 6.12.6 debug: 4.3.4 espree: 9.6.1 - globals: 13.20.0 + globals: 13.21.0 ignore: 5.2.4 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -729,20 +729,20 @@ packages: engines: {node: '>=8'} dev: true - /@jest/console@29.6.2: - resolution: {integrity: sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w==} + /@jest/console@29.6.3: + resolution: {integrity: sha512-ukZbHAdDH4ktZIOKvWs1juAXhiVAdvCyM8zv4S/7Ii3vJSDvMW5k+wOVGMQmHLHUFw3Ko63ZQNy7NI6PSlsD5w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 chalk: 4.1.2 - jest-message-util: 29.6.2 - jest-util: 29.6.2 + jest-message-util: 29.6.3 + jest-util: 29.6.3 slash: 3.0.0 dev: true - /@jest/core@29.6.2: - resolution: {integrity: sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg==} + /@jest/core@29.6.3: + resolution: {integrity: sha512-skV1XrfNxfagmjRUrk2FyN5/2YwIzdWVVBa/orUfbLvQUANXxERq2pTvY0I+FinWHjDKB2HRmpveUiph4X0TJw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -750,32 +750,32 @@ packages: node-notifier: optional: true dependencies: - '@jest/console': 29.6.2 - '@jest/reporters': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/console': 29.6.3 + '@jest/reporters': 29.6.3 + '@jest/test-result': 29.6.3 + '@jest/transform': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.8.0 exit: 0.1.2 graceful-fs: 4.2.11 - jest-changed-files: 29.5.0 - jest-config: 29.6.2(@types/node@20.4.9) - jest-haste-map: 29.6.2 - jest-message-util: 29.6.2 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.2 - jest-resolve-dependencies: 29.6.2 - jest-runner: 29.6.2 - jest-runtime: 29.6.2 - jest-snapshot: 29.6.2 - jest-util: 29.6.2 - jest-validate: 29.6.2 - jest-watcher: 29.6.2 + jest-changed-files: 29.6.3 + jest-config: 29.6.3(@types/node@20.5.3) + jest-haste-map: 29.6.3 + jest-message-util: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.3 + jest-resolve-dependencies: 29.6.3 + jest-runner: 29.6.3 + jest-runtime: 29.6.3 + jest-snapshot: 29.6.3 + jest-util: 29.6.3 + jest-validate: 29.6.3 + jest-watcher: 29.6.3 micromatch: 4.0.5 - pretty-format: 29.6.2 + pretty-format: 29.6.3 slash: 3.0.0 strip-ansi: 6.0.1 transitivePeerDependencies: @@ -784,59 +784,59 @@ packages: - ts-node dev: true - /@jest/environment@29.6.2: - resolution: {integrity: sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q==} + /@jest/environment@29.6.3: + resolution: {integrity: sha512-u/u3cCztYCfgBiGHsamqP5x+XvucftOGPbf5RJQxfpeC1y4AL8pCjKvPDA3oCmdhZYPgk5AE0VOD/flweR69WA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/fake-timers': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 - jest-mock: 29.6.2 + '@jest/fake-timers': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 + jest-mock: 29.6.3 dev: true - /@jest/expect-utils@29.6.2: - resolution: {integrity: sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg==} + /@jest/expect-utils@29.6.3: + resolution: {integrity: sha512-nvOEW4YoqRKD9HBJ9OJ6przvIvP9qilp5nAn1462P5ZlL/MM9SgPEZFyjTGPfs7QkocdUsJa6KjHhyRn4ueItA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-get-type: 29.4.3 + jest-get-type: 29.6.3 dev: true - /@jest/expect@29.6.2: - resolution: {integrity: sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg==} + /@jest/expect@29.6.3: + resolution: {integrity: sha512-Ic08XbI2jlg6rECy+CGwk/8NDa6VE7UmIG6++9OTPAMnQmNGY28hu69Nf629CWv6T7YMODLbONxDFKdmQeI9FA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - expect: 29.6.2 - jest-snapshot: 29.6.2 + expect: 29.6.3 + jest-snapshot: 29.6.3 transitivePeerDependencies: - supports-color dev: true - /@jest/fake-timers@29.6.2: - resolution: {integrity: sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA==} + /@jest/fake-timers@29.6.3: + resolution: {integrity: sha512-pa1wmqvbj6eX0nMvOM2VDAWvJOI5A/Mk3l8O7n7EsAh71sMZblaKO9iT4GjIj0LwwK3CP/Jp1ypEV0x3m89RvA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 + '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.4.9 - jest-message-util: 29.6.2 - jest-mock: 29.6.2 - jest-util: 29.6.2 + '@types/node': 20.5.3 + jest-message-util: 29.6.3 + jest-mock: 29.6.3 + jest-util: 29.6.3 dev: true - /@jest/globals@29.6.2: - resolution: {integrity: sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw==} + /@jest/globals@29.6.3: + resolution: {integrity: sha512-RB+uI+CZMHntzlnOPlll5x/jgRff3LEPl/td/jzMXiIgR0iIhKq9qm1HLU+EC52NuoVy/1swit/sDGjVn4bc6A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.6.2 - '@jest/expect': 29.6.2 - '@jest/types': 29.6.1 - jest-mock: 29.6.2 + '@jest/environment': 29.6.3 + '@jest/expect': 29.6.3 + '@jest/types': 29.6.3 + jest-mock: 29.6.3 transitivePeerDependencies: - supports-color dev: true - /@jest/reporters@29.6.2: - resolution: {integrity: sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw==} + /@jest/reporters@29.6.3: + resolution: {integrity: sha512-kGz59zMi0GkVjD2CJeYWG9k6cvj7eBqt9aDAqo2rcCLRTYlvQ62Gu/n+tOmJMBHGjzeijjuCENjzTyYBgrtLUw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -845,25 +845,25 @@ packages: optional: true dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 + '@jest/console': 29.6.3 + '@jest/test-result': 29.6.3 + '@jest/transform': 29.6.3 + '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.19 - '@types/node': 20.4.9 + '@types/node': 20.5.3 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 + istanbul-lib-instrument: 6.0.0 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.1.6 - jest-message-util: 29.6.2 - jest-util: 29.6.2 - jest-worker: 29.6.2 + jest-message-util: 29.6.3 + jest-util: 29.6.3 + jest-worker: 29.6.3 slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 @@ -872,15 +872,15 @@ packages: - supports-color dev: true - /@jest/schemas@29.6.0: - resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==} + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@sinclair/typebox': 0.27.8 dev: true - /@jest/source-map@29.6.0: - resolution: {integrity: sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==} + /@jest/source-map@29.6.3: + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jridgewell/trace-mapping': 0.3.19 @@ -888,41 +888,41 @@ packages: graceful-fs: 4.2.11 dev: true - /@jest/test-result@29.6.2: - resolution: {integrity: sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw==} + /@jest/test-result@29.6.3: + resolution: {integrity: sha512-k7ZZaNvOSMBHPZYiy0kuiaFoyansR5QnTwDux1EjK3kD5iWpRVyJIJ0RAIV39SThafchuW59vra7F8mdy5Hfgw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/console': 29.6.2 - '@jest/types': 29.6.1 + '@jest/console': 29.6.3 + '@jest/types': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 collect-v8-coverage: 1.0.2 dev: true - /@jest/test-sequencer@29.6.2: - resolution: {integrity: sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw==} + /@jest/test-sequencer@29.6.3: + resolution: {integrity: sha512-/SmijaAU2TY9ComFGIYa6Z+fmKqQMnqs2Nmwb0P/Z/tROdZ7M0iruES1EaaU9PBf8o9uED5xzaJ3YPFEIcDgAg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.6.2 + '@jest/test-result': 29.6.3 graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 + jest-haste-map: 29.6.3 slash: 3.0.0 dev: true - /@jest/transform@29.6.2: - resolution: {integrity: sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==} + /@jest/transform@29.6.3: + resolution: {integrity: sha512-dPIc3DsvMZ/S8ut4L2ViCj265mKO0owB0wfzBv2oGzL9pQ+iRvJewHqLBmsGb7XFb5UotWIEtvY5A/lnylaIoQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.22.10 - '@jest/types': 29.6.1 + '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.19 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - jest-regex-util: 29.4.3 - jest-util: 29.6.2 + jest-haste-map: 29.6.3 + jest-regex-util: 29.6.3 + jest-util: 29.6.3 micromatch: 4.0.5 pirates: 4.0.6 slash: 3.0.0 @@ -931,14 +931,14 @@ packages: - supports-color dev: true - /@jest/types@29.6.1: - resolution: {integrity: sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==} + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 29.6.0 + '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.4.9 + '@types/node': 20.5.3 '@types/yargs': 17.0.24 chalk: 4.1.2 dev: true @@ -994,7 +994,7 @@ packages: detect-libc: 2.0.2 https-proxy-agent: 5.0.1 make-dir: 3.1.0 - node-fetch: 2.6.12 + node-fetch: 2.6.13 nopt: 5.0.0 npmlog: 5.0.1 rimraf: 3.0.2 @@ -1043,7 +1043,7 @@ packages: engines: {node: '>=12'} dependencies: '@types/node-fetch': 2.6.4 - node-fetch: 2.6.12 + node-fetch: 2.6.13 transitivePeerDependencies: - encoding dev: false @@ -1057,7 +1057,7 @@ packages: is-glob: 4.0.3 open: 9.1.0 picocolors: 1.0.0 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /@postlight/ci-failed-test-reporter@1.0.26: @@ -1065,7 +1065,7 @@ packages: hasBin: true dependencies: dotenv: 6.2.0 - node-fetch: 2.6.12 + node-fetch: 2.6.13 transitivePeerDependencies: - encoding dev: false @@ -1160,7 +1160,7 @@ packages: '@sentry/core': 7.64.0 '@sentry/types': 7.64.0 '@sentry/utils': 7.64.0 - tslib: 2.6.1 + tslib: 2.6.2 dev: false /@sentry/core@7.64.0: @@ -1169,7 +1169,7 @@ packages: dependencies: '@sentry/types': 7.64.0 '@sentry/utils': 7.64.0 - tslib: 2.6.1 + tslib: 2.6.2 dev: false /@sentry/node@7.64.0: @@ -1183,7 +1183,7 @@ packages: cookie: 0.4.2 https-proxy-agent: 5.0.1 lru_map: 0.3.3 - tslib: 2.6.1 + tslib: 2.6.2 transitivePeerDependencies: - supports-color dev: false @@ -1198,7 +1198,7 @@ packages: engines: {node: '>=8'} dependencies: '@sentry/types': 7.64.0 - tslib: 2.6.1 + tslib: 2.6.2 dev: false /@sinclair/typebox@0.27.8: @@ -1246,7 +1246,7 @@ packages: /@types/accepts@1.3.5: resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/babel__core@7.20.1: @@ -1286,7 +1286,7 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/cacheable-request@6.0.3: @@ -1294,7 +1294,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 20.4.9 + '@types/node': 20.5.3 '@types/responselike': 1.0.0 dev: false @@ -1309,7 +1309,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/content-disposition@0.5.5: @@ -1322,7 +1322,7 @@ packages: '@types/connect': 3.4.35 '@types/express': 4.17.17 '@types/keygrip': 1.0.2 - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/debug@4.1.8: @@ -1331,10 +1331,10 @@ packages: '@types/ms': 0.7.31 dev: false - /@types/express-serve-static-core@4.17.35: - resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + /@types/express-serve-static-core@4.17.36: + resolution: {integrity: sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -1344,7 +1344,7 @@ packages: resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} dependencies: '@types/body-parser': 1.19.2 - '@types/express-serve-static-core': 4.17.35 + '@types/express-serve-static-core': 4.17.36 '@types/qs': 6.9.7 '@types/serve-static': 1.15.2 dev: true @@ -1352,7 +1352,7 @@ packages: /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/http-assert@1.5.3: @@ -1390,7 +1390,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: false /@types/koa-compose@3.2.5: @@ -1409,7 +1409,7 @@ packages: '@types/http-errors': 2.0.1 '@types/keygrip': 1.0.2 '@types/koa-compose': 3.2.5 - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/mdast@3.0.12: @@ -1433,12 +1433,12 @@ packages: /@types/node-fetch@2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 form-data: 3.0.1 dev: false - /@types/node@20.4.9: - resolution: {integrity: sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==} + /@types/node@20.5.3: + resolution: {integrity: sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==} /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} @@ -1459,7 +1459,7 @@ packages: resolution: {integrity: sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==} dependencies: '@types/caseless': 0.12.2 - '@types/node': 20.4.9 + '@types/node': 20.5.3 '@types/tough-cookie': 4.0.2 form-data: 2.5.1 dev: false @@ -1467,14 +1467,14 @@ packages: /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: false /@types/send@0.17.1: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/serve-static@1.15.2: @@ -1482,7 +1482,7 @@ packages: dependencies: '@types/http-errors': 2.0.1 '@types/mime': 3.0.1 - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: true /@types/stack-utils@2.0.1: @@ -1515,7 +1515,7 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 20.4.9 + '@types/node': 20.5.3 dev: false optional: true @@ -1724,7 +1724,7 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} dependencies: - tslib: 2.6.1 + tslib: 2.6.2 dev: false /async-sema@3.1.1: @@ -1748,17 +1748,17 @@ packages: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} dev: false - /babel-jest@29.6.2(@babel/core@7.22.10): - resolution: {integrity: sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==} + /babel-jest@29.6.3(@babel/core@7.22.10): + resolution: {integrity: sha512-1Ne93zZZEy5XmTa4Q+W5+zxBrDpExX8E3iy+xJJ+24ewlfo/T3qHfQJCzi/MMVFmBQDNxtRR/Gfd2dwb/0yrQw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: '@babel/core': 7.22.10 - '@jest/transform': 29.6.2 + '@jest/transform': 29.6.3 '@types/babel__core': 7.20.1 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0(@babel/core@7.22.10) + babel-preset-jest: 29.6.3(@babel/core@7.22.10) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -1779,8 +1779,8 @@ packages: - supports-color dev: true - /babel-plugin-jest-hoist@29.5.0: - resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} + /babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/template': 7.22.5 @@ -1809,14 +1809,14 @@ packages: '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.10) dev: true - /babel-preset-jest@29.5.0(@babel/core@7.22.10): - resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} + /babel-preset-jest@29.6.3(@babel/core@7.22.10): + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.22.10 - babel-plugin-jest-hoist: 29.5.0 + babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) dev: true @@ -1915,8 +1915,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001519 - electron-to-chromium: 1.4.490 + caniuse-lite: 1.0.30001522 + electron-to-chromium: 1.4.499 node-releases: 2.0.13 update-browserslist-db: 1.0.11(browserslist@4.21.10) dev: true @@ -2019,8 +2019,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001519: - resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} + /caniuse-lite@1.0.30001522: + resolution: {integrity: sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==} dev: true /caseless@0.12.0: @@ -2130,7 +2130,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /chownr@2.0.0: @@ -2147,8 +2147,8 @@ packages: mitt: 3.0.1 dev: false - /chrono-node@2.6.4: - resolution: {integrity: sha512-weCpfagfISvUMleIIqCi12AL9iQYn1ybX/6RB9qolynvHNvYlfdJete51uyB8TmwDTgEeKFEq0I5p/SHhOfhsw==} + /chrono-node@2.6.5: + resolution: {integrity: sha512-1B4iFd8xJ235PAprvRbs7zaEvmepOrN7dQ5UWjsXoDnlRP1vriGUwmcYw+KeQGKtz+YkgMo7bglf/q/l2VhoxQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: dayjs: 1.11.8 @@ -2382,7 +2382,7 @@ packages: /cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: - node-fetch: 2.6.12 + node-fetch: 2.6.13 transitivePeerDependencies: - encoding dev: false @@ -2618,8 +2618,8 @@ packages: wrappy: 1.0.2 dev: true - /diff-sequences@29.4.3: - resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true @@ -2733,8 +2733,8 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: false - /electron-to-chromium@1.4.490: - resolution: {integrity: sha512-6s7NVJz+sATdYnIwhdshx/N/9O6rvMxmhVoDSDFdj6iA45gHR8EQje70+RYsF4GeB+k0IeNSBnP7yG9ZXJFr7A==} + /electron-to-chromium@1.4.499: + resolution: {integrity: sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==} dev: true /ellipsize@0.1.0: @@ -2906,12 +2906,12 @@ packages: eslint: '>=8' dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0) - '@eslint-community/regexpp': 4.6.2 + '@eslint-community/regexpp': 4.7.0 eslint: 8.47.0 dev: true - /eslint-plugin-n@16.0.1(eslint@8.47.0): - resolution: {integrity: sha512-CDmHegJN0OF3L5cz5tATH84RPQm9kG+Yx39wIqIwPR2C0uhBGMWfbbOtetR83PQjjidA5aXMu+LEFw1jaSwvTA==} + /eslint-plugin-n@16.0.2(eslint@8.47.0): + resolution: {integrity: sha512-Y66uDfUNbBzypsr0kELWrIz+5skicECrLUqlWuXawNSLUq3ltGlCwu6phboYYOTSnoTdHgTLrc+5Ydo6KjzZog==} engines: {node: '>=16.0.0'} peerDependencies: eslint: '>=7.0.0' @@ -2982,7 +2982,7 @@ packages: hasBin: true dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0) - '@eslint-community/regexpp': 4.6.2 + '@eslint-community/regexpp': 4.7.0 '@eslint/eslintrc': 2.1.2 '@eslint/js': 8.47.0 '@humanwhocodes/config-array': 0.11.10 @@ -3003,7 +3003,7 @@ packages: file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.20.0 + globals: 13.21.0 graphemer: 1.4.0 ignore: 5.2.4 imurmurhash: 0.1.4 @@ -3111,16 +3111,15 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /expect@29.6.2: - resolution: {integrity: sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA==} + /expect@29.6.3: + resolution: {integrity: sha512-x1vY4LlEMWUYVZQrFi4ZANXFwqYbJ/JNQspLVvzhW2BNY28aNcXMQH6imBbt+RBf5sVRTodYHXtSP/TLEU0Dxw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/expect-utils': 29.6.2 - '@types/node': 20.4.9 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.6.2 - jest-message-util: 29.6.2 - jest-util: 29.6.2 + '@jest/expect-utils': 29.6.3 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.6.3 + jest-message-util: 29.6.3 + jest-util: 29.6.3 dev: true /extend@3.0.2: @@ -3163,8 +3162,8 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true - /fast-fifo@1.3.0: - resolution: {integrity: sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==} + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} dev: false /fast-glob@3.3.1: @@ -3381,8 +3380,8 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -3414,7 +3413,7 @@ packages: extend: 3.0.2 https-proxy-agent: 7.0.1 is-stream: 2.0.1 - node-fetch: 2.6.12 + node-fetch: 2.6.13 transitivePeerDependencies: - encoding - supports-color @@ -3519,8 +3518,8 @@ packages: engines: {node: '>=4'} dev: true - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + /globals@13.21.0: + resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -4201,6 +4200,19 @@ packages: - supports-color dev: true + /istanbul-lib-instrument@6.0.0: + resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.22.10 + '@babel/parser': 7.22.10 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} @@ -4229,35 +4241,36 @@ packages: istanbul-lib-report: 3.0.1 dev: true - /jest-changed-files@29.5.0: - resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} + /jest-changed-files@29.6.3: + resolution: {integrity: sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: execa: 5.1.1 + jest-util: 29.6.3 p-limit: 3.1.0 dev: true - /jest-circus@29.6.2: - resolution: {integrity: sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw==} + /jest-circus@29.6.3: + resolution: {integrity: sha512-p0R5YqZEMnOpHqHLWRSjm2z/0p6RNsrNE/GRRT3eli8QGOAozj6Ys/3Tv+Ej+IfltJoSPwcQ6/hOCRkNlxLLCw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.6.2 - '@jest/expect': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/environment': 29.6.3 + '@jest/expect': 29.6.3 + '@jest/test-result': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 is-generator-fn: 2.1.0 - jest-each: 29.6.2 - jest-matcher-utils: 29.6.2 - jest-message-util: 29.6.2 - jest-runtime: 29.6.2 - jest-snapshot: 29.6.2 - jest-util: 29.6.2 + jest-each: 29.6.3 + jest-matcher-utils: 29.6.3 + jest-message-util: 29.6.3 + jest-runtime: 29.6.3 + jest-snapshot: 29.6.3 + jest-util: 29.6.3 p-limit: 3.1.0 - pretty-format: 29.6.2 + pretty-format: 29.6.3 pure-rand: 6.0.2 slash: 3.0.0 stack-utils: 2.0.6 @@ -4266,8 +4279,8 @@ packages: - supports-color dev: true - /jest-cli@29.6.2: - resolution: {integrity: sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q==} + /jest-cli@29.6.3: + resolution: {integrity: sha512-KuPdXUPXQIf0t6DvmG8MV4QyhcjR1a6ruKl3YL7aGn/AQ8JkROwFkWzEpDIpt11Qy188dHbRm8WjwMsV/4nmnQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: @@ -4276,16 +4289,16 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/types': 29.6.1 + '@jest/core': 29.6.3 + '@jest/test-result': 29.6.3 + '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.1.0 - jest-config: 29.6.2(@types/node@20.4.9) - jest-util: 29.6.2 - jest-validate: 29.6.2 + jest-config: 29.6.3(@types/node@20.5.3) + jest-util: 29.6.3 + jest-validate: 29.6.3 prompts: 2.4.2 yargs: 17.7.2 transitivePeerDependencies: @@ -4295,8 +4308,8 @@ packages: - ts-node dev: true - /jest-config@29.6.2(@types/node@20.4.9): - resolution: {integrity: sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==} + /jest-config@29.6.3(@types/node@20.5.3): + resolution: {integrity: sha512-nb9bOq2aEqogbyL4F9mLkAeQGAgNt7Uz6U59YtQDIxFPiL7Ejgq0YIrp78oyEHD6H4CIV/k7mFrK7eFDzUJ69w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@types/node': '*' @@ -4308,26 +4321,26 @@ packages: optional: true dependencies: '@babel/core': 7.22.10 - '@jest/test-sequencer': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 - babel-jest: 29.6.2(@babel/core@7.22.10) + '@jest/test-sequencer': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 + babel-jest: 29.6.3(@babel/core@7.22.10) chalk: 4.1.2 ci-info: 3.8.0 deepmerge: 4.3.1 glob: 7.2.3 graceful-fs: 4.2.11 - jest-circus: 29.6.2 - jest-environment-node: 29.6.2 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.2 - jest-runner: 29.6.2 - jest-util: 29.6.2 - jest-validate: 29.6.2 + jest-circus: 29.6.3 + jest-environment-node: 29.6.3 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.3 + jest-runner: 29.6.3 + jest-util: 29.6.3 + jest-validate: 29.6.3 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.6.2 + pretty-format: 29.6.3 slash: 3.0.0 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -4335,68 +4348,68 @@ packages: - supports-color dev: true - /jest-diff@29.6.2: - resolution: {integrity: sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==} + /jest-diff@29.6.3: + resolution: {integrity: sha512-3sw+AdWnwH9sSNohMRKA7JiYUJSRr/WS6+sEFfBuhxU5V5GlEVKfvUn8JuMHE0wqKowemR1C2aHy8VtXbaV8dQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - diff-sequences: 29.4.3 - jest-get-type: 29.4.3 - pretty-format: 29.6.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.6.3 dev: true - /jest-docblock@29.4.3: - resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} + /jest-docblock@29.6.3: + resolution: {integrity: sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: detect-newline: 3.1.0 dev: true - /jest-each@29.6.2: - resolution: {integrity: sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw==} + /jest-each@29.6.3: + resolution: {integrity: sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 + '@jest/types': 29.6.3 chalk: 4.1.2 - jest-get-type: 29.4.3 - jest-util: 29.6.2 - pretty-format: 29.6.2 + jest-get-type: 29.6.3 + jest-util: 29.6.3 + pretty-format: 29.6.3 dev: true - /jest-environment-node@29.6.2: - resolution: {integrity: sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ==} + /jest-environment-node@29.6.3: + resolution: {integrity: sha512-PKl7upfPJXMYbWpD+60o4HP86KvFO2c9dZ+Zr6wUzsG5xcPx/65o3ArNgHW5M0RFvLYdW4/aieR4JSooD0a2ew==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.6.2 - '@jest/fake-timers': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 - jest-mock: 29.6.2 - jest-util: 29.6.2 + '@jest/environment': 29.6.3 + '@jest/fake-timers': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 + jest-mock: 29.6.3 + jest-util: 29.6.3 dev: true - /jest-get-type@29.4.3: - resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /jest-haste-map@29.6.2: - resolution: {integrity: sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==} + /jest-haste-map@29.6.3: + resolution: {integrity: sha512-GecR5YavfjkhOytEFHAeI6aWWG3f/cOKNB1YJvj/B76xAmeVjy4zJUYobGF030cRmKaO1FBw3V8CZZ6KVh9ZSw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 + '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.6 - '@types/node': 20.4.9 + '@types/node': 20.5.3 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 - jest-regex-util: 29.4.3 - jest-util: 29.6.2 - jest-worker: 29.6.2 + jest-regex-util: 29.6.3 + jest-util: 29.6.3 + jest-worker: 29.6.3 micromatch: 4.0.5 walker: 1.0.8 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /jest-junit@16.0.0: @@ -4409,49 +4422,49 @@ packages: xml: 1.0.1 dev: true - /jest-leak-detector@29.6.2: - resolution: {integrity: sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ==} + /jest-leak-detector@29.6.3: + resolution: {integrity: sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-get-type: 29.4.3 - pretty-format: 29.6.2 + jest-get-type: 29.6.3 + pretty-format: 29.6.3 dev: true - /jest-matcher-utils@29.6.2: - resolution: {integrity: sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==} + /jest-matcher-utils@29.6.3: + resolution: {integrity: sha512-6ZrMYINZdwduSt5Xu18/n49O1IgXdjsfG7NEZaQws9k69eTKWKcVbJBw/MZsjOZe2sSyJFmuzh8042XWwl54Zg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - jest-diff: 29.6.2 - jest-get-type: 29.4.3 - pretty-format: 29.6.2 + jest-diff: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.6.3 dev: true - /jest-message-util@29.6.2: - resolution: {integrity: sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ==} + /jest-message-util@29.6.3: + resolution: {integrity: sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/code-frame': 7.22.10 - '@jest/types': 29.6.1 + '@jest/types': 29.6.3 '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.5 - pretty-format: 29.6.2 + pretty-format: 29.6.3 slash: 3.0.0 stack-utils: 2.0.6 dev: true - /jest-mock@29.6.2: - resolution: {integrity: sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg==} + /jest-mock@29.6.3: + resolution: {integrity: sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 - '@types/node': 20.4.9 - jest-util: 29.6.2 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 + jest-util: 29.6.3 dev: true - /jest-pnp-resolver@1.2.3(jest-resolve@29.6.2): + /jest-pnp-resolver@1.2.3(jest-resolve@29.6.3): resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} engines: {node: '>=6'} peerDependencies: @@ -4460,100 +4473,100 @@ packages: jest-resolve: optional: true dependencies: - jest-resolve: 29.6.2 + jest-resolve: 29.6.3 dev: true - /jest-regex-util@29.4.3: - resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} + /jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /jest-resolve-dependencies@29.6.2: - resolution: {integrity: sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w==} + /jest-resolve-dependencies@29.6.3: + resolution: {integrity: sha512-iah5nhSPTwtUV7yzpTc9xGg8gP3Ch2VNsuFMsKoCkNCrQSbFtx5KRPemmPJ32AUhTSDqJXB6djPN6zAaUGV53g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-regex-util: 29.4.3 - jest-snapshot: 29.6.2 + jest-regex-util: 29.6.3 + jest-snapshot: 29.6.3 transitivePeerDependencies: - supports-color dev: true - /jest-resolve@29.6.2: - resolution: {integrity: sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw==} + /jest-resolve@29.6.3: + resolution: {integrity: sha512-WMXwxhvzDeA/J+9jz1i8ZKGmbw/n+s988EiUvRI4egM+eTn31Hb5v10Re3slG3/qxntkBt2/6GkQVDGu6Bwyhw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - jest-pnp-resolver: 1.2.3(jest-resolve@29.6.2) - jest-util: 29.6.2 - jest-validate: 29.6.2 + jest-haste-map: 29.6.3 + jest-pnp-resolver: 1.2.3(jest-resolve@29.6.3) + jest-util: 29.6.3 + jest-validate: 29.6.3 resolve: 1.22.4 resolve.exports: 2.0.2 slash: 3.0.0 dev: true - /jest-runner@29.6.2: - resolution: {integrity: sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w==} + /jest-runner@29.6.3: + resolution: {integrity: sha512-E4zsMhQnjhirFPhDTJgoLMWUrVCDij/KGzWlbslDHGuO8Hl2pVUfOiygMzVZtZq+BzmlqwEr7LYmW+WFLlmX8w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/console': 29.6.2 - '@jest/environment': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/console': 29.6.3 + '@jest/environment': 29.6.3 + '@jest/test-result': 29.6.3 + '@jest/transform': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 - jest-docblock: 29.4.3 - jest-environment-node: 29.6.2 - jest-haste-map: 29.6.2 - jest-leak-detector: 29.6.2 - jest-message-util: 29.6.2 - jest-resolve: 29.6.2 - jest-runtime: 29.6.2 - jest-util: 29.6.2 - jest-watcher: 29.6.2 - jest-worker: 29.6.2 + jest-docblock: 29.6.3 + jest-environment-node: 29.6.3 + jest-haste-map: 29.6.3 + jest-leak-detector: 29.6.3 + jest-message-util: 29.6.3 + jest-resolve: 29.6.3 + jest-runtime: 29.6.3 + jest-util: 29.6.3 + jest-watcher: 29.6.3 + jest-worker: 29.6.3 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color dev: true - /jest-runtime@29.6.2: - resolution: {integrity: sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg==} + /jest-runtime@29.6.3: + resolution: {integrity: sha512-VM0Z3a9xaqizGpEKwCOIhImkrINYzxgwk8oQAvrmAiXX8LNrJrRjyva30RkuRY0ETAotHLlUcd2moviCA1hgsQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.6.2 - '@jest/fake-timers': 29.6.2 - '@jest/globals': 29.6.2 - '@jest/source-map': 29.6.0 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/environment': 29.6.3 + '@jest/fake-timers': 29.6.3 + '@jest/globals': 29.6.3 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.6.3 + '@jest/transform': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 glob: 7.2.3 graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - jest-message-util: 29.6.2 - jest-mock: 29.6.2 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.2 - jest-snapshot: 29.6.2 - jest-util: 29.6.2 + jest-haste-map: 29.6.3 + jest-message-util: 29.6.3 + jest-mock: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.6.3 + jest-snapshot: 29.6.3 + jest-util: 29.6.3 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color dev: true - /jest-snapshot@29.6.2: - resolution: {integrity: sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA==} + /jest-snapshot@29.6.3: + resolution: {integrity: sha512-66Iu7H1ojiveQMGFnKecHIZPPPBjZwfQEnF6wxqpxGf57sV3YSUtAb5/sTKM5TPa3OndyxZp1wxHFbmgVhc53w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.22.10 @@ -4561,75 +4574,75 @@ packages: '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.10) '@babel/types': 7.22.10 - '@jest/expect-utils': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 + '@jest/expect-utils': 29.6.3 + '@jest/transform': 29.6.3 + '@jest/types': 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) chalk: 4.1.2 - expect: 29.6.2 + expect: 29.6.3 graceful-fs: 4.2.11 - jest-diff: 29.6.2 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.6.2 - jest-message-util: 29.6.2 - jest-util: 29.6.2 + jest-diff: 29.6.3 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.6.3 + jest-message-util: 29.6.3 + jest-util: 29.6.3 natural-compare: 1.4.0 - pretty-format: 29.6.2 + pretty-format: 29.6.3 semver: 7.5.4 transitivePeerDependencies: - supports-color dev: true - /jest-util@29.6.2: - resolution: {integrity: sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==} + /jest-util@29.6.3: + resolution: {integrity: sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 picomatch: 2.3.1 dev: true - /jest-validate@29.6.2: - resolution: {integrity: sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg==} + /jest-validate@29.6.3: + resolution: {integrity: sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.6.1 + '@jest/types': 29.6.3 camelcase: 6.3.0 chalk: 4.1.2 - jest-get-type: 29.4.3 + jest-get-type: 29.6.3 leven: 3.1.0 - pretty-format: 29.6.2 + pretty-format: 29.6.3 dev: true - /jest-watcher@29.6.2: - resolution: {integrity: sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA==} + /jest-watcher@29.6.3: + resolution: {integrity: sha512-NgpFjZ2U2MKusjidbi4Oiu7tfs+nrgdIxIEVROvH1cFmOei9Uj25lwkMsakqLnH/s0nEcvxO1ck77FiRlcnpZg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.4.9 + '@jest/test-result': 29.6.3 + '@jest/types': 29.6.3 + '@types/node': 20.5.3 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 - jest-util: 29.6.2 + jest-util: 29.6.3 string-length: 4.0.2 dev: true - /jest-worker@29.6.2: - resolution: {integrity: sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==} + /jest-worker@29.6.3: + resolution: {integrity: sha512-wacANXecZ/GbQakpf2CClrqrlwsYYDSXFd4fIGdL+dXpM2GWoJ+6bhQ7vR3TKi3+gkSfBkjy1/khH/WrYS4Q6g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.4.9 - jest-util: 29.6.2 + '@types/node': 20.5.3 + jest-util: 29.6.3 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.6.2: - resolution: {integrity: sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg==} + /jest@29.6.3: + resolution: {integrity: sha512-alueLuoPCDNHFcFGmgETR4KpQ+0ff3qVaiJwxQM4B5sC0CvXcgg4PEi7xrDkxuItDmdz/FVc7SSit4KEu8GRvw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: @@ -4638,10 +4651,10 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.6.2 - '@jest/types': 29.6.1 + '@jest/core': 29.6.3 + '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.6.2 + jest-cli: 29.6.3 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -4998,8 +5011,8 @@ packages: uc.micro: 1.0.6 dev: false - /lint-staged@14.0.0: - resolution: {integrity: sha512-0tLf0pqZYkar/wu3nTctk4rVIG+d7PanDYv4/IQR4qwdqfQkTDziLRFnqMcLuLBTuUqmcLwsHPD2EjQ18d/oaA==} + /lint-staged@14.0.1: + resolution: {integrity: sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==} engines: {node: ^16.14.0 || >=18.0.0} hasBin: true dependencies: @@ -5577,8 +5590,8 @@ packages: - supports-color dev: true - /node-fetch@2.6.12: - resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} + /node-fetch@2.6.13: + resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} engines: {node: 4.x || >=6.0.0} peerDependencies: encoding: ^0.1.0 @@ -5657,7 +5670,7 @@ packages: engines: {node: '>=12'} dependencies: markdown-table: 2.0.0 - node-fetch: 2.6.12 + node-fetch: 2.6.13 transitivePeerDependencies: - encoding dev: false @@ -6069,11 +6082,11 @@ packages: hasBin: true dev: true - /pretty-format@29.6.2: - resolution: {integrity: sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==} + /pretty-format@29.6.3: + resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 29.6.0 + '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.2.0 dev: true @@ -6116,7 +6129,7 @@ packages: resolution: {integrity: sha512-S1m0Ao0IGoXfy14dKXAaJCUkCBCnleYzElzoATj42Iq4d8EYqOZq4jS4G/D94AzrU6QaPOzzoEDjbm7VJQGq9g==} engines: {node: '>=14'} dependencies: - tslib: 2.6.1 + tslib: 2.6.2 dev: false /proxy-from-env@1.1.0: @@ -6341,8 +6354,8 @@ packages: resolution: {integrity: sha512-mnAH0jDJQ0SJtEXjoW5aQILEc+33RwtKzKxwK9JG1a06M6nn8WDWheD+kmc5ucs+ux4FEWX3+PZuEB8r3x15yQ==} dev: false - /re2js@0.3.2: - resolution: {integrity: sha512-N++IGnIi5bCcNxtQHEpmPJ1AwKnfStk7NNjZj51ewNDtmCPTG4CyGN+mv8zphaSB8FlelVGRGcWz4fnqU+Be0A==} + /re2js@0.3.3: + resolution: {integrity: sha512-zjGPsQN4Zaw7ijseQBmUYn+ncMus+arFSJOHQA3wMu9xuzh73kPPdPrRg6+UmNq2HAexdBXPr2Fnde5CELmA4A==} dev: false /react-is@18.2.0: @@ -6899,7 +6912,7 @@ packages: /streamx@2.15.1: resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} dependencies: - fast-fifo: 1.3.0 + fast-fifo: 1.3.2 queue-tick: 1.0.1 dev: false @@ -6980,8 +6993,8 @@ packages: engines: {node: '>=8'} dev: true - /superagent@8.0.9: - resolution: {integrity: sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==} + /superagent@8.1.2: + resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} engines: {node: '>=6.4.0 <13 || >=14'} dependencies: component-emitter: 1.3.0 @@ -7003,7 +7016,7 @@ packages: engines: {node: '>=6.4.0'} dependencies: methods: 1.1.2 - superagent: 8.0.9 + superagent: 8.1.2 transitivePeerDependencies: - supports-color dev: true @@ -7041,7 +7054,7 @@ packages: engines: {node: ^14.18.0 || >=16.0.0} dependencies: '@pkgr/utils': 2.4.2 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /tar-fs@3.0.4: @@ -7056,7 +7069,7 @@ packages: resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} dependencies: b4a: 1.6.4 - fast-fifo: 1.3.0 + fast-fifo: 1.3.2 streamx: 2.15.1 dev: false @@ -7234,8 +7247,8 @@ packages: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: false - /tslib@2.6.1: - resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} /tsscmp@1.0.6: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} diff --git a/scripts/docs-scraper/docs.rsshub.app.json b/scripts/docs-scraper/docs.rsshub.app.json index ab2b54ce3d0f13..de0477e677c223 100644 --- a/scripts/docs-scraper/docs.rsshub.app.json +++ b/scripts/docs-scraper/docs.rsshub.app.json @@ -13,7 +13,7 @@ "lvl3": ".theme-doc-markdown h3", "lvl4": ".theme-doc-markdown h4", "lvl5": ".theme-doc-markdown h5", - "text": ".theme-doc-markdown p.path, .theme-doc-markdown div.routeBlock div, .theme-doc-markdown table" + "text": ".theme-doc-markdown p, .theme-doc-markdown .params, .theme-doc-markdown table, .theme-doc-markdown li ul li code" }, "strip_chars": " .,;:#", "scrap_start_urls": false, diff --git a/test/config.js b/test/config.js index f82a9ea5d03adc..145068ee0ff37b 100644 --- a/test/config.js +++ b/test/config.js @@ -73,6 +73,20 @@ describe('config', () => { delete process.env.MEDIUM_COOKIE_34; }); + it('discourse config', () => { + process.env.DISCOURSE_CONFIG_12 = JSON.stringify({ a: 1 }); + process.env.DISCOURSE_CONFIG_34 = JSON.stringify({ b: 2 }); + + const config = require('../lib/config').value; + expect(config.discourse.config).toMatchObject({ + 12: { a: 1 }, + 34: { b: 2 }, + }); + + delete process.env.DISCOURSE_CONFIG_12; + delete process.env.DISCOURSE_CONFIG_34; + }); + it('no random ua', () => { process.env.NO_RANDOM_UA = true; diff --git a/website/docs/.format/format.js b/website/docs/.format/format.js index 32759f37eb2bbe..d538a7dda144a7 100644 --- a/website/docs/.format/format.js +++ b/website/docs/.format/format.js @@ -56,9 +56,9 @@ const loopNav = (nav, lang) => */ const buildFileList = async () => { const config = require(`../../sidebars.js`); - const fileList = config.guideSidebar[2].items.map((item) => ({ + const fileList = config.guideSidebar[2].items.map(({ id }) => ({ type: file.ROUTE_TYPE, - path: path.resolve(__dirname, '..', `./${item}.md`), + path: path.resolve(__dirname, '..', `./${id}.md`), lang: 'zh-CN', })); // let fileList = []; diff --git a/website/docs/.format/tojson.js b/website/docs/.format/tojson.js index 33ce7c6ee255fc..066f69e3457c0e 100644 --- a/website/docs/.format/tojson.js +++ b/website/docs/.format/tojson.js @@ -84,7 +84,7 @@ function parseMd(name) { // }) // }) - let newContent = `import Route from '@site/src/components/Route';\n\n` + `# ${cnParsed.h1}\n\n`; + let newContent = `# ${cnParsed.h1}\n\n`; cnParsed.h2.forEach((item) => { newContent += `## ${item.h2}\n\n`; if (item.content) { diff --git a/website/docs/README.md b/website/docs/README.md index 76beb3f09b691e..035cc5b3775bd5 100644 --- a/website/docs/README.md +++ b/website/docs/README.md @@ -1,5 +1,3 @@ - - # Introduction

diff --git a/website/docs/api.md b/website/docs/api.md index bdfa2541514ba2..e3020c30120620 100644 --- a/website/docs/api.md +++ b/website/docs/api.md @@ -1,15 +1,19 @@ # API -:::caution Warning +:::caution + The API is under active development and is subject to change. All suggestions are welcome! + ::: RSSHub provides the following APIs: ## List of Public Routes -:::tip Tip +:::tip + This API **will not** return any routes under `lib/protected_router.js`. + ::: Eg: diff --git a/website/docs/faq.md b/website/docs/faq.md index 876f70782ed748..26332d4f8151ec 100644 --- a/website/docs/faq.md +++ b/website/docs/faq.md @@ -1,5 +1,3 @@ -import Badge from '@site/src/components/Badge'; - # FAQs **Q: How does RSSHub work?** diff --git a/website/docs/install/README.md b/website/docs/install/README.md index 839f9891783cd3..ea25ad0e7e2d6c 100644 --- a/website/docs/install/README.md +++ b/website/docs/install/README.md @@ -89,7 +89,7 @@ Edit `environment` in [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob ## Docker Deployment -:::tip Tip +:::tip To enable puppeteer, replace `diygod/rsshub` with `diygod/rsshub:chromium-bundled` in **EACH** command. @@ -186,44 +186,58 @@ $ cd RSSHub Execute the following commands to install dependencies (Do not add the `--production` parameter for development). - - + + ```bash pnpm install --prod ``` - - + + ```bash yarn --production ``` - - + + ```bash npm install --omit=dev ``` - - + + ### Launch Under `RSSHub`'s root directory, execute the following commands to launch + + + +```bash +pnpm start +``` + + + + ```bash $ yarn start ``` -Or + + ```bash $ npm start ``` + + + Or use [PM2](https://pm2.io/docs/plus/quick-start/) ```bash @@ -236,7 +250,7 @@ Refer to our [Guide](https://docs.rsshub.app/) for usage. Replace `https://rsshu ### Configuration -:::tip Tip +:::tip On arm/arm64, this deployment method does not include puppeteer dependencies. To enable puppeteer, install Chromium from your distribution repositories first, then set `CHROMIUM_EXECUTABLE_PATH` to its executable path. @@ -491,7 +505,7 @@ If you would like to test routes or avoid IP limits, etc., you may build your ow [![Try in PWD](https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png)](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml) -:::caution Warning +:::caution - [DockerHub](https://hub.docker.com) account required - [Play with Docker](https://labs.play-with-docker.com/) instance will last for 4 hours at most. It should only be used for testing purpose @@ -725,7 +739,7 @@ Configs in this sections are in beta stage, and **are turn off by default**. Ple ### Route-specific Configurations -:::tip Notice +:::tip Configs here are incomplete. @@ -778,6 +792,11 @@ See docs of the specified route and `lib/config.js` for detailed information. - `DISCORD_AUTHORIZATION`: Discord authorization token, can be found in the header of XHR requests after logging in Discord web client +- Discourse + - `DISCOURSE_CONFIG_{id}`: `id` could be arbitrary number or string, while the value should be the format of `{"link":link,"key":key}`, where: + - `link` is the link to the forum. + - `key` is the access key for the forum API, which you can refer to [this snippet](https://pastebin.com/YbLCgdWW) to obtain one. Ensure that this key is granted sufficient permission. + - Discuz cookie - `DISCUZ_COOKIE_{cid}`: Cookie of a forum powered by Discuz, cid can be anything from 00 to 99. When visiting a Discuz route, use cid to specify this cookie. diff --git a/website/docs/joinus/advanced/advanced-feed.md b/website/docs/joinus/advanced/advanced-feed.md index 4a900f45540fde..4b8627626c8e0a 100644 --- a/website/docs/joinus/advanced/advanced-feed.md +++ b/website/docs/joinus/advanced/advanced-feed.md @@ -2,8 +2,6 @@ sidebar_position: 1 --- -import Route from '@site/src/components/Route'; - # RSS Feed Fundamentals This guide is intended for advanced users who want to know how to create an RSS feed in detail. If you're new to creating RSS feeds, we recommend reading [Create Your Own RSSHub Route](/joinus/new-rss/start-code) first. @@ -56,6 +54,7 @@ Each item in an RSS feed is represented by an object with a set of fields that d | **`doi`** | *(Optional)* The Digital Object Identifier of the item, which should be a string in the format `10.xxxx/xxxxx.xxxx` | `undefinded` | R | :::caution Formatting Considerations + When specifying certain fields in an RSS feed, it's important to keep in mind some formatting considerations. Specifically, you should avoid including any linebreaks, consecutive whitespace, or leading/trailing whitespace in the following fields: **`title`**, **`subtitle`** (only for Atom), **`author`** (only for Atom), **`item.title`**, and **`item.author`**. While most RSS readers will automatically trim these fields, some may not process them properly. Therefore, to ensure compatibility with all RSS readers, we recommend trimming these fields before outputting them. If your route cannot tolerate trimming these fields, you should consider changing their format. @@ -63,6 +62,7 @@ While most RSS readers will automatically trim these fields, some may not proces Additionally, while other fields will not be forced to be trimmed, we suggest avoiding violations of the above formatting rules as much as possible. If you are using Cheerio to extract content from web pages, be aware that Cheerio will retain line breaks and indentation. For the **`item.description`** field, in particular, any intended linebreaks should be converted to `
` tags to prevent them from being trimmed by the RSS reader. If you're extracting an RSS feed from JSON data, be aware that the JSON may contain linebreaks that need to be displayed, so you should convert them to `
` tags in this case. It's important to keep these formatting considerations in mind to ensure your RSS feed is compatible with all RSS readers. + ::: ## Create a BitTorrent/Magnet Feed @@ -89,7 +89,7 @@ By including these fields in your RSS feed, you'll be able to create BitTorrent/ If you're adding support for BitTorrent/Magnet feeds in your RSSHub route, it's important to update the documentation to reflect this change. To do this, you'll need to set the `supportBT` attribute of the `Route` component to `"1"`. Here's an example: -```vue +```tsx ``` @@ -115,7 +115,7 @@ By including this `doi` field in your RSS feed, you'll be able to create journal To update the documentation for your route with support for Sci-hub, you'll need to set the `supportScihub` attribute of the Route component to `"1"`. Here's an example: -```vue +```tsx ``` @@ -155,7 +155,7 @@ By including these fields in your RSS feed, you'll be able to create podcast fee To update the documentation for your route with support for podcast feeds, you'll need to set the `supportPodcast` attribute of the `Route` component to `"1"`. Here's an example: -```vue +```tsx ``` diff --git a/website/docs/joinus/advanced/pub-date.md b/website/docs/joinus/advanced/pub-date.md index 4654d801314783..3700df49f2e966 100644 --- a/website/docs/joinus/advanced/pub-date.md +++ b/website/docs/joinus/advanced/pub-date.md @@ -36,8 +36,10 @@ const pubDate = parseDate('2020/12/30'); const pubDate = parseDate('2020/12/30', 'YYYY/MM/DD'); ``` -:::tip Tips +:::tip + You can refer to the [day.js documentation](https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens) for all available date formats. + ::: If you need to parse a relative date, use `parseRelativeDate`. diff --git a/website/docs/joinus/advanced/script-standard.md b/website/docs/joinus/advanced/script-standard.md index 1ef29747fe2e4d..7d9ca5fa25c558 100644 --- a/website/docs/joinus/advanced/script-standard.md +++ b/website/docs/joinus/advanced/script-standard.md @@ -111,8 +111,10 @@ The `maintainer.js` file should export an object that provides maintainer inform To generate a list of maintainers, use the following command: `pnpm run build:maintainer`, which will create the list under `assets/build/`. -:::danger Warning +:::danger + The path in the `@koa/router` object should be the same as the `path` in the corresponding documentation before the namespace appended in front of it. + ::: ### Radar Rules @@ -121,8 +123,10 @@ All routes are required to include the `radar.js` file, which includes the corre To generate a complete `radar-rules.js` file, use the following command: `yarn build:radar`, which will create the file under `assets/build/`. -:::tip Tips +:::tip + Remember to remove all build artifacts in `assets/build/` before committing. + ::: ### Rendering Templates @@ -154,7 +158,7 @@ const renderAuthor = (author) => art(path.join(__dirname, 'templates/author.art' ### v1 Route Standard -:::danger Warning +:::danger The v1 Route Standard is deprecated. All new routes should be following the [v2 Route Standard](/joinus/advanced/script-standard#v2-route-standard). diff --git a/website/docs/joinus/advanced/use-cache.md b/website/docs/joinus/advanced/use-cache.md index 2d61a71981c045..409c6f1b64b07f 100644 --- a/website/docs/joinus/advanced/use-cache.md +++ b/website/docs/joinus/advanced/use-cache.md @@ -29,7 +29,8 @@ The above code snippet from [Create Your Own RSSHub Route](/joinus/new-rss/start The object returned from the previous statement will be reused, and an extra `description` property will be added to it. The returned cache for each `item.link` will be `{ title, link, pubDate, author, category, description }`. The next time the same path is requested, this processed cache will be used instead of making a request to the server and recomputing the data. -:::caution Warning +:::caution + Any assignments to variables that are declared outside of the `tryGet()` function will not be processed under a cache-hit scenario. For example, the following code will not work as expected: ```js @@ -62,10 +63,12 @@ Any assignments to variables that are declared outside of the `tryGet()` functio [lib/middleware/cache/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/cache/index.js#L58) -:::tip Tips +:::tip + Below are advanced methods for using cache. You should use `ctx.cache.tryGet()` most of the time. Note that you need to use `JSON.parse()` when retrieving the cache using `ctx.cache.get()`. + ::: ### ctx.cache.get(key [, refresh ]) diff --git a/website/docs/joinus/new-radar.md b/website/docs/joinus/new-radar.md index 9a813a251b8cd5..6570466459c18a 100644 --- a/website/docs/joinus/new-radar.md +++ b/website/docs/joinus/new-radar.md @@ -40,13 +40,14 @@ The first inner object key is `_name`, which is the name of the website. This sh The rest of the inner object keys are the subdomains of a website. If a website you want to match does not have any subdomains, or you want to match both `www.example.com` and `example.com`, use `'.'` instead. In this case, we will use `'.'` since we want to match `github.com`. Note that each subdomain should return **an array of objects**. - - + + -```js{4} +```js module.exports = { 'github.com': { _name: 'GitHub', + // highlight-next-line '.': [ { title: '...', @@ -59,13 +60,14 @@ module.exports = { }; ``` - - + + -```js{4} +```js module.exports = { 'github.com': { _name: 'GitHub', + // highlight-next-line abc: [ { title: '...', @@ -78,13 +80,14 @@ module.exports = { }; ``` - - + + -```js{4} +```js module.exports = { 'github.com': { _name: 'GitHub', + // highlight-next-line 'abc.def': [ { title: '...', @@ -97,8 +100,8 @@ module.exports = { }; ``` - - + + ### `title` @@ -116,8 +119,10 @@ The source field is *optional* and should specifies the URL path. Leave it blank The source should be an array of strings. For example, if the source for `GitHub Repo Issues` is `/:user/:repo`, it means that when you visit `https://github.com/DIYgod/RSSHub`, which matches the `github.com/:user/:repo` pattern, the parameters for this URL will be: `{user: 'DIYgod', repo: 'RSSHub'}`. The browser extension uses these parameters to create an RSSHub subscription address based on the `target` field. -:::caution Warning +:::caution + If the value you want to extract is in the URL search parameters or URL hash, use target as a function instead of the `source` field. Also, remember that the `source` field only matches the URL path and not any other parts of the URL. + ::: You can use the `*` symbol to perform wildcard matching. Note that the syntax here is not the same as the [path-to-regexp](https://github.com/pillarjs/path-to-regexp). For instance, `/:user/:repo/*` will match both `https://github.com/DIYgod/RSSHub/issues` and `https://github.com/DIYgod/RSSHub/issues/1234`. If you want to name the matching result, you can place the variable name after the `*` symbol. For example, `/user/:repo/*path`, whereby path will be `issues` and `issues/1234` in the above scenario. @@ -140,10 +145,10 @@ It is essential to note that the `target` method runs in a sandbox, and any chan Here are two examples of how to use the `target` field as a function: - - + + -```js{9} +```js module.exports = { 'github.com': { _name: 'GitHub', @@ -152,6 +157,7 @@ module.exports = { title: 'Repo Issues', docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo/issues/:id', '/:user/:repo/issues', '/:user/:repo'], + // highlight-next-line target: (params) => `/github/issue/${params.user}/${params.repo}`, }, ], @@ -159,10 +165,10 @@ module.exports = { }; ``` - - + + -```js{9} +```js module.exports = { 'github.com': { _name: 'GitHub', @@ -171,6 +177,7 @@ module.exports = { title: 'Repo Issues', docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo'], + // highlight-next-line target: (_, url) => `/github/issue${new URL(url).pathname}` }, ], @@ -178,8 +185,8 @@ module.exports = { }; ``` - - + + Both the above examples will return the same RSSHub subscription address as the [first example](/joinus/new-radar#code-the-rule). diff --git a/website/docs/joinus/new-rss/add-docs.md b/website/docs/joinus/new-rss/add-docs.md index 6dcff33591f843..0f92164ec39bf5 100644 --- a/website/docs/joinus/new-rss/add-docs.md +++ b/website/docs/joinus/new-rss/add-docs.md @@ -2,67 +2,71 @@ sidebar_position: 4 --- -import Route from '@site/src/components/Route'; - # Add documentation Now that we have completed the code, it's time to add the documentation for your route. Open the appropriate file in the [document (/website/docs)](https://github.com/DIYgod/RSSHub/blob/master/website/docs), which in this example is `/website/i18n/en/docusaurus-plugin-content-docs/current/routes/programming.md`. In order to preview the documentation in real-time, you need to install the dependencies for the documentation. Run the following command in the **`website` directory**: - - + + ```bash pnpm i ``` - - + + ```bash yarn ``` - - + + ```bash npm install ``` - - + + You can now preview the documentation in real-time by running the following command in the **`website` directory**: - - + + ```bash -pnpm run start -- --locale en +pnpm run start ``` - - + + ```bash -yarn start --locale en +yarn start ``` - - + + ```bash -npm run start -- --locale en +npm run start ``` - - + + + +:::caution + +You cannot switch to other languages in development mode. This is a [technical limitation](https://docusaurus.io/docs/i18n/tutorial#start-your-site) from Docusaurus. + +::: -The documentation is written in Markdown and rendered with [VuePress v1](https://v1.vuepress.vuejs.org). +The documentation is written in MDX and rendered with [Docusaurus v2](https://docusaurus.io/docs). -To add documentation to your route, use Vue components. They work like HTML tags. The following are the most commonly used components: +To add documentation to your route, use the `Route` React component. It works like HTML tag. The following are the most commonly used component properties: - `author`: The route maintainer(s), separated by a single space. It should be the same as [`maintainer.js`](/joinus/new-rss/before-start#understand-the-basics-maintainer-js) - `example`: The route example, with a leading `/` @@ -79,7 +83,7 @@ To add documentation to your route, use Vue components. They work like HTML tags ### Repo Issues (No parameter) -```vue +```tsx ``` @@ -91,7 +95,7 @@ To add documentation to your route, use Vue components. They work like HTML tags ### Repo Issues (Multiple parameters) -```vue +```tsx ``` @@ -103,7 +107,7 @@ To add documentation to your route, use Vue components. They work like HTML tags ### Keyword (Description with table) -```vue +```tsx | only not R18 | only R18 | no filter | @@ -130,46 +134,84 @@ To add documentation to your route, use Vue components. They work like HTML tags If you'd like to provide additional information about a particular route, you can use these custom containers: ```md +

+ Click to expand + This is a detail block. Title is optional and does not support Markdown. +
+ +:::note + +This is a note. + +::: + :::tip Tips title -This is a tip. + +Title is optional. + ::: -:::caution Warning title -This is a warning. +:::info + +Supprts Markdown. + ::: -:::danger Danger title -This is a dangerous warning. +:::caution + +Add a empty line around the starting and ending directive `:::` + ::: -:::note Details title -This is a details block. +:::danger + +Otherwise the content may not be rendered properly. + ::: ``` --- +
+ Click to expand + This is a detail block. Title is optional and does not support Markdown. +
+ +:::note + +This is a note. + +::: + :::tip Tips title -This is a tip. + +Title is optional. + ::: -:::caution Warning title -This is a warning. +:::info + +Supprts Markdown. + ::: -:::danger Danger title -This is a dangerous warning. +:::caution + +Add a empty line around the starting and ending directive `:::` + ::: -:::note Details title -This is a details block. +:::danger + +Otherwise the content may not be rendered properly. + ::: --- ### Other components -In addition to the route components, there are several other components you can use to provide more information about your route: +In addition to the aforementioned component properties, there are several other properties you can use to provide more information about your route: - `anticrawler`: set to `1` if the target website has an anti-crawler mechanism. - `puppeteer`: set to `1` if the feed uses puppeteer. @@ -180,9 +222,9 @@ In addition to the route components, there are several other components you can - `supportPodcast`: set to `1` if the feed supports podcasts. - `supportScihub`: set to `1` if the feed supports Sci-Hub. -By using these components, you can provide valuable information to users and make it easier for them to understand and use your route. Adding these components to your route documentation will add a badge in front of it. +By using these properties, you can provide valuable information to users and make it easier for them to understand and use your route. Adding these properties to your route documentation will add a badge in front of it. -```vue +```tsx ``` @@ -201,26 +243,26 @@ By using these components, you can provide valuable information to users and mak - **Remember to close the tag!** - Don't forget to run the following command in the **root directory** of the project to check and format your code before committing and submitting a merge request: - - + + ```bash pnpm run format ``` - - + + ```bash yarn format ``` - - + + ```bash npm run format ``` - - + + diff --git a/website/docs/joinus/new-rss/before-start.md b/website/docs/joinus/new-rss/before-start.md index 8f616a3d9aae36..d512366a5c5341 100644 --- a/website/docs/joinus/new-rss/before-start.md +++ b/website/docs/joinus/new-rss/before-start.md @@ -10,57 +10,57 @@ In this tutorial, we will walk you through the process of creating an RSS feed f Before you start, you need to install the dependencies for RSSHub. You can do this by running the following command in the root directory of RSSHub: - - + + ```bash pnpm i ``` - - + + ```bash yarn ``` - - + + ```bash npm install ``` - - + + ## Start debugging Once you have successfully installed the dependencies, you can start debugging RSSHub by running the following command: - - + + ```bash pnpm run dev ``` - - + + ```bash yarn dev ``` - - + + ```bash npm run dev ``` - - + + Make sure to keep an eye on the console output for any error messages or other useful information that can help you diagnose and resolve issues. Additionally, don't hesitate to consult the RSSHub documentation or seek help from the community if you encounter any difficulties. @@ -78,8 +78,10 @@ Before submitting your Pull Request, make sure to carefully review the [Script S The first step in creating a new RSS route is to create a namespace. The namespace should be the **same** as the second level domain name of the main website for which you are creating the RSS feed. For example, if you are creating an RSS feed for , the second level domain name is `github`. Therefore, you should create a folder called `github` under `lib/v2` to serve as the namespace for your RSS route. -:::tip Tips +:::tip + When creating a namespace, it's important to avoid creating multiple namespaces for variations of the same domain. For example, if you are creating an RSS feed for both `yahoo.co.jp` and `yahoo.com`, you should stick with a single namespace `yahoo`, rather than creating multiple namespaces like `yahoo-jp`, `yahoojp`, `yahoo.jp`, `jp.yahoo`, `yahoocojp`, etc. + ::: ## Understand the Basics @@ -90,26 +92,28 @@ Once you have created the namespace for your RSS route, the next step is to regi For example, if you are creating an RSS feed for [GitHub Repo Issues](/routes/programming#github-repo-issues) and suppose you want users to enter a GitHub username and a repository name, and fall back to `RSSHub` if they don't enter the repository name, you can register your new RSS route in `github/router.js` using the following code: - - + + -```js{2} +```js module.exports = (router) => { + // highlight-next-line router.get('/issue/:user/:repo?', require('./issue')); }; ``` - - + + -```js{2} +```js module.exports = function (router) { + // highlight-next-line router.get('/issue/:user/:repo?', require('./issue')); }; ``` - - + + When registering your new RSS route in `router.js`, you can define the route path and specify the corresponding function to be executed. In the code above, the `router.get()` method is used to specify the HTTP method and the path of the new RSS route. The first parameter of `router.get()` is the route path using [path-to-regexp](https://github.com/pillarjs/path-to-regexp) syntax. The second parameter is the exported function from your new RSS rule, `issue.js`. Note that you can omit the `.js` extension. @@ -121,16 +125,19 @@ Once you have defined the route path, you can retrieve the value of the paramete You can use the `*` or `+` symbols to match the rest of the path, like `/some/path/:variable*`. Note that `*` and `+` mean "zero or more" and "one or more", respectively. You can also use patterns like `/some/path/:variable(\\d+)?` or even RegExp. -:::tip Tips +:::tip + For more advanced usage of `router`, see the [@koa/router API Reference](https://github.com/koajs/router/blob/master/API.md). + ::: ### maintainer.js This file is used to store information about the maintainer of the RSS routes. You can add your GitHub username to the value array. Note that the key here should exactly match the path in `router.js` : -```js{2} +```js module.exports = { + // highlight-next-line '/issue/:user/:repo?': ['DIYgod'], }; ``` diff --git a/website/docs/joinus/new-rss/start-code.md b/website/docs/joinus/new-rss/start-code.md index e710ad400bb105..f7a49801c7d0a7 100644 --- a/website/docs/joinus/new-rss/start-code.md +++ b/website/docs/joinus/new-rss/start-code.md @@ -23,8 +23,8 @@ Open your code editor and create a new file. Since we are going to create an RSS Here's the basic code to get you started: - - + + ```js // Import the necessary modules @@ -40,18 +40,19 @@ module.exports = async (ctx) => { }; ``` - - + + ### Retrieving user input As mentioned earlier, we need to retrieve the GitHub username and repository name from user input. The repository name should default to `RSSHub` if it is not provided in the request URL. Here's how you can do it: - - + + -```js{2} +```js module.exports = async (ctx) => { + // highlight-next-line const { user, repo = 'RSSHub' } = ctx.params; ctx.state.data = { @@ -60,13 +61,15 @@ module.exports = async (ctx) => { }; ``` - - + + -```js{2,3} +```js module.exports = async (ctx) => { + // highlight-start const user = ctx.params.user; const repo = ctx.params.repo ?? 'RSSHub'; + // highlight-end ctx.state.data = { // Your RSS output here @@ -74,8 +77,8 @@ module.exports = async (ctx) => { }; ``` - - + + Both of these code snippets do the same thing. The first one uses object destructuring to assign the `user` and `repo` variables, while the second one uses traditional assignment with a nullish coalescing operator to assign the `repo` variable a default value of `RSSHub` if it is not provided in the request URL. @@ -83,12 +86,13 @@ Both of these code snippets do the same thing. The first one uses object destruc After we have the user input, we can use it to make a request to the API. In most cases, you will need to use `got` from `@/utils/got` (a customized got wrapper) to make HTTP requests. For more information, please refer to the [got documentation](https://github.com/sindresorhus/got/tree/v11#usage). - - + + -```js{3-16} +```js module.exports = async (ctx) => { const { user, repo = 'RSSHub' } = ctx.params; + // highlight-start // Send an HTTP GET request to the API // and destruct the data object returned by the request const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { @@ -103,6 +107,7 @@ module.exports = async (ctx) => { per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, }, }); + // highlight-end ctx.state.data = { // Your RSS output here @@ -110,13 +115,14 @@ module.exports = async (ctx) => { }; ``` - - + + -```js{4-14} +```js module.exports = async (ctx) => { const user = ctx.params.user; const repo = ctx.params.repo ?? 'RSSHub'; + // highlight-start // Send an HTTP GET request to the API const response = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { @@ -128,6 +134,7 @@ module.exports = async (ctx) => { }); // response.data is the data object returned by the above request const data = response.data; + // highlight-end ctx.state.data = { // Your RSS output here @@ -135,8 +142,8 @@ module.exports = async (ctx) => { }; ``` - - + + ### Outputting the RSS @@ -146,10 +153,10 @@ To do this, we can assign the relevant data to the `ctx.state.data` object, and Here is the final code that you should have: - - + + -```js{16-30,32-39} +```js const got = require('@/utils/got'); const { parseDate } = require('@/utils/parse-date'); @@ -165,6 +172,7 @@ module.exports = async (ctx) => { }, }); + // highlight-start // extract the relevant data from the API response const items = data.map((item) => ({ // item title @@ -180,7 +188,9 @@ module.exports = async (ctx) => { // item category, if available category: item.labels.map((label) => label.name), })); + // highlight-end + // highlight-start ctx.state.data = { // channel title title: `${user}/${repo} issues`, @@ -189,13 +199,14 @@ module.exports = async (ctx) => { // each feed item item: items, }; + // highlight-end }; ``` - - + + -```js{16-36} +```js const got = require('@/utils/got'); const { parseDate } = require('@/utils/parse-date'); @@ -211,6 +222,7 @@ module.exports = async (ctx) => { }, }); + // highlight-start ctx.state.data = { // channel title title: `${user}/${repo} issues`, @@ -232,11 +244,12 @@ module.exports = async (ctx) => { category: item.labels.map((label) => label.name), })); }; + // highlight-end }; ``` - - + + ## Via HTML web page using got @@ -269,10 +282,12 @@ You will add your own code to extract data from the HTML document, process it, a As mentioned before, we want users to enter a GitHub username and a repository name, and fall back to `RSSHub` if they don't enter the repository name in the request URL. -```js{2-3} +```js module.exports = async (ctx) => { + // highlight-start // Retrieve user and repository name from the URL parameters const { user, repo = 'RSSHub' } = ctx.params; + // highlight-end ctx.state.data = { // Your RSS output here @@ -288,20 +303,23 @@ After receiving the user input, we need to make a request to the web page to ret To begin, we'll make an HTTP GET request to the API and load the HTML response into Cheerio, a library that helps us parse and manipulate HTML. -```js{5-6} +```js const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; // Note that the ".data" property contains the full HTML source of the target page returned by the request + // highlight-start const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); + // highlight-end ``` Next, we'll use Cheerio selectors to select the relevant HTML elements, parse the data we need, and convert it into an array. -```js{3-21} +```js // We use a Cheerio selector to select all 'div' elements with the class name 'js-navigation-container' // that contain child elements with the class name 'flex-auto'. + // highlight-start const item = $('div.js-navigation-container .flex-auto') // We use the `toArray()` method to retrieve all the DOM elements selected as an array. .toArray() @@ -321,6 +339,7 @@ Next, we'll use Cheerio selectors to select the relevant HTML elements, parse th .map((item) => $(item).text()), }; }); + // highlight-end ctx.state.data = { // Your RSS output here @@ -335,7 +354,7 @@ Assign them to the `ctx.state.data` object, and RSSHub's middleware will take ca Here's an example code: -```js{29-36} +```js const got = require('@/utils/got'); const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); @@ -364,6 +383,7 @@ module.exports = async (ctx) => { }; }); + // highlight-start ctx.state.data = { // channel title title: `${user}/${repo} issues`, @@ -372,6 +392,7 @@ module.exports = async (ctx) => { // each feed item item: items, }; + // highlight-end }; ``` @@ -381,7 +402,7 @@ The previous code provides only part of the information for each feed item. To p Here's the updated code: -```js{12,29-43,48} +```js const got = require('@/utils/got'); const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); @@ -393,6 +414,7 @@ module.exports = async (ctx) => { const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); + // highlight-next-line const list = $('div.js-navigation-container .flex-auto') .toArray() .map((item) => { @@ -410,6 +432,7 @@ module.exports = async (ctx) => { }; }); + // highlight-start const items = await Promise.all( list.map((item) => ctx.cache.tryGet(item.link, async () => { @@ -425,10 +448,12 @@ module.exports = async (ctx) => { }) ) ); + // highlight-end ctx.state.data = { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, + // highlight-next-line item: items, }; }; @@ -437,10 +462,12 @@ module.exports = async (ctx) => { Now the RSS feed will have a similar reading experience to the original website. -:::tip Note +:::tip + Note that in the previous section, we only needed to send one HTTP request using an API to get all the data we needed. However, in this section, we need to send `1 + n` HTTP requests, where `n` is the number of feed items in the list from the first request. Some websites may not want to receive too many requests in a short amount of time, which can cause them to return an error message like `429 Too Many Requests`. + ::: ## Using the common configured route @@ -477,7 +504,7 @@ module.exports = async (ctx) => { Our RSS feed currently lacks content. The `item` must be set to add the content. Here's an example: -```js{15-22} +```js const buildData = require('@/utils/common-config'); module.exports = async (ctx) => { @@ -492,6 +519,7 @@ module.exports = async (ctx) => { title: `${user}/${repo} issues`, baseUrl: 'https://github.com', }, + // highlight-start item: { item: 'div.js-navigation-container .flex-auto', // You need to use template literals if you want to use variables @@ -500,6 +528,7 @@ module.exports = async (ctx) => { // description: ..., we don't have description for now pubDate: `parseDate($('relative-time').attr('datetime'))`, }, + // highlight-end }); }; ``` @@ -510,10 +539,12 @@ You'll notice that the code is similar to the [Obtaining data from the webpage]( To get the full article of each issue, you need to add a few more lines of code. Here is an example: -```js{2-3,25-34} +```js const buildData = require('@/utils/common-config'); +// highlight-start const got = require('@/utils/got'); const cheerio = require('cheerio'); +// highlight-end module.exports = async (ctx) => { const { user, repo = 'RSSHub' } = ctx.params; @@ -535,6 +566,7 @@ module.exports = async (ctx) => { }, }); + // highlight-start await Promise.all( ctx.state.data.item.map((item) => ctx.cache.tryGet(item.link, async () => { @@ -545,6 +577,7 @@ module.exports = async (ctx) => { }) ) ); + // highlight-end }; ``` @@ -577,10 +610,10 @@ module.exports = async (ctx) => { Now, we will be using `puppeteer` instead of `got` to retrieve data from the web page. - - + + -```js{9-33,39-40} +```js const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); const logger = require('@/utils/logger'); @@ -589,6 +622,7 @@ module.exports = async (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; + // highlight-start // require puppeteer utility class and initialise a browser instance const browser = await require('@/utils/puppeteer')(); // open a new tab @@ -614,13 +648,16 @@ module.exports = async (ctx) => { const response = await page.content(); // close the tab page.close(); + // highlight-end const $ = cheerio.load(response); // const item = ...; + // highlight-start // don't forget to close the browser instance at the end of the function browser.close(); + // highlight-end ctx.state.data = { // Your RSS output here @@ -628,10 +665,10 @@ module.exports = async (ctx) => { } ``` - - + + -```js{9} +```js const got = require('@/utils/got'); const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); @@ -640,6 +677,7 @@ module.exports = async (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; + // highlight-next-line const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); @@ -649,14 +687,14 @@ module.exports = async (ctx) => { } ``` - - + + ### Retrieving full articles Retrieving the full articles of each issue using a new browser page is similar to the [previous section](#better-reading-experience). We can use the following code: -```js{46-60,71-72} +```js const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); const logger = require('@/utils/logger'); @@ -702,6 +740,7 @@ module.exports = async (ctx) => { const items = await Promise.all( list.map((item) => ctx.cache.tryGet(item.link, async () => { + // highlight-start // reuse the browser instance and open a new tab const page = await browser.newPage(); // set up request interception to only allow document requests @@ -717,6 +756,7 @@ module.exports = async (ctx) => { const response = await page.content(); // close the tab after retrieving the HTML content page.close(); + // highlight-end const $ = cheerio.load(response); @@ -727,8 +767,10 @@ module.exports = async (ctx) => { ) ); + // highlight-start // close the browser instance after all requests are done browser.close(); + // highlight-end ctx.state.data = { title: `${user}/${repo} issues`, diff --git a/website/docs/parameter.md b/website/docs/parameter.md index 9974532e625698..e296af19b09fc2 100644 --- a/website/docs/parameter.md +++ b/website/docs/parameter.md @@ -20,22 +20,20 @@ E.g. ## Filtering -:::caution Warning +:::caution Please make sure you've [fully URL-encoded](https://gchq.github.io/CyberChef/#recipe=URL_Encode(true)) the parameters. Do not rely on the browser's automatic URL encoding. Some characters, such as `+`, `&`, will not be automatically encoded, resulting in the final parsing result not being correct. ::: -:::caution Warning +:::caution filter supports Regex, and due to the fact that some Regex are vulnerable to DoS (ReDoS), default engine `re2` blocks some of these functionalities available in node `Regexp`. These two engines also behaves a bit different in some corner cases. [Details](https://github.com/uhop/node-re2#limitations-things-re2-does-not-support) - If you need to use a different engine, please refer to [Deploy->Features->FILTER_REGEX_ENGINE](/install/#configuration-features). ::: - The following URL query parameters are supported, Regex support is built-in. Set `filter` to include the content @@ -122,7 +120,7 @@ E.g. ## Multimedia processing -:::caution Warning +:::caution This is an experimental API diff --git a/website/docs/routes/anime.md b/website/docs/routes/anime.md index c5e01c1e0a646e..9281dfc39249b2 100644 --- a/website/docs/routes/anime.md +++ b/website/docs/routes/anime.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🎨️ ACG ## 005.tv {#005.tv} @@ -20,7 +18,7 @@ import Route from '@site/src/components/Route'; -:::tip 提示 +:::tip 若订阅 [新品速递](https://www.78dm.net/news),网址为 。截取 `https://www.78dm.net` 到末尾的部分 `/news` 作为参数,此时路由为 [`/78dm/news`](https://rsshub.app/78dm/news)。 @@ -34,7 +32,7 @@ import Route from '@site/src/components/Route'; -:::tip 提示 +:::tip 若订阅 [精彩评测](https://www.78dm.net/eval_list),网址为 。截取 `https://www.78dm.net` 到末尾的部分 `/eval_list` 作为参数,此时路由为 [`/78dm/eval_list`](https://rsshub.app/78dm/eval_list)。 @@ -48,7 +46,7 @@ import Route from '@site/src/components/Route'; -:::tip 提示 +:::tip 若订阅 [好帖推荐](https://www.78dm.net/ht_list),网址为 。截取 `https://www.78dm.net` 到末尾的部分 `/ht_list` 作为参数,此时路由为 [`/78dm/ht_list`](https://rsshub.app/78dm/ht_list)。 @@ -64,7 +62,7 @@ import Route from '@site/src/components/Route'; -:::tip 提示 +:::tip 番剧 id 不包含开头的 aa。 例如: 的番剧 id 是 5022158,不包括开头的 aa。 @@ -227,7 +225,7 @@ For more tags, please go to [Search torrent](https://bangumi.moe/search/index) -:::tip Tip +:::tip To subscribe to this route, you can first visit the site and specify filters, and then fill in the field after `https://www.dlsite.com/` in the URL of the corresponding page at the path of the route. Here are 2 examples. @@ -351,7 +349,7 @@ Sources | ----- | ------- | ------------ | ------- | ------------- | ------ | ------- | ------ | | posts | patreon | fanbox | gumroad | subscribestar | dlsite | discord | fantia | -:::tip Tip +:::tip When `posts` is selected as the value of the parameter **source**, the parameter **id** does not take effect. @@ -385,8 +383,10 @@ When `posts` is selected as the value of the parameter **source**, the parameter :::tip Please note! + The schedule and other information obtained by this route is subject to the official website announcement! The RSS routing has not been rigorously tested and the information provided cannot be guaranteed accurate! + ::: | Sub-project Name (not full name) | 全シリーズ | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! | ラブライブ!スクールアイドルミュージカル | @@ -411,7 +411,7 @@ The RSS routing has not been rigorously tested and the information provided cann -:::tip 提示 +:::tip 在首页将分类参数选择确定后跳转到的分类页面 URL 中,`/l/` 后的字段即为分类参数。 @@ -573,7 +573,7 @@ For example: ,若该域名无法访问,可以通过在路由最后加上 `?domain=<域名>` 指定路由访问的域名。如指定备用域名为 ,则在所有禁漫天堂路由最后加上 `?domain=jmcomic1.me` 即可,此时路由为 [`/18comic?domain=jmcomic1.me`](https://rsshub.app/18comic?domain=jmcomic1.me) @@ -728,7 +728,7 @@ You can use some RSS parsing libraries (like `feedpraser` in `Python`) to receiv -:::tip 提示 +:::tip 关键字必须超过两个字,这是来自网站的限制。 @@ -740,7 +740,7 @@ You can use some RSS parsing libraries (like `feedpraser` in `Python`) to receiv -:::tip 提示 +:::tip 专辑 id 不包括 URL 中标题的部分。 @@ -770,7 +770,7 @@ You can use some RSS parsing libraries (like `feedpraser` in `Python`) to receiv -:::tip 提示 +:::tip 个人订阅需要自建 环境变量需要添加 MHGUI_COOKIE @@ -847,7 +847,7 @@ You can use some RSS parsing libraries (like `feedpraser` in `Python`) to receiv | ------ | ------ | ------ | ------ | ------ | ------ | ------ | | mt | rise | new | pay | top | male | female | -:::tip 提示 +:::tip `time` 参数仅在 `type` 参数选为 **月票榜** 的时候生效。 diff --git a/website/docs/routes/bbs.md b/website/docs/routes/bbs.md index b905eb01b49b10..9136f178c8327b 100644 --- a/website/docs/routes/bbs.md +++ b/website/docs/routes/bbs.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 💬️ BBS ## 19 楼 {#19-lou} @@ -128,7 +126,7 @@ import Route from '@site/src/components/Route'; ## Dcard {#dcard} -:::caution 注意 +:::caution 僅能透過台灣 IP 抓取。 @@ -142,6 +140,18 @@ import Route from '@site/src/components/Route'; +## Discourse {#discourse} + +:::caution + +You need to set the environment variable `DISCOURSE_CONFIG_{id}` before using it. Please refer to Configuration section in the Deploy page of the documentation. + +::: + +### Latest posts {#discourse-latest-posts} + + + ## Discuz {#discuz} ### General Subforum - Auto detection {#discuz-general-subforum---auto-detection} @@ -282,7 +292,7 @@ import Route from '@site/src/components/Route'; ### AV {#playno.1-wan-le-da-ren-av} -:::caution 注意 +:::caution 目前观测到该博客可能禁止日本 IP 访问。建议部署在日本区以外的服务器上。 @@ -438,11 +448,11 @@ When accessing Joeyray's Bar, `SCBOY_BBS_TOKEN` needs to be filled in `environme ### 帖子列表 {#bai-du-tie-ba-tie-zi-lie-biao} - + ### 精品帖子 {#bai-du-tie-ba-jing-pin-tie-zi} - + ### 帖子动态 {#bai-du-tie-ba-tie-zi-dong-tai} @@ -637,7 +647,7 @@ When accessing Joeyray's Bar, `SCBOY_BBS_TOKEN` needs to be filled in `environme | --- | --- | ------ | | nba | cba | soccer | -:::tip 提示 +:::tip 电竞分类参见 [游戏热帖](https://bbs.hupu.com/all-gg) 的对应路由 [`/hupu/all/all-gg`](https://rsshub.app/hupu/all/all-gg)。 @@ -649,7 +659,7 @@ When accessing Joeyray's Bar, `SCBOY_BBS_TOKEN` needs to be filled in `environme -:::tip 提示 +:::tip 更多社区参见 [社区](https://bbs.hupu.com) @@ -661,7 +671,7 @@ When accessing Joeyray's Bar, `SCBOY_BBS_TOKEN` needs to be filled in `environme -:::tip 提示 +:::tip 更多热帖版面参见 [论坛](https://bbs.hupu.com) @@ -997,7 +1007,7 @@ When accessing Joeyray's Bar, `SCBOY_BBS_TOKEN` needs to be filled in `environme -:::tip 提示 +:::tip 尚不支持需要登录访问的版块 @@ -1194,7 +1204,7 @@ When accessing Joeyray's Bar, `SCBOY_BBS_TOKEN` needs to be filled in `environme -:::caution 三个 id 获取方式 +:::tip 三个 id 获取方式 1. 打开 2. 打开控制台 diff --git a/website/docs/routes/blog.md b/website/docs/routes/blog.md index 2f865645fa761f..56efb62c517d48 100644 --- a/website/docs/routes/blog.md +++ b/website/docs/routes/blog.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🖊️️ Blog ## Amazon {#amazon} @@ -48,8 +46,10 @@ import Route from '@site/src/components/Route'; -:::tip 使用说明 +:::tip + Freebuf 的文章页面带有反爬虫机制,所以目前无法获取文章的完整内容。 + ::: @@ -82,7 +82,7 @@ Freebuf 的文章页面带有反爬虫机制,所以目前无法获取文章的 -:::tip 提示 +:::tip username 为博主用户名,而非`xxx.hashnode.dev`中`xxx`所代表的 blog 地址。 @@ -170,7 +170,7 @@ username 为博主用户名,而非`xxx.hashnode.dev`中`xxx`所代表的 blog The List ID is the last part of the URL after `-`, for example, the username in "https://medium.com/@imsingee/list/collection-7e67004f23f9" is `imsingee`, and the ID is `7e67004f23f9`. -:::caution Note +:::caution To access private lists, only self-hosting is supported. @@ -182,7 +182,7 @@ To access private lists, only self-hosting is supported. -:::caution Note +:::caution Personalized recommendations require the cookie value after logging in, so only self-hosting is supported. See the configuration module on the deployment page for details. @@ -194,7 +194,7 @@ Personalized recommendations require the cookie value after logging in, so only -:::caution Note +:::caution Personalized recommendations require the cookie value after logging in, so only self-hosting is supported. See the configuration module on the deployment page for details. @@ -208,7 +208,7 @@ Personalized recommendations require the cookie value after logging in, so only There are many tags, which can be obtained by clicking on a tag from the homepage and looking at the URL. For example, if the URL is `https://medium.com/?tag=web3`, then the tag is `web3`. -:::caution Note +:::caution Personalized recommendations require the cookie value after logging in, so only self-hosting is supported. See the configuration module on the deployment page for details. @@ -397,7 +397,7 @@ Limit the number of entries to be retrieved by adding `?limit=x` to the end of t -:::tip 提示 +:::tip 如 `藝能新聞` 的 `日劇新聞` 分类,路由为 `/jnews/news_drama` @@ -515,7 +515,7 @@ Limit the number of entries to be retrieved by adding `?limit=x` to the end of t -:::tip 提示 +:::tip 在路由末尾处加上 `?limit=限制获取数目` 来限制获取条目数量,默认值为`20` diff --git a/website/docs/routes/design.md b/website/docs/routes/design.md index fe143aa23ed330..61587ab6f73489 100644 --- a/website/docs/routes/design.md +++ b/website/docs/routes/design.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🎨️ Design ## Axis Studios {#axis-studios} @@ -275,7 +273,7 @@ Default is under 'https://www.methodstudios.com/en/features'. 在 **精选** 分类下的 **运营设计** 子分类全部内容基础上,筛选出有 **视频**,且城市选择 **北京**,可直接使用路由 [`/zcool/discover/0/617/1/北京`](https://rsshub.app/zcool/discover/0/617/1/北京) -:::tip 提示 +:::tip 下方仅提供 **分类及其子分类** 参数的代码。**学校** 参数的代码可以在 [站酷发现页](https://www.zcool.com.cn/discover) 中选择跳转后,从浏览器地址栏中找到。 diff --git a/website/docs/routes/finance.md b/website/docs/routes/finance.md index 0c6e1d9ed0d870..7f5a6e6d52e845 100644 --- a/website/docs/routes/finance.md +++ b/website/docs/routes/finance.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 💰 Finance ## AI 财经社 {#ai-cai-jing-she} @@ -79,6 +77,29 @@ import Route from '@site/src/components/Route'; +## DL NEWS {#dl-news} + +### All Articles {#dl-news-all-articles} + + + +### Topic {#dl-news-topic} + + + +| Topic | Link | +|--------------------|---------------------| +| DeFi | defi | +| Fintech/VC/Deals | fintech | +| Llama U | llama-u | +| Markets | markets | +| People & Culture | people-culture | +| Regulation | regulation | +| Snapshot | snapshot | +| Web3 | web3 | + + + ## DT 财经 {#dt-cai-jing} ### 数据洞察 {#dt-cai-jing-shu-ju-dong-cha} @@ -101,6 +122,7 @@ import Route from '@site/src/components/Route'; + ## Finology Insider {#finology-insider} ### Bullets {#finology-insider-bullets} @@ -143,7 +165,7 @@ import Route from '@site/src/components/Route'; -:::note Topic +Topic | Topic | Link | |---------------------|-----------------------| @@ -176,8 +198,6 @@ import Route from '@site/src/components/Route'; | Technology | technology | | Regulatory Bodies | regulatory-bodies | -::: - ## finviz {#finviz} @@ -276,7 +296,7 @@ Language ## TokenInsight {#tokeninsight} -:::tip Tips +:::tip TokenInsight also provides official RSS, you can take a look at . @@ -340,7 +360,7 @@ See filters in [Report](https://www.weforum.org/reports) for Year and Platform t -:::tip 提示 +:::tip 栏目 id 留空则返回快讯,在对应页地址栏 `columnId=` 后可以看到。 diff --git a/website/docs/routes/forecast.md b/website/docs/routes/forecast.md index ab5a5bf940a23d..06f10a30c423e5 100644 --- a/website/docs/routes/forecast.md +++ b/website/docs/routes/forecast.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # ❗️ Forecast and alerts ## BADAN METEOROLOGI, KLIMATOLOGI, DAN GEOFISIKA(Indonesian) {#badan-meteorologi%2C-klimatologi%2C-dan-geofisika(indonesian)} @@ -204,7 +202,7 @@ Please skip the local service area code for `name`, for example `https://outage. | ---- | ---- | ---- | ---- | ---- | | | 红色 | 橙色 | 黄色 | 蓝色 | -:::tip 提示 +:::tip 若订阅全国的全部预警信息,此时路由为 [`/cneb/yjxx`](https://rsshub.app/cneb/yjxx)。 diff --git a/website/docs/routes/game.md b/website/docs/routes/game.md index 315d503992f5f5..b915045164d099 100644 --- a/website/docs/routes/game.md +++ b/website/docs/routes/game.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🎮 Gaming ## 3DMGame {#3dmgame} @@ -268,7 +266,7 @@ Or So the route is [`/itch/games/top-rated/tag-singleplayer`](https://rsshub.app/itch/games/top-rated/tag-singleplayer). -:::tip tips +:::tip You can browse all the tags at [here](https://itch.io/tags). @@ -506,7 +504,7 @@ For instance, in `https://store.steampowered.com/search/?specials=1&term=atelier ## TapTap International {#taptap-international} -:::caution Warning +:::caution Due to the regional restrictions, an RSSHub deployment in China Mainland may not work on accessing the TapTap International Website. @@ -544,7 +542,7 @@ Language Code ## TapTap 中国 {#taptap-zhong-guo} -:::caution 注意 +:::caution 由于区域限制,需要在有国内 IP 的机器上自建才能正常获取 RSS。\ 而对于《TapTap 国际版》则需要部署在具有海外出口的 IP 上才可正常获取 RSS。 @@ -834,7 +832,7 @@ Example:`https://www.iyingdi.com/tz/people/55547` ,id 是 `55547` -:::tip 提示 +:::tip 若订阅 [热点聚焦](https://keylol.com/f161-1),网址为 。截取 `https://keylol.com/` 到末尾的部分 `f161-1` 作为参数,此时路由为 [`/keylol/f161-1`](https://rsshub.app/keylol/f161-1)。 diff --git a/website/docs/routes/government.md b/website/docs/routes/government.md index 90d9fc83524c85..2e4f4cbf39b748 100644 --- a/website/docs/routes/government.md +++ b/website/docs/routes/government.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 📢 Government ## Australia Department of Home Affairs {#australia-department-of-home-affairs} @@ -91,7 +89,7 @@ Category -:::tip Tip +:::tip Fill in the English expression for the month in the Month field, eg `December` for the 12th Month。 @@ -197,7 +195,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://kjt.ah.gov.cn/` 和 `/index.html` 之间的字段。下面是一个例子。 @@ -219,7 +217,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://www.bjsk.org.cn/` 和 `.html` 之间的字段。下面是一个例子。 @@ -465,7 +463,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://www.stats.gov.cn/` 后的字段。下面是一个例子。 @@ -514,7 +512,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://www.nmpa.gov.cn/` 与 `/index.html` 之间的字段,下面是一个例子。 @@ -530,7 +528,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://www.nifdc.gov.cn/nifdc/` 与 `/index.html` 之间的字段,下面是一个例子。 @@ -546,7 +544,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://www.cmde.org.cn/` 与 `/index.html` 之间的字段,下面是一个例子。 @@ -606,7 +604,7 @@ Language -:::tip 提示 +:::tip 若订阅 [基金要闻 - 通知公告](https://www.nsfc.gov.cn/publish/portal0/tab442),网址为 。截取 `https://www.nsfc.gov.cn` 到末尾的部分 `/publish/portal0/tab442` 作为参数,此时路由为 [`/gov/nsfc/publish/portal0/tab442`](https://rsshub.app/gov/nsfc/publish/portal0/tab442)。 @@ -650,7 +648,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://www.sasac.gov.cn/` 与 `/index.html` 之间的字段,下面是一个例子。 @@ -759,7 +757,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中茂名有关政府网站的域名最前面的部分和域名后的字段。下面是一个例子。 @@ -785,7 +783,7 @@ Language 政策解读']}> -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -799,7 +797,7 @@ Language 政策解读']}> -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -813,7 +811,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -827,7 +825,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -841,7 +839,7 @@ Language 政策解读']}> -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -855,7 +853,7 @@ Language 政策解读']}> -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -869,7 +867,7 @@ Language 政策解读']}> -:::tip 提示 +:::tip 路径处填写对应页面 URL 中最前面的部分和域名后的字段。下面是一个例子。 @@ -903,7 +901,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://www.nopss.gov.cn/` 后的字段。下面是一个例子。 @@ -963,7 +961,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://yjj.sh.gov.cn/` 与 `/index.html` 之间的字段,下面是一个例子。 @@ -1002,7 +1000,7 @@ Language | 往期专题 | wqzt | | 区县专题 | qxzt | -:::tip 提示 +:::tip **热点专题**栏目包含**市本级专题**和**区县专题** @@ -1176,7 +1174,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://www.cnnic.net.cn/` 后的字段。下面是一个例子。 @@ -1192,7 +1190,7 @@ Language -:::tip 提示 +:::tip 若订阅 [文职人员 - 工作动态](https://81rc.81.cn/wzry/gzdt),网址为 。截取 `https://81rc.81.cn` 到末尾的部分 `/wzry/gzdt` 作为参数,此时路由为 [`/81/81rc/wzry/gzdt`](https://rsshub.app/81/81rc/wzry/gzdt)。 @@ -1294,7 +1292,7 @@ Language -:::tip 提示 +:::tip 下表分类可能并不完整。请查看各飞行任务详情页获得完整分类。 @@ -1356,10 +1354,12 @@ Language -:::tip 提示 +:::tip + 路径处填写对应页面 URL 中 `http://www.csrc.gov.cn/csrc/` 后的字段。下面是一个例子。 若订阅 [证监会要闻](http://www.csrc.gov.cn/csrc/c100028/common_xq_list.shtml) 则将对应页面 URL 中 `http://www.csrc.gov.cn/csrc/` 后的字段 `c100028/common_xq_list.shtml` 作为路径填入。此时路由为 [`/gov/csrc/news/c100028/common_xq_list.shtml`](https://rsshub.app/gov/csrc/news/c100028/common_xq_list.shtml) + ::: @@ -1592,7 +1592,7 @@ Language -:::caution 注意 +:::caution 由于区域限制,建议在国内 IP 的机器上自建 @@ -1713,7 +1713,7 @@ Language -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://www.ccdi.gov.cn/` 后的字段。下面是一个例子。 @@ -1729,7 +1729,7 @@ Language -:::tip 提示 +:::tip 路径填写对应页面 URL 中间部分。例如: diff --git a/website/docs/routes/journal.md b/website/docs/routes/journal.md index f43ea4ca318287..025a270b30cb4f 100644 --- a/website/docs/routes/journal.md +++ b/website/docs/routes/journal.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🔬 Scientific Journal ## Academy of Management {#academy-of-management} @@ -37,7 +35,7 @@ Return results from 2020 -:::tip Tip +:::tip See [Browse Content](https://pubs.acs.org) @@ -53,7 +51,7 @@ See [Browse Content](https://pubs.acs.org) The URL of the journal [American Economic Review](https://www.aeaweb.org/journals/aer) is `https://www.aeaweb.org/journals/aer`, where `aer` is the id of the journal, so the route for this journal is `/aeaweb/aer`. -:::tip Tip +:::tip More jounals can be found in [AEA Journals](https://www.aeaweb.org/journals). @@ -69,7 +67,7 @@ More jounals can be found in [AEA Journals](https://www.aeaweb.org/journals). Refer to the URL format `pubs.aip.org/:pub/:jrn` -:::tip Tip +:::tip More jounals can be found in [AIP Publications](https://publishing.aip.org/publications/find-the-right-journal). @@ -85,7 +83,7 @@ More jounals can be found in [AIP Publications](https://publishing.aip.org/publi The URL of the journal [Annual Review of Analytical Chemistry](https://www.annualreviews.org/journal/anchem) is `https://www.annualreviews.org/journal/anchem`, where `anchem` is the id of the journal, so the route for this journal is `/annualreviews/anchem`. -:::tip Tip +:::tip More jounals can be found in [Browse Journals](https://www.annualreviews.org/action/showPublications). @@ -288,7 +286,7 @@ Papers that are published in this week. ## Nature Journal {#nature-journal} -:::tip Tips +:::tip You can get all short name of a journal from or [Journal List](#nature-journal-journal-list). @@ -353,7 +351,7 @@ Subscribe to the cover images of the Nature journals, and get the latest publica -:::caution Warning +:::caution Only some journals are supported. @@ -389,8 +387,10 @@ Return results from 2020 -:::tip Tips +:::tip + Some topics require adding `topic/` to `topicPath` like [`/pnas/topic/app-math`](https://rsshub.app/pnas/topic/app-math) and some don't like [`/pnas/biophysics-and-computational-biology`](https://rsshub.app/pnas/biophysics-and-computational-biology) + ::: @@ -401,7 +401,7 @@ Some topics require adding `topic/` to `topicPath` like [`/pnas/topic/app-math`] -:::tip Tip +:::tip For the parameter **filter**, the `filter` parameter in the URL should be split into a string by `,`, here is an example. @@ -491,7 +491,7 @@ Category | -------- | --------- | --------- | ------- | -- | ------------------ | | mobile | internet | boardcast | general | it | industry-resources | -:::tip Tips +:::tip If `country` or `type` includes empty space, use `-` instead. For example, `United States` needs to be replaced with `United-States`, `White paper` needs to be replaced with `White-paper` @@ -571,8 +571,10 @@ Return results from 2020 ### 作者期刊文献 {#zhong-guo-zhi-wang-zuo-zhe-qi-kan-wen-xian} -:::tip 注意 +:::tip + 可能仅限中国大陆服务器访问,以实际情况为准。 + ::: diff --git a/website/docs/routes/live.md b/website/docs/routes/live.md index 892a36338a5bb6..1443d7eae1d841 100644 --- a/website/docs/routes/live.md +++ b/website/docs/routes/live.md @@ -1,4 +1,3 @@ -import Route from '@site/src/components/Route'; # 🎥 Live @@ -52,7 +51,7 @@ import Route from '@site/src/components/Route'; -:::caution 注意 +:::caution 由于接口未提供开播时间,如果直播间未更换标题与分区,将视为一次。如果直播间更换分区与标题,将视为另一项 diff --git a/website/docs/routes/multimedia.md b/website/docs/routes/multimedia.md index 6f563d252fcf1b..50fd691be6f974 100644 --- a/website/docs/routes/multimedia.md +++ b/website/docs/routes/multimedia.md @@ -1,10 +1,8 @@ -import Route from '@site/src/components/Route'; - # 🔊 Multimedia ## 141JAV {#141jav} -:::tip 提示 +:::tip 官方提供的订阅源不支持 BT 下载订阅,地址为 @@ -52,7 +50,7 @@ import Route from '@site/src/components/Route'; ## 141PPV {#141ppv} -:::tip 提示 +:::tip 官方提供的订阅源不支持 BT 下载订阅,地址为 @@ -148,7 +146,7 @@ import Route from '@site/src/components/Route'; -:::tip 提示 +:::tip 若订阅 [最新 4K 电影](https://www.4ksj.com/forum-2-1.html),网址为 。截取 `https://www.4ksj.com/forum-` 到末尾 `.html` 的部分 `2-1` 作为参数,此时路由为 [`/4ksj/forum/2-1`](https://rsshub.app/4ksj/forum/2-1)。 @@ -249,7 +247,7 @@ When `uncensored_makersr` as **Uncensored** is chosen as **Category**, the avail ## 91porn {#91porn} -:::tip Tips +:::tip 91porn has multiple backup domains, routes use the permanent domain by default. If the domain is not accessible, you can add `?domain=` to specify the domain to be used. If you want to specify the backup domain to , you can add `?domain=0122.91p30.com` to the end of all 91porn routes, then the route will become [`/91porn?domain=0122.91p30.com`](https://rsshub.app/91porn?domain=0122.91p30.com) @@ -283,7 +281,8 @@ When `uncensored_makersr` as **Uncensored** is chosen as **Category**, the avail ### 演员 {#av01%EF%BC%88av01.tv%EF%BC%89-yan-yuan} -:::tip 提示 +:::tip + 当没有给定排序类型时,默认为按上传时间排序及 mr ::: @@ -334,7 +333,7 @@ When `uncensored_makersr` as **Uncensored** is chosen as **Category**, the avail -:::tip 提示 +:::tip 分类页中域名末尾到 `.htm` 前的字段即为对应分类,如 [电影](https://www.btbtt20.com/forum-index-fid-951.htm) 中域名末尾到 `.htm` 前的字段为 `forum-index-fid-951`,所以路由应为 [`/btzj/forum-index-fid-951`](https://rsshub.app/btzj/forum-index-fid-951) @@ -360,7 +359,7 @@ When `uncensored_makersr` as **Uncensored** is chosen as **Category**, the avail | -------------------- | -------------------- | | forum-index-fid-1187 | forum-index-fid-1191 | -:::tip 提示 +:::tip BT 之家的域名会变更,本路由以 为默认域名,若该域名无法访问,可以通过在路由后方加上 `?domain=<域名>` 指定路由访问的域名。如指定域名为 ,则在 `/btzj` 后加上 `?domain=btbtt15.com` 即可,此时路由为 [`/btzj?domain=btbtt15.com`](https://rsshub.app/btzj?domain=btbtt15.com) @@ -382,7 +381,7 @@ BT 之家的域名会变更,本路由以 为默认 -:::tip 提示 +:::tip 由于 BT 之家域名有多个。此 feed 对应[`https://www.88btbtt.com`](https://www.88btbtt.com)域名和[`http://www.2btjia.com/`](http://www.2btjia.com/)域名. 可空,默认为 base @@ -393,7 +392,7 @@ BT 之家的域名会变更,本路由以 为默认 ### 栏目 {#cntv-lan-mu} -:::tip 提示 +:::tip 栏目 ID 查找示例: 打开栏目具体某一期页面,F12 控制台输入`column_id`得到栏目 ID。 @@ -431,7 +430,9 @@ BT 之家的域名会变更,本路由以 为默认 :::tip + 由于大部分详情页是 `/html/xxx.html`,还有部分是 `/detail/123.html`,所以此处做了兼容,id 取 `xxx` 或者 `123` 都可以。 + ::: ## E-Hentai {#e-hentai} @@ -440,7 +441,7 @@ BT 之家的域名会变更,本路由以 为默认 -:::tip 提示 +:::tip 参数 **需要输出种子文件** 设置为 `true` `yes` `t` `y` 等值后,RSS 会携带种子文件的路径,以供支持 RSS 的下载工具订阅下载。 @@ -468,7 +469,7 @@ BT 之家的域名会变更,本路由以 为默认 -:::tip 提示 +:::tip 参数 **需要输出种子文件**、**需要显示大图** 的说明同上,以下是一个例子: @@ -482,7 +483,7 @@ BT 之家的域名会变更,本路由以 为默认 -:::tip 提示 +:::tip 参数 **需要输出种子文件**、**需要显示大图** 的说明同上,以下是一个例子: @@ -540,7 +541,7 @@ Official RSS: -:::tip Tip +:::tip If you subscribe to [イヤーマイッタマイッタ](https://www.ibc.co.jp/radio/maitta/audio), the URL is . Intercept `maitta` between `https://www.ibc.co.jp/radio/` and `/audio/` as an argument, then the route will be [`/ibc/radio/maitta`](https://rsshub.app/ibc/radio/maitta). @@ -562,7 +563,7 @@ You can change the language of each route to the languages listed below. ::: -:::tip Tips +:::tip JavBus has multiple backup domains, these routes use default domain . If the domain is unreachable, you can add `?domain=` to the end of the route to specify the domain to visit. Let say you want to use the backup domain , you can add `?domain=javsee.icu` to the end of the route, then the route will be [`/javbus/en?domain=javsee.icu`](https://rsshub.app/javbus?domain=javsee.icu) @@ -676,7 +677,7 @@ For more actresses [Western AV Idols](https://www.javbus.org/en/actresses) ## JavDB {#javdb} -:::tip 提示 +:::tip JavDB 有多个备用域名,本路由默认使用永久域名 ,若该域名无法访问,可以通过在路由最后加上 `?domain=<域名>` 指定路由访问的域名。如指定备用域名为 ,则在所有 JavDB 路由最后加上 `?domain=javdb36.com` 即可,此时路由为 [`/javdb?domain=javdb36.com`](https://rsshub.app/javdb?domain=javdb36.com) @@ -686,7 +687,7 @@ JavDB 有多个备用域名,本路由默认使用永久域名 -:::tip 提示 +:::tip 在 [分類](https://javdb.com/tags) 中选定分类后,URL 中 `tags?` 后的字段即为筛选参数。 @@ -886,7 +887,7 @@ JavDB 有多个备用域名,本路由默认使用永久域名 + + +:::tip -| 最近更新 | 剧集推荐 | 电影推荐 | 纪录片推荐 | 动画推荐 | 真人秀推荐 | -| -------- | -------- | -------- | ---------- | -------- | ---------- | -| 1 | 2 | 3 | 4 | 5 | 6 | +`downLinkType` 参数指下载链接类型,默认为 **磁力链**。网站提供的下载链接类型包括但不限于 **磁力链**、**百度网盘**、**阿里云盘**、**夸克网盘**、**UC网盘** 等。若无法找到指定类型的下载链接,将会返回第 1 条下载链接。 + +与其他路由不同的是,本路由的 `limit` 参数作用于获取剧集数量,所以返回的总条目数根据每次获取的剧集所包含的条目变更而不同。 + +::: + +| 制作中 | 最近更新 | 剧集推荐 | 电影推荐 | 纪录片推荐 | 动画推荐 | 真人秀推荐 | +| ------ | -------- | -------- | -------- | ---------- | -------- | ---------- | +| 0 | 1 | 2 | 3 | 4 | 5 | 6 | ### 指定剧集 {#new-zi-mu-zu-zhi-ding-ju-ji} - + + +:::tip + +[雪国列车(剧版)](https://nzmz.xyz/details-qEzRyY3v.html) 的下载页 URL 为 ,即剧集 id 为 `qEzRyY3v` -如:雪国列车(剧版)的下载页 URL 为 `https://ysfx.tv/view/qEzRyY3v.html`,即剧集 id 为 `qEzRyY3v`。 +::: @@ -1056,7 +1069,7 @@ See [Directory](https://www.javlibrary.com/en/star_list.php) to view all stars. ## OneJAV {#onejav} -:::tip 提示 +:::tip 官方提供的订阅源不支持 BT 下载订阅,地址为 @@ -1248,7 +1261,7 @@ Refer to [Pornhub F.A.Qs](https://help.pornhub.com/hc/en-us/articles/36004432703 ## The Movie Database {#the-movie-database} -:::tip Tips +:::tip Refer to for the language parameter in the route. @@ -1342,15 +1355,17 @@ When `mediaType` is `movie`, `sheet` should be: -:::tip 提示 +:::tip + 可抓取內容根据服务器所在地区而定 + ::: ## 哔嘀影视 {#bi-di-ying-shi} -:::tip 提示 +:::tip 哔嘀影视有多个备用域名,路由默认使用域名 。若该域名无法访问,可以通过在路由最后加上 `?domain=<域名>` 指定路由访问的域名。如指定备用域名为 ,则在所有哔嘀影视路由最后加上 `?domain=bde4.icu` 即可,此时路由为 [`/bdys?domain=bde4.icu`](https://rsshub.app/bdys?domain=bde4.icu) @@ -1448,7 +1463,7 @@ When `mediaType` is `movie`, `sheet` should be: -:::tip 提示 +:::tip 帖子 id 查找办法: @@ -1740,9 +1755,10 @@ When `mediaType` is `movie`, `sheet` should be: ## 网易云音乐 {#wang-yi-yun-yin-yue} -:::tip 部分歌单及听歌排行信息为登陆后可见 +:::tip 部分歌单及听歌排行信息为登陆后可见,自建时将环境变量`NCM_COOKIES`设为登陆后的 Cookie 值,即可正常获取。 + ::: ### 歌单歌曲 {#wang-yi-yun-yin-yue-ge-dan-ge-qu} @@ -1793,10 +1809,12 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 目前喜马拉雅的 API 只能一集一集的获取各节目上的 ShowNote,会极大的占用系统资源,所以默认为不获取节目的 ShowNote。下方有一个新的路径可选获取 ShowNote。 -:::caution 注意 +:::caution + 专辑类型即 url 中的分类拼音,使用通用分类 `album` 通常是可行的,专辑 id 是跟在**分类拼音**后的那个 id, 不要输成某集的 id 了 **付费内容需要配置好已购买账户的 token 才能收听,详情见部署页面的配置模块** + ::: @@ -1813,7 +1831,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 -:::caution 注意 +:::caution 小宇宙的 api 需要验证 `x-jike-device-id`、`x-jike-access-token` 和 `x-jike-refresh-token` 。必要时需要自行配置,具体见部署文档。 @@ -1841,7 +1859,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 所以对应路由为 [`/radio/album/15682090498666`](https://rsshub.app/radio/album/15682090498666) -:::tip 提示 +:::tip 部分专辑不适用该路由,此时可以尝试 [节目](#yun-ting-jie-mu) 路由 @@ -1857,7 +1875,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 所以对应路由为 [`/radio/1552135`](https://rsshub.app/radio/1552135) -:::tip 提示 +:::tip 该路由仅适用于更新时间较早的电台节目,如 [共和国追梦人](http://www.radio.cn/pc-portal/sanji/detail.html?columnId=1552135) @@ -1875,7 +1893,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 所以对应路由为 [`/radio/zhibo/1395528`](https://rsshub.app/radio/zhibo/1395528) -:::tip 提示 +:::tip 查看更多电台直播节目,可前往 [电台直播](http://www.radio.cn/pc-portal/erji/radioStation.html) @@ -1907,7 +1925,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 ## 中文播客榜 {#zhong-wen-bo-ke-bang} -:::tip 提示 +:::tip 可以通过指定 `limit` 参数确定榜单排名下限,默认为 250。 @@ -1963,7 +1981,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 ### 影视 {#zi-mu-zu-%EF%BC%88zimuzu.tv%EF%BC%89-ying-shi} -:::tip 提示 +:::tip 跟官方提供的 RSS 相比:官方使用了不规范的 magnet 字段,无法被 BT 客户端识别并自动下载,其他数据相同 diff --git a/website/docs/routes/new-media.md b/website/docs/routes/new-media.md index 7f3c9bb3b77193..6f7f021e816987 100644 --- a/website/docs/routes/new-media.md +++ b/website/docs/routes/new-media.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 📱 New media ## 199IT {#199it} @@ -96,7 +94,7 @@ import Route from '@site/src/components/Route'; 访问 “邱毅看平潭” 专题,会跳转到 。其中 `F1626082387819` 即为 **专题 id** 对应的地区代码。 -:::tip 提示 +:::tip 更多的专题可以点击 [这里](https://www.52hrtt.com/global/n/w/symposium) @@ -209,7 +207,7 @@ Supported categories: Philosophy, Science, Psychology, Society, and Culture. -:::tip 提示 +:::tip 若订阅 [每日热点 - 最新](https://bad.news/tag/每日热点/sort-new),网址为 [https://bad.news/tag/ 每日热点 /sort-new](https://bad.news/tag/每日热点/sort-new)。截取 `https://bad.news` 到末尾的部分 `/tag/每日热点/sort-new` 作为参数,此时路由为 [`/bad/tag/每日热点/sort-new`](https://rsshub.app/bad/tag/每日热点/sort-new)。 @@ -348,7 +346,7 @@ Category of news -:::tip 提示 +:::tip 完整的主题列表参见 [主题列表](https://www.cnbeta.com.tw/topics.htm) @@ -494,7 +492,7 @@ Category of news -:::note Categories +Categories | España | Internacional | Economía | Deportes | | -------- | ------------- | -------- | -------- | @@ -528,8 +526,6 @@ Category of news | ------ | --------------- | | murcia | ceuta-y-melilla | -::: - ## ezone.hk {#ezone.hk} @@ -754,7 +750,7 @@ Tag -:::note Topics +Topics | Topic Name | Topic Link | |---------------------|---------------------| @@ -800,8 +796,6 @@ Tag | Updates | updates | | Video | video | -::: - ## Grub Street {#grub-street} @@ -820,7 +814,7 @@ Tag | ------ | ------- | -------------- | ------- | | Latest | Popular | From the Store | For You | -:::tip Tip +:::tip Click here to view [All Topics](https://hbr.org/topics) @@ -1086,7 +1080,7 @@ Edition ## Matataki {#matataki} -:::tip 提示 +:::tip 在 Matataki 发表的文章会上传到星际文件系统(IPFS),永久保存。即使站内文章因为各种原因消失,用 RSS 获取过带 IPFS 连接的 Feed Item 的话,还是可以从 RSS 阅读器找回文章的。 IPFS 网关有可能失效,那时候换成其他网关。 @@ -1512,7 +1506,7 @@ Compared to the official one, this feed: -:::note Member ID +Member ID | Member ID | Name | | --------- | --------------------- | @@ -1557,8 +1551,6 @@ Compared to the official one, this feed: | 36749 | 伊藤 理々杏 | | 264 | 齋藤 飛鳥 | -::: - ### Keyakizaka46 News 欅坂 46 新闻 {#sakamichi-series-ban-dao-xi-lie-guan-wang-zi-xun-keyakizaka46-news-ju-ban-46-xin-wen} @@ -1577,7 +1569,7 @@ Compared to the official one, this feed: -:::note Member ID +Member ID | Member ID | Name | | --------- | ------------ | @@ -1616,8 +1608,6 @@ Compared to the official one, this feed: | 04 | 尾関 梨香 | | 03 | 上村 莉菜 | -::: - ### Hinatazaka46 News 日向坂 46 新闻 {#sakamichi-series-ban-dao-xi-lie-guan-wang-zi-xun-hinatazaka46-news-ri-xiang-ban-46-xin-wen} @@ -1628,7 +1618,7 @@ Compared to the official one, this feed: -:::note Member ID +Member ID | Member ID | Name | | --------- | ------------ | @@ -1668,8 +1658,6 @@ Compared to the official one, this feed: > Note: The personal blogs of the fourth-generation members have not been opened yet. The unified blog number is `2000`. -::: - ## Samsung {#samsung} @@ -1995,7 +1983,7 @@ Supported sub-sites: -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://web3caff.com/` 后的字段。下面是一个例子。 @@ -2031,7 +2019,7 @@ Supported sub-sites: -:::tip 提示 +:::tip 全部站点请见 [此处](https://hot.zyw.asia/#/list) @@ -2059,7 +2047,7 @@ Supported sub-sites: -:::tip 提示 +:::tip 默认抓取前 20 条,可通过 `?limit=` 改变。 @@ -2182,7 +2170,7 @@ Supported sub-sites: -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://www.bast.net.cn/` 后的字段。下面是两个例子。 @@ -2502,7 +2490,7 @@ area 分区选项 查看湖北省武汉市武昌区的新冠疫苗接种点,路由为 `/dxy/vaccine/湖北/武汉/武昌区`。 -:::tip 提示 +:::tip 若参数为空,则返回全国所有新冠疫苗接种点。 @@ -2575,7 +2563,7 @@ area 分区选项 ## 懂球帝 {#dong-qiu-di} -:::tip 提示 +:::tip - 可以通过头条新闻 + 参数过滤的形式获得早报、专题等内容。 @@ -2605,7 +2593,7 @@ area 分区选项 -:::tip 提示 +:::tip 部分球队和球员可能会有两个 id, 正确 id 应该由 `5000` 开头. @@ -2627,7 +2615,7 @@ area 分区选项 通过提取文章全文,以提供比官方源更佳的阅读体验。 -:::caution 注意 +:::caution 付费内容全文可能需要登陆获取,详情见部署页面的配置模块。 @@ -2659,7 +2647,7 @@ Type 栏目: -:::caution 注意 +:::caution 需要自建,详情见部署页面的配置模块。 @@ -2717,7 +2705,7 @@ Type 栏目: | -------- | ------------- | -------- | ----------- | | articles | localarticles | history | all-comment | -:::tip 提示 +:::tip 支持形如 的路由,即 [`/storm/category/118`](https://rsshub.app/storm/category/118) @@ -2733,7 +2721,7 @@ Type 栏目: -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://news.ifeng.com/` 后的字段。下面是一个例子。 @@ -2815,7 +2803,7 @@ home = 评论 & 研究 + 要闻 + 风闻 others = 热点新闻 + 滚动新闻 -:::tip 提示 +:::tip 观察者网首页左中右的三个 column 分别对应 **评论 & 研究**、**要闻**、**风闻** 三个部分。 @@ -2841,7 +2829,7 @@ others = 热点新闻 + 滚动新闻 | -------- | -------- | ----------- | -------- | -------- | ---------- | -------- | | 1 | 2 | 3 | 6 | 7 | 8 | 5 | -:::tip 提示 +:::tip 仅在话题 id 为 0,即选择 全部 时,**3 个月最热**、**24 小时最热**、**3 天最热**、**7 天最热** 和 **专栏文章** 参数生效。 @@ -3009,7 +2997,7 @@ others = 热点新闻 + 滚动新闻 -:::tip 提示 +:::tip 若订阅 [标签:妖](https://www.cbaigui.com/post-tag/妖),网址为 [https://www.cbaigui.com/post-tag/ 妖](https://www.cbaigui.com/post-tag/妖)。截取 `https://www.cbaigui.com` 到末尾的部分 `/post-tag/妖` 作为参数,此时路由为 [`/cbaigui/post-tag/妖`](https://rsshub.app/cbaigui/post-tag/妖)。 @@ -3065,6 +3053,12 @@ others = 热点新闻 + 滚动新闻 ## 今日热榜 {#jin-ri-re-bang} +:::caution + +由于需要登录后的 Cookie 值才能获取原始链接,所以需要自建,需要在环境变量中配置 `TOPHUB_COOKIE`,详情见部署页面的配置模块。 + +::: + ### 榜单 {#jin-ri-re-bang-bang-dan} @@ -3133,7 +3127,7 @@ column 为 third 时可选的 category: | ---- | ------------- | ------------- | ------------- | ------------- | ------------- | | all | category_lsgg | category_dqgg | category_zjjg | category_cxpl | category_scpl | -:::tip 提示 +:::tip 需要筛选多个 category 时,应使用 `;` 将多个字段连接起来。 @@ -3215,7 +3209,7 @@ column 为 third 时可选的 category: -:::tip 提示 +:::tip 使用 **类型** 表中的两个参数时,编号应留空,如:**最新** 为 [`/mydrivers/new`](https://rsshub.app/mydrivers/new) @@ -3430,7 +3424,7 @@ column 为 third 时可选的 category: | -------- | -------- | | enter4 | life3 | -:::tip 提示 +:::tip 酷 18 文档参见 [此处](https://docs.rsshub.app/picture#ku-18) @@ -3457,7 +3451,7 @@ column 为 third 时可选的 category: | newspark | local | | -------- | ----- | -:::tip 提示 +:::tip 若订阅 [时政](https://www.6parknews.com/newspark/index.php?type=1),其网址为 ,其中 `newspark` 为分站,`1` 为栏目 id。 @@ -3513,7 +3507,7 @@ column 为 third 时可选的 category: | ------------ | ----------- | ---------- | -------- | -------- | -------- | | breakingnews | weeklytopic | culture | press | case | special | -:::tip 提示 +:::tip 除了直接订阅分类全部文章(如 [每週專題](https://aamacau.com/topics/weeklytopic) 的对应路由为 [/aamacau/weeklytopic](https://rsshub.app/aamacau/weeklytopic)),你也可以订阅特定的专题,如 [【9-12】2021 澳門立法會選舉](https://aamacau.com/topics/【9-12】2021澳門立法會選舉) 的对应路由为 [/【9-12】2021 澳門立法會選舉](https://rsshub.app/aamacau/【9-12】2021澳門立法會選舉)。 @@ -3601,7 +3595,7 @@ column 为 third 时可选的 category: -:::tip 提示 +:::tip 下表为科室对应的 sid,若想获得 tid,可以到对应科室页面 URL 中寻找 `t_id` 字段的值,下面是一个例子: @@ -3787,8 +3781,10 @@ column 为 third 时可选的 category: - `fulltext`,全文输出,例如:`/pingwest/tag/ChinaJoy/1/fulltext` -:::tip 提示 +:::tip + 该路由一次最多显示 30 条文章 + ::: @@ -4372,7 +4368,7 @@ column 为 third 时可选的 category: ## 网易新闻 {#wang-yi-xin-wen} -:::caution 注意 +:::caution 若视频因防盗链而无法播放,请参考 [通用参数 -> 多媒体处理](/parameter#多媒体处理) 配置 `multimedia_hotlink_template` **或** `wrap_multimedia_in_iframe`。 @@ -4382,7 +4378,7 @@ column 为 third 时可选的 category: -:::tip 提示 +:::tip 参数 **需要获取全文** 设置为 `true` `yes` `t` `y` 等值后,RSS 会携带该新闻条目的对应全文。 @@ -4394,7 +4390,7 @@ column 为 third 时可选的 category: -:::tip 提示 +:::tip 全站新闻 **点击榜** 的统计时间仅包含 “24 小时”、“本周”、“本月”,不包含 “1 小时”。即可用的`time`参数为`day`、`week`、`month`。 @@ -4446,7 +4442,7 @@ column 为 third 时可选的 category: ## 微信 {#wei-xin} -:::tip 提示 +:::tip 公众号直接抓取困难,故目前提供几种间接抓取方案,请自行选择 @@ -4470,13 +4466,13 @@ column 为 third 时可选的 category: | `1` | 公众号全名 | 未启用 efb-patch-middleware | | `2` | #公众号全名 | 已启用 efb-patch-middleware | -:::tip 提示 +:::tip 启用搜索有助于在订阅了过多公众号的频道里有效筛选,不易因为大量公众号同时推送导致一些公众号消息被遗漏,但必须正确选择搜索查询类型,否则会搜索失败。 ::: -:::caution 注意 +:::caution 该方法需要通过 efb 进行频道绑定,具体操作见 @@ -4526,7 +4522,7 @@ column 为 third 时可选的 category: -:::caution 注意 +:::caution 由于使用了一些针对反爬的缓解措施,本路由响应较慢。默认只抓取前 5 条,可通过 `?limit=` 改变(不推荐,容易被反爬)。\ 该网站使用 IP 甄别访客,且应用严格的每日阅读量限额(约 15 次),请自建并确保正确配置缓存;如使用内存缓存而非 Redis 缓存,请增大缓存容量。该限额足够订阅至少 3 个公众号 (假设公众号每日仅更新一次);首页 / 分类页更新相当频繁,不推荐订阅。 @@ -4639,7 +4635,7 @@ column 为 third 时可选的 category: -:::tip 提示 +:::tip 标签名参见 [所有标签](https://review.proletar.ink/tags) @@ -5230,4 +5226,3 @@ QueryString: ### 公众号 {#zi-you-wei-xin-gong-zhong-hao} - diff --git a/website/docs/routes/other.md b/website/docs/routes/other.md index f23cbdd43e4687..2efe2767f8ecf9 100644 --- a/website/docs/routes/other.md +++ b/website/docs/routes/other.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🔍 Uncategorized ## 4399 论坛 {#4399-lun-tan} @@ -8,7 +6,7 @@ import Route from '@site/src/components/Route'; -:::caution 注意 +:::caution 需要用户 cookie 值,详情见部署页面的配置模块。 @@ -22,7 +20,7 @@ import Route from '@site/src/components/Route'; -:::tip Tip +:::tip Copy the URL of the 591 filter housing page and remove the front part "?", you will get the query parameters. @@ -478,7 +476,7 @@ For example: ## Notion {#notion} -:::caution Warning +:::caution Need to set up Notion integration, please refer to [Route-specific Configurations](https://docs.rsshub.app/install/#Deployment) for details. @@ -619,7 +617,7 @@ Specify options (in the format of query string) in parameter `routeParams` param | `itemLink` | The JSON Path as `link` in `item` | `string` | None | | `itemDesc` | The JSON Path as `description` in `item` | `string` | None | -:::tip Note +:::tip JSON Path only supports format like `a.b.c`. if you need to access arrays, like `a[0].b`, you can write it as `a.0.b`. @@ -681,8 +679,10 @@ Board and Build can be found in [here](http://api.ineal.me/tss/status) -::: +:::tip + type 为 all 时,category 参数不支持 cost 和 free + ::: | 全部 | 祖源分析 | 付费 | 遗传性疾病 | 药物指南 | 免费 | 运动基因 | 营养代谢 | 心理特质 | 健康风险 | 皮肤特性 | 遗传特征 | @@ -817,7 +817,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate ### 习惯打卡 {#di-da-qing-dan-xi-guan-da-ka} -:::caution 注意 +:::caution 需要账号密码,详情见部署文档部分 RSS 模块配置 @@ -929,7 +929,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate 快递公司代号如果不能确定,可通过下方快递列表获得。 -:::caution 注意 +:::caution 1. 构造链接前请确认所有参数正确:错误`快递公司 - 订单号`组合将会缓存信息一小段时间防止产生无用查询 2. 正常查询的订单在未签收状态下不会被缓存:请控制查询频率 @@ -1035,7 +1035,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `http://www.qiyoujiage.com/` 和 `.shtml` 之间的字段。下面是一个例子。 diff --git a/website/docs/routes/picture.md b/website/docs/routes/picture.md index c27fc8ad2f703b..ad8ef530baab1c 100644 --- a/website/docs/routes/picture.md +++ b/website/docs/routes/picture.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🖼️ Picture ## 1X {#1x} @@ -373,7 +371,7 @@ For example: -:::tip 提示 +:::tip [NASA 中文](https://www.nasachina.cn/) 提供了每日天文图的中英双语图文说明,但在更新上偶尔略有一两天的延迟。 @@ -429,7 +427,7 @@ For example: ## wallhaven {#wallhaven} -:::tip Tip +:::tip When parameter **Need Details** is set to `true` `yes` `t` `y`, RSS will add the title, uploader, upload time, and category information of each image, which can support the filtering function of RSS reader. @@ -453,7 +451,7 @@ For example [Latest Wallpapers](https://wallhaven.cc/latest), the route turning -:::tip Tip +:::tip Subscribe pages starting with `https://wallhaven.cc/search`, fill the text after `?` as `filter` in the route. The following is an example: @@ -558,7 +556,7 @@ For example: | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | bbs | bbs7 | bbs2 | bbs6 | bbs4 | bj | bbs5 | bbs3 | -:::tip 提示 +:::tip 留园网文档参见 [此处](https://docs.rsshub.app/routes/new-media#liu-yuan-wang) diff --git a/website/docs/routes/program-update.md b/website/docs/routes/program-update.md index 8bfcf9fccabea5..180acc76ff8553 100644 --- a/website/docs/routes/program-update.md +++ b/website/docs/routes/program-update.md @@ -1,4 +1,3 @@ -import Route from '@site/src/components/Route'; # 🔄 Application Updates @@ -381,8 +380,10 @@ Language ## Logseq {#logseq} :::caution + Logseq 开发团队已经放弃了 [旧网站](https://logseq.com/blog)。 请使用 代替。 + ::: ## MacKed {#macked} diff --git a/website/docs/routes/programming.md b/website/docs/routes/programming.md index 6c506fd9d66b99..c7a74910a63715 100644 --- a/website/docs/routes/programming.md +++ b/website/docs/routes/programming.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 💻 Programming ## A List Apart {#a-list-apart} @@ -14,8 +12,6 @@ import Route from '@site/src/components/Route'; You have the option to utilize the main heading or use individual categories as topics for the path. -:::note Topics - | **Code** | _code_ | |-------------------------|-------------------------| | **Application Development** | _application-development_ | @@ -62,8 +58,6 @@ You have the option to utilize the main heading or use individual categories as | **Usability** | _usability_ | | **User Research** | _user-research_ | -::: - ## ACM {#acm} @@ -822,8 +816,6 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News -:::note Category - | **Category** | | |----------------------|-----------------------| | Accessibility | accessibility | @@ -860,8 +852,6 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News | Web Design | web-design | | Workflow | workflow | -::: - ## TesterHome {#testerhome} @@ -946,7 +936,7 @@ Stay up to date on the latest React news, tutorials, resources, and more. Delive ## 安全客 {#an-quan-ke} -:::tip 提示 +:::tip 官方提供了混合的主页资讯 RSS: @@ -1197,7 +1187,7 @@ Stay up to date on the latest React news, tutorials, resources, and more. Delive ## 拉勾网 {#la-gou-wang} -:::tip 提示 +:::tip 拉勾网官方提供职位的[邮件订阅](https://www.lagou.com/s/subscribe.html),请根据自身需要选择使用。 @@ -1422,7 +1412,7 @@ Stay up to date on the latest React news, tutorials, resources, and more. Delive ## 腾讯游戏开发者社区 {#teng-xun-you-xi-kai-fa-zhe-she-qu} -:::caution 注意 +:::caution 有部分输出全文带有未进行样式处理的代码内容,显示效果不佳,建议跳转原文阅读 diff --git a/website/docs/routes/reading.md b/website/docs/routes/reading.md index 43b1eec46eb8a3..af2139dea70838 100644 --- a/website/docs/routes/reading.md +++ b/website/docs/routes/reading.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 📚 Reading ## All Poetry {#all-poetry} @@ -178,7 +176,7 @@ Eg: -:::tip 提示 +:::tip 更多专题请见 [关键词](http://www.aisixiang.com/zhuanti/) @@ -213,7 +211,7 @@ Eg: ## 笔趣阁 {#bi-qu-ge} -:::tip 看我 +:::tip 此处的 **笔趣阁** 指网络上使用和 **笔趣阁** 样式相似模板的小说阅读网站,包括但不限于下方列举的网址。 @@ -241,7 +239,7 @@ Eg: -:::tip 看我 +:::tip #### 使用方法 @@ -259,7 +257,7 @@ Eg: ::: -:::caution 提示 +:::caution 上方列举的网址可能部分不可用,这取决于该网站的维护者是否持续运营网站。请选择可以正常访问的网址,获取更新的前提是该网站可以正常访问。 @@ -279,7 +277,7 @@ Eg: -:::tip 看我 +:::tip 全部期刊可以在 [这里](http://qk.chaoxing.com/space/index) 找到,你也可以从 [学科分类](https://qikan.chaoxing.com/jourclassify) 和 [期刊导航](https://qikan.chaoxing.com/search/openmag) 中发现更多期刊。 @@ -287,7 +285,7 @@ Eg: ::: -:::caution 提示 +:::caution 你可以设置参数 **需要获取文章全文** 为 `true` `yes` `t` `y` 等值(或者忽略这个参数),RSS 的条目会携带期刊中的 **文章全文**,而不仅仅是 **文章概要**。但因为发起访问请求过多会被该网站屏蔽,你可以将其关闭(设置该参数为 `false` `no` `f` `n` 等值),这将会大大减少请求次数从而更难触发网站的反爬机制。 @@ -305,9 +303,10 @@ Eg: -:::caution 注意 +:::caution 正文内容需要用户登录后的 x-member 值,详情见部署页面的配置模块。若无相关配置或 x-member 失效,则只显示文章摘要。 + ::: @@ -340,7 +339,7 @@ Eg: -:::caution 注意 +:::caution count 的取值范围为 1-12,为防止请求次数过多,推荐设置为 5 以下。 ::: @@ -464,7 +463,7 @@ count 的取值范围为 1-12,为防止请求次数过多,推荐设置为 5 -:::tip 提示 +:::tip 参数 **是否查看历史榜单** 设置为 `true` `yes` `t` `y` 等值后,RSS 会返回历史榜单。 @@ -500,7 +499,7 @@ count 的取值范围为 1-12,为防止请求次数过多,推荐设置为 5 -:::caution 注意 +:::caution 首页需要登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 diff --git a/website/docs/routes/shopping.md b/website/docs/routes/shopping.md index 81e342226998a8..c69ac6a4ea85fe 100644 --- a/website/docs/routes/shopping.md +++ b/website/docs/routes/shopping.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🛍️ Shopping ## 0818 团 {#0818-tuan} @@ -38,7 +36,7 @@ Time | ------------------- | --------------- | ------------ | | 24h | week | alltime | -:::tip Tip +:::tip Parameter `time` only works when `mostwanted` is chosen as the category. @@ -362,7 +360,7 @@ For instance, in -:::tip 提示 +:::tip 如商品 中的 id 为 `526835`,所以路由为 [`/jd/price/526835`](https://rsshub.app/jd/price/526835) @@ -449,7 +447,7 @@ For instance, in diff --git a/website/docs/routes/social-media.md b/website/docs/routes/social-media.md index 021cc841ce196c..63d829bea3efce 100644 --- a/website/docs/routes/social-media.md +++ b/website/docs/routes/social-media.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 💬 Social Media ## 755 {#755} @@ -70,7 +68,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 -:::caution 注意 +:::caution UP 主粉丝现在需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -82,7 +80,7 @@ UP 主粉丝现在需要 b 站登录后的 Cookie 值,所以只能自建,详 -:::caution 注意 +:::caution UP 主关注用户现在需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -250,7 +248,7 @@ UP 主关注用户现在需要 b 站登录后的 Cookie 值,所以只能自建 -:::caution 注意 +:::caution 用户动态需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -262,7 +260,7 @@ UP 主关注用户现在需要 b 站登录后的 Cookie 值,所以只能自建 -:::caution 注意 +:::caution 用户动态需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -274,7 +272,7 @@ UP 主关注用户现在需要 b 站登录后的 Cookie 值,所以只能自建 -:::caution 注意 +:::caution 用户动态需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -354,7 +352,7 @@ UP 主关注用户现在需要 b 站登录后的 Cookie 值,所以只能自建 -:::caution 注意 +:::caution 用户追漫需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -556,8 +554,10 @@ If you don't want to setup credentials, you can use [Picnob](#picnob) or [Picuki | ------------- | ------- | | user | tags | -:::tip Tips +:::tip + It's highly recommended to deploy with Redis cache enabled. + ::: @@ -788,7 +788,7 @@ Only for self-hosted -:::tip 提示 +:::tip 提供不同内容的 `pid`, 可以得到不同的热门瞬间推荐,如果想看多个种类的热门可以用 `/` 把不同的 `pid` 连起来,例如: `NXJiSlM5V21kamJWVlgvZUh1NEExdz09/MkM0amxSTUNiTEpLcHhzSlRzTEI1dz09` @@ -983,6 +983,7 @@ This route requires Twitter token's corresponding id, therefore it's only availa ### User Profile {#vimeo-user-profile} + :::tip Special category name attention Some of the categories contain slash like `3D/CG` , must change the slash `/` to the vertical bar`|`. @@ -1047,13 +1048,15 @@ YouTube provides official RSS feeds for channels, for instance -:::note Chart +Chart + | Top artists | Top songs | Top music videos | Trending | | ----------- | --------- | ---------------- | -------- | | TopArtists | TopSongs | TopVideos | TrendingVideos | -::: -:::note Country Code + +Country Code + | Argentina | Australia | Austria | Belgium | Bolivia | Brazil | Canada | | --------- | --------- | ------- | ------- | ------- | ------ | ------ | | ar | au | at | be | bo | br | ca | @@ -1090,7 +1093,7 @@ YouTube provides official RSS feeds for channels, for instance @@ -1140,7 +1143,7 @@ YouTube provides official RSS feeds for channels, for instance -:::tip 提示 +:::tip - **目前只支持整数型 id** - 字母型的 id,可以通过头像图片链接来找到其整数型 id,图片命名规则`ul[userid]-*.jpg`或`u[userid]-*.jpg`,即取文件名中间的数字 @@ -1388,8 +1391,10 @@ YouTube provides official RSS feeds for channels, for instance :::tip + 仅限于采集**站内订阅**的看看号的内容。看看号 ID 可在看看号界面右上分享 - 复制链接得到。 + ::: @@ -1507,7 +1514,9 @@ YouTube provides official RSS feeds for channels, for instance @@ -1592,7 +1601,7 @@ rule ## 微博 {#wei-bo} -:::caution 注意 +:::caution 微博会针对请求的来源地区返回不同的结果。\ 一个已知的例子为:部分视频因未知原因仅限中国大陆境内访问 (CDN 域名为 `locallimit.us.sinaimg.cn` 而非 `f.video.weibocdn.com`)。若一条微博含有这种视频且 RSSHub 实例部署在境外,抓取到的微博可能不含视频。将 RSSHub 部署在境内有助于抓取这种视频,但阅读器也必须处于境内网络环境以加载视频。 @@ -1663,7 +1672,7 @@ rule -:::caution 注意 +:::caution 需要对应用户打开页面进行授权生成 token 才能生成内容 @@ -1677,7 +1686,7 @@ rule -:::caution 注意 +:::caution 由于微博官方未提供自定义分组相关 api, 此方案必须使用用户`Cookie`进行抓取 @@ -1701,7 +1710,7 @@ rule -:::tip 注意 +:::tip 用户的动态是一定时间范围内用户提出的问题和作出的回答,距离现在时间较久的问题和回答不会出现,此时选择 `dongtai` 用户动态是会缺失的。 @@ -1717,8 +1726,10 @@ rule -:::tip 提示 +:::tip + 笔记全文不支持显示视频 + ::: ### 用户收藏 {#xiao-hong-shu-yong-hu-shou-cang} @@ -1731,9 +1742,11 @@ rule ## 新榜 {#xin-bang} -:::caution 注意 +:::caution + 部署时需要配置 NEWRANK_COOKIE,具体见部署文档 请勿过高频抓取,新榜疑似对每天调用 token 总次数进行了限制,超限会报错 + ::: ### 微信公众号 {#xin-bang-wei-xin-gong-zhong-hao} @@ -1744,8 +1757,10 @@ rule -:::caution 注意 +:::caution + 免费版账户抖音每天查询次数 20 次,如需增加次数可购买新榜会员或等待未来多账户支持 + ::: ## 知乎 {#zhi-hu} @@ -1828,7 +1843,7 @@ rule -:::caution 注意 +:::caution 用户关注动态需要登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -1836,6 +1851,18 @@ rule +### [xhu](https://github.com/REToys/xhu) - 收藏夹 {#zhi-hu-%5Bxhu%5D(https%3A%2F%2Fgithub.com%2Fretoys%2Fxhu)---shou-cang-jia} + + + +### [xhu](https://github.com/REToys/xhu) - 专栏 {#zhi-hu-%5Bxhu%5D(https%3A%2F%2Fgithub.com%2Fretoys%2Fxhu)---zhuan-lan} + + + +### [xhu](https://github.com/REToys/xhu) - 问题 {#zhi-hu-%5Bxhu%5D(https%3A%2F%2Fgithub.com%2Fretoys%2Fxhu)---wen-ti} + + + ### [xhu](https://github.com/REToys/xhu) - 话题 {#zhi-hu-%5Bxhu%5D(https%3A%2F%2Fgithub.com%2Fretoys%2Fxhu)---hua-ti} diff --git a/website/docs/routes/study.md b/website/docs/routes/study.md index d0d4fadbf7ae8c..e86386fd5e9317 100644 --- a/website/docs/routes/study.md +++ b/website/docs/routes/study.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 📖 Study ## 51VOA 美国之音 {#51voa-mei-guo-zhi-yin} @@ -383,7 +381,7 @@ paramsDesc={['一个整数,筛选最近的limit场比赛,默认为5']}> | ---- | ---- | ---- | | tz | dt | gs | -:::tip 提示 +:::tip 分类字段处填写的是对应东莞教研网网址中中介于 **** 和 **.htm** 中间的一段。 @@ -451,7 +449,7 @@ paramsDesc={['一个整数,筛选最近的limit场比赛,默认为5']}> -:::tip 提示 +:::tip 若订阅 [信息与政策](https://www.sdzk.cn/NewsList.aspx?BCID=1),网址为 。截取 `BCID=1` 作为参数,此时路由为 [`/sdzk/1`](https://rsshub.app/sdzk/1)。 @@ -499,7 +497,7 @@ paramsDesc={['一个整数,筛选最近的limit场比赛,默认为5']}> -:::tip 提示 +:::tip 不支持分类搜索和自定义搜索排序,即 `search` 参数不为空时,其他参数不起作用。 @@ -631,7 +629,7 @@ paramsDesc={['一个整数,筛选最近的limit场比赛,默认为5']}> -:::tip 提示 +:::tip 卡片对应的话题、专题等内容过期后,该卡片 id 也会失效,此时填入该卡片 id 将会报错。 diff --git a/website/docs/routes/traditional-media.md b/website/docs/routes/traditional-media.md index 78047a34a6c32f..bcf5c37da736bd 100644 --- a/website/docs/routes/traditional-media.md +++ b/website/docs/routes/traditional-media.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 📰 News ## 21 财经 {#21-cai-jing} @@ -14,7 +12,7 @@ import Route from '@site/src/components/Route'; -:::tip Tip +:::tip All Topics in [Topic Library](https://abc.net.au/news/topics) are supported, you can fill in the field after `topic` in its URL, or fill in the `documentId`. @@ -72,7 +70,7 @@ Language | ------ | ------- | ------- | | arbric | chinese | english | -:::tip Tip +:::tip If you subscribe to [Al Jazeera English - Economy](https://www.aljazeera.com/economy), whose language is `english` and whose path is `economy`, you can get the route as [`/aljazeera/english/economy`](https://rsshub.app/aljazeera/english/economy) @@ -92,7 +90,7 @@ Language | ------ | ------- | ------- | | arbric | chinese | english | -:::tip Tip +:::tip If you subscribe to [Al Jazeera English - Science and Technology](https://www.aljazeera.com/tag/science-and-technology), whose language is `english` and whose path is `science-and-technology`, you can get the route as [`/aljazeera/english/tag/science-and-technology`](https://rsshub.app/aljazeera/english/tag/science-and-technology) @@ -110,7 +108,7 @@ Language | ------ | ------- | ------- | | arbric | chinese | english | -:::tip Tip +:::tip There is no RSS source for Al Jazeera Chinese, returning homepage content by default @@ -283,7 +281,9 @@ Topics: |dna-verified| :::tip Topic + The URL of the form `https://www.dnaindia.com/topic/dna-verified` demonstrates the utilization of the subdomain `topic` + ::: @@ -294,7 +294,7 @@ The URL of the form `https://www.dnaindia.com/topic/dna-verified` demonstrates t -:::tip 提示 +:::tip - 不支持付费文章。 @@ -313,7 +313,7 @@ The URL of the form `https://www.dnaindia.com/topic/dna-verified` demonstrates t -:::tip tips +:::tip - Visit ft.com -> myFT -> Contact Preferences to enable personal RSS feed, see [help.ft.com](https://help.ft.com/faq/email-alerts-and-contact-preferences/what-is-myft-rss-feed/) - Obtain the key from the personal RSS address, it looks like `12345678-abcd-4036-82db-vdv20db024b8` @@ -395,8 +395,10 @@ Provides a way to get an specific rss feed by date and category over the officia -:::tip tips +:::tip + Only `s00017` is in English. + ::: | category | Channel | @@ -445,7 +447,7 @@ Only `s00017` is in English. -:::tip 提示 +:::tip **编号** 仅对事件追蹤、評論節目、新聞專題三个分类起作用,例子如下: @@ -606,7 +608,7 @@ This route adds the missing photo and Link element. (Offical RSS doesn't have Li -:::tip Tip +:::tip When subscribing to podcasts, fill `category` with **podcast**. For example, URL to [SBS 普通话电台](https://www.sbs.com.au/chinese/mandarin/zh-hans/podcast/sbs-mandarin) is , with **sbs-mandarin** as `id`, **mandarin** as `dialect`, `language` as **zh-hans**, and the route is [`/sbs/chinese/podcast/sbs-mandarin/mandarin/zh-hans`](https://rsshub.app/sbs/chinese/podcast/sbs-mandarin/mandarin/zh-hans). @@ -644,7 +646,7 @@ SBS Cantonese Programs: | ------------------ | -------------- | -------------- | ----------- | ---------------- | | healthy-happy-life | gardening-tips | global-finance | culture-360 | technology-world | -:::tip Tip +:::tip Mostly, you can omit `language`, for the reason that **madarin** is with **zh-hans** and **cantonese** is with **zh-hant** by default. For example, the route of [SBS 普通话电台](https://www.sbs.com.au/chinese/mandarin/zh-hans/podcast/sbs-mandarin) is [`/sbs/chinese/podcast/sbs-mandarin/mandarin/zh-hans`](https://rsshub.app/sbs/chinese/podcast/sbs-mandarin/mandarin/zh-hans), which can also be [`/sbs/chinese/podcast/sbs-mandarin/mandarin`](https://rsshub.app/sbs/chinese/podcast/sbs-mandarin/mandarin). @@ -660,7 +662,7 @@ You still can customize `language`, however, it is important to note that not al -:::tip 提示 +:::tip Solidot 提供的 feed: @@ -873,7 +875,7 @@ Provides all of the articles by the specified New York Times author. -:::tip 提示 +:::tip 如 [中国 经济 日经中文网](https://cn.nikkei.com/china/ceconomy.html) 的 URL 为 对应路由为 [`/nikkei/cn/cn/china/ceconomy`](https://rsshub.app/nikkei/cn/cn/china/ceconomy) @@ -1080,8 +1082,6 @@ Category 列表: -:::note 栏目 - | 栏目 | id | | -------------- | -------- | | 第一关注 | diyi | @@ -1104,13 +1104,11 @@ Category 列表: | 军事 | junshi | | 参考人物 | cankaorw | -::: - ## 朝日新聞中文網(繁體中文版) {#chao-ri-xin-wen-zhong-wen-wang-%EF%BC%88-fan-ti-zhong-wen-ban-%EF%BC%89} -:::tip 提示 +:::tip 朝日新闻中文网已于 2021 年 3 月 31 日关闭。 @@ -1120,7 +1118,7 @@ Category 列表: -:::tip 提示 +:::tip 以下小标题即类型 `genre`,标题下表格中为对应类型的分类 `category`,两者需要配合使用。 @@ -1284,7 +1282,7 @@ IT・科学 tech_science -:::tip 提示 +:::tip 全部主题词见 [此处](https://www.yicai.com/feed/alltheme) @@ -1462,7 +1460,7 @@ IT・科学 tech_science -:::tip 提示 +:::tip 在北京时间深夜可能无法获取内容。 @@ -1676,7 +1674,7 @@ IT・科学 tech_science -:::tip 提示 +:::tip 以下小标题即栏目 `column`,标题下表格中为对应栏目的分类 `category`,两者需要配合使用。 @@ -1808,7 +1806,7 @@ category 对应的关键词有 ## 联合早报 {#lian-he-zao-bao} -:::caution 注意 +:::caution 由于 [RSSHub#10309](https://github.com/DIYgod/RSSHub/issues/10309) 中的问题,使用靠近香港的服务器部署将从 hk 版联合早报爬取内容,造成输出的新闻段落顺序错乱。如有订阅此源的需求,建议寻求部署在远离香港的服务器上的 RSSHub,或者在自建时选择远离香港的服务器。 @@ -1908,8 +1906,10 @@ category 对应的关键词有 -:::tip 提示 +:::tip + 若此处输入的是栏目 ID(而非南方号 ID),则该接口会返回与输入栏目相关联栏目的文章。例如,输入栏目 ID `38`(广州),则返回的结果还会包含 ID 为 `3547`(市长报道集)的文章。 + ::: 1. `pc.nfapp.southcn.com` 下的文章页面,可通过 url 查看,例: 的栏目 ID 为 `13707`。 @@ -1996,7 +1996,7 @@ category 对应的关键词有 -:::tip 提示 +:::tip 如 [蒙古语卫视新闻联播](http://www.nmtv.cn/folder292/folder663/folder301/folder830/folder877) 的 URL 为 ,其栏目 id 为末尾数字编号,即 `877`。可以得到其对应路由为 [`/nmtv/column/877`](https://rsshub.app/nmtv/column/877) @@ -2212,7 +2212,7 @@ category 对应的关键词有 2. 把 `http://opinion.people.com.cn/GB/` 与 `/index.html` 间 `427456/434878` 作为 `category` 参数填入; 3. 最终可获得 [`/people/opinion/427456/434878`](https://rsshub.app/people/opinion/427456/434878)。 -:::tip 提示 +:::tip 人民网大部分站点支持上述通用规则进行订阅。 @@ -2276,7 +2276,7 @@ category 对应的关键词有 -:::tip 提示 +:::tip 参数 **是否仅获取完整视频** 设置为 `true` `yes` `t` `y` 等值后,路由仅返回当期节目的完整视频,而不会返回节目所提供的节选视频。 @@ -2585,7 +2585,7 @@ category 对应的关键词有 | 头条 | 国内 | 国际 | 言路 | 财经 | 地方 | 副刊 | 娱乐 | 体育 | 百格 | 星角攝 | 好运来 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ------ | ------ | -:::tip 提示 +:::tip 若订阅单级分类 [头条](https://www.sinchew.com.my/category/头条),其 URL 为 [https://www.sinchew.com.my/category/ 头条](https://www.sinchew.com.my/category/头条),则路由为 [`/sinchew/category/头条`](https://rsshub.app/sinchew/category/头条)。 @@ -2617,7 +2617,7 @@ category 对应的关键词有 | -------- | ---------- | ------------ | | zdzy | jjbxs | dydhly | -:::tip 提示 +:::tip 更多栏目请看 [这里](https://tv.cctv.com/lm) @@ -2629,7 +2629,7 @@ category 对应的关键词有 -:::tip 提示 +:::tip 如 [2020 年国家网络安全宣传周](https://news.cctv.com/special/2020gjwlaqxcz/index.shtml) 的专题页 URL 为 id 即为 `2020gjwlaqxcz`。 diff --git a/website/docs/routes/travel.md b/website/docs/routes/travel.md index 87cda2bb054e0b..04bd6ca52499f5 100644 --- a/website/docs/routes/travel.md +++ b/website/docs/routes/travel.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🛫 Travel ## 12306 {#12306} diff --git a/website/docs/routes/university.md b/website/docs/routes/university.md index bd3291cdd168bf..bfaddcec60db2b 100644 --- a/website/docs/routes/university.md +++ b/website/docs/routes/university.md @@ -1,5 +1,3 @@ -import Route from '@site/src/components/Route'; - # 🎓 University ## Beijing Jiaotong University 北京交通大学 {#beijing-jiaotong-university-bei-jing-jiao-tong-da-xue} @@ -305,7 +303,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::caution 注意 +:::caution 论坛部分帖子正文内容的获取需要用户登录后的 Cookie 值,详情见部署页面的配置模块。 @@ -327,7 +325,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::tip 提示 +:::tip 分类字段处填写的是对应北京大学人事处分类页网址中介于 **** 和 **/index.htm** 中间的一段,并将其中的 `/` 修改为 `-`。 @@ -489,7 +487,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::tip 提示 +:::tip 路径处填写对应页面 URL 中 `https://fdy.bnu.edu.cn/` 和 `/index.htm` 之间的字段。下面是一个例子。 @@ -505,8 +503,10 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::caution 注意 +:::caution + 由于学校官网对非大陆 IP 的访问存在限制,需自行部署。 + ::: ## 北京协和医学院 {#bei-jing-xie-he-yi-xue-yuan} @@ -535,7 +535,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::caution 注意 +:::caution 由于需要登陆 `https://webapp.bupt.edu.cn/wap/login.html?redirect=http://` 后的 Cookie 值,所以只能自建,详情见部署页面的配置模块 @@ -545,7 +545,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::caution 注意 +:::caution 由于需要登陆 `https://webapp.bupt.edu.cn/wap/login.html?redirect=http://` 后的 Cookie 值,所以只能自建,详情见部署页面的配置模块 @@ -554,7 +554,8 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's ### BTBYR 趣味盒 {#bei-jing-you-dian-da-xue-btbyr-qu-wei-he} -:::caution 注意 + +:::caution 由于需要登陆 BTBYR 后的 Cookie 值,所以只能自建,并且部署和订阅端均需支持 IPV6 网络或使用镜像站点。 @@ -623,16 +624,20 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::tip 提示 +:::tip + 路径参数的值为相应通知列表页面的地址去除后缀名和域名后的路径。 例如 “通知公告” 列表页面地址为 ,相应参数为 `index/tgzz`。 + ::: -:::caution 注意 +:::caution + 原重庆大学教务网网站变更为重庆大学本科教学信息网。该路由编写时(2021-07-29)它[正处于试运行阶段](http://jwc.cqu.edu.cn/info/1080/3482.htm)。 通知的分类比较迷,请小心甄别、使用(以免漏掉需要的通知)。 + ::: ### 新闻网讲座预告 {#chong-qing-da-xue-xin-wen-wang-jiang-zuo-yu-gao} @@ -824,7 +829,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | | tzgg | gzdt | zcfg | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学人事处](http://perdep.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -840,7 +845,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | | xwkd | zytg | bhgs | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学教务处](http://teach.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -860,7 +865,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | --------------------- | --------------------- | --------------------- | | yjszs/zcwj1 | yjszs/gzdt/gzdt | yjszs/zlxz/zlxz | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学研究生院](http://gs.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -876,7 +881,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | -------- | ---------- | ---------- | | jdxw | zhxw | xytz | xsdt | bkstz | yjstz | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学软件学院](http://ssdut.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -892,7 +897,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | | tzgg | xqxw | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学开发区校区](http://eda.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -908,7 +913,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | -------- | -------- | ---- | | xqxw | xywh | xyfc | xsdt | mtbd | gg | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学盘锦校区](https://panjin.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -924,7 +929,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | --------- | | zytz | xgdt | gsgonggao | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学盘锦校区学生事务办公室](http://xsgzb.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -940,7 +945,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | -------- | ---------- | | xwkd | zytz | jxwj | cjwt | xkyks | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学盘锦校区教务教学事务办公室](http://pjteach.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -956,7 +961,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | -------- | | tzgg | dzyd | zwkx | fgzd | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学盘锦校区总务部](http://pjxqzwb.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -972,7 +977,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | | xyxw | zxgg | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学体育与健康学院盘锦分院](http://tjpj.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -988,7 +993,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | ---------- | -------- | | jstz | xstong_zhi | xwsd | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学国际合作与交流处(港澳台办)](http://dutdice.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -1004,7 +1009,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's | -------- | -------- | -------- | -------- | | tzgg | hdrc | xwdt | jkzs | -:::tip 提示 +:::tip 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学体育场馆中心](http://tycgzx.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。 @@ -1126,7 +1131,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::tip 提示 +:::tip 若订阅 [通知公告](https://sohac.nenu.edu.cn/index/tzgg.htm),网址为 。截取 `https://sohac.nenu.edu.cn/` 到末尾 `.htm` 的部分 `index/tzgg` 作为参数,此时路由为 [`/nenu/sohac/index/tzgg`](https://rsshub.app/nenu/sohac/index/tzgg)。 @@ -1140,7 +1145,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::tip 提示 +:::tip 若订阅 [通知公告](https://yjsy.nenu.edu.cn/tzgg.htm),网址为 。截取 `https://yjsy.nenu.edu.cn/` 到末尾 `.htm` 的部分 `tzgg` 作为参数,此时路由为 [`/nenu/yjsy/tzgg`](https://rsshub.app/nenu/yjsy/tzgg)。 @@ -1248,7 +1253,7 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's -:::tip 提示 +:::tip 如 [通知公告](http://hr.uibe.edu.cn/tzgg) 的 URL 为 ,其路由为 [`/uibe/hr/tzgg`](https://rsshub.app/uibe/hr/tzgg) @@ -1478,8 +1483,10 @@ category 列表: ## 哈尔滨工业大学 {#ha-er-bin-gong-ye-da-xue} -:::caution 注意 +:::caution + 哈工大网站疑似禁止了`rsshub.app`的访问,使用路由需要自行 [部署](https://docs.rsshub.app/install)。 + ::: ### 教务处通知公告 {#ha-er-bin-gong-ye-da-xue-jiao-wu-chu-tong-zhi-gong-gao} @@ -1490,13 +1497,17 @@ category 列表: -:::tip 提示 +:::tip + 今日哈工大的文章分为公告公示和新闻快讯,每个页面右侧列出了更详细的分类,其编号为每个 URL 路径的最后一个数字。 例如会议讲座的路径为`/taxonomy/term/10/25`,则可以通过 [`/hit/today/25`](https://rsshub.app/hit/today/25) 订阅该详细类别。 + ::: -:::caution 注意 +:::caution + 部分文章需要经过统一身份认证后才能阅读全文。 + ::: @@ -1637,8 +1648,10 @@ category 列表: -:::caution 注意 +:::caution + jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS_REJECT_UNAUTHORIZED = 0 + ::: ## 湖南大学 {#hu-nan-da-xue} @@ -1794,8 +1807,10 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS -:::caution 注意 +:::caution + 由于学院官网对非大陆 IP 的访问存在限制,需自行部署。 + ::: ## 华南农业大学 {#hua-nan-nong-ye-da-xue} @@ -2324,7 +2339,7 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS ## 南京信息工程大学 {#nan-jing-xin-xi-gong-cheng-da-xue} -:::tip 提示 +:::tip 路由地址全部按照 **学校官网域名和栏目编号** 设计 @@ -2352,7 +2367,7 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS | -------- | -------- | -------- | -------- | -------- | -------- | ---- | | 783 | 784 | 785 | 786 | 788 | 789 | qt | -:::caution 注意 +:::caution 全文内容需使用 校园网或[VPN](http://vpn.nuist.edu.cn) 获取 @@ -2384,7 +2399,7 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS -:::tip 提示 +:::tip 路径字段处填写的是对应南京信息工程大学研究生院学科建设处分类页网址中介于 **** 和 **.htm** 中间的一段。 @@ -2482,8 +2497,10 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS -:::caution 注意 +:::caution + 由于学校通知仅允许校园网访问,需自行部署。 + ::: ### 清华大学招聘信息 {#qing-hua-da-xue-qing-hua-da-xue-zhao-pin-xin-xi} @@ -2790,7 +2807,7 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS ## 上海立信会计金融学院 {#shang-hai-li-xin-kuai-ji-jin-rong-xue-yuan} -:::caution 注意 +:::caution 分区 ID 是`info/iList.jsp?cat_id=`后方数字 @@ -2866,8 +2883,10 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS -:::caution 注意 +:::caution + 计算机学院通知公告疑似禁止了非大陆 IP 访问,使用路由需要自行 [部署](https://docs.rsshub.app/install)。 + ::: ## 四川旅游学院 {#si-chuan-l%C3%BC-you-xue-yuan} @@ -3114,7 +3133,7 @@ paramsDesc={['公告类型,详见表格']}> -:::tip 提示 +:::tip 支持`http://dean.xjtu.edu.cn/`下所有**有文章列表**的栏目, @@ -3199,9 +3218,10 @@ paramsDesc={['公告类型,详见表格']}> -:::caution 注意 +:::caution 有些内容需使用校园网或 VPN 访问知行网获取 + ::: | 通知公告 | 新闻动态 | 规章制度 | 竞赛结果公示 | 竞赛获奖通知 | 竞赛信息 | 公开公示 | @@ -3214,9 +3234,10 @@ paramsDesc={['公告类型,详见表格']}> -:::caution 注意 +:::caution 有些内容指向外部链接,目前只提供这些链接,不提供具体内容,去除 jwc 和 index 的修改 + ::: | 通知公告 | 工作动态 | @@ -3465,7 +3486,7 @@ paramsDesc={['公告类型,详见表格']}> -:::tip 提示 +:::tip 若订阅 [院情总览 - 通知公告](https://dongke.yangtzeu.edu.cn/yqzl/tzgg.htm),网址为 。截取 `https://dongke.yangtzeu.edu.cn` 到末尾 `.htm` 的部分 `/yqzl/tzgg` 作为参数,此时路由为 [`/yangtzeu/dongke/yqzl/tzgg`](https://rsshub.app/yangtzeu/dongke/yqzl/tzgg)。 @@ -3714,11 +3735,16 @@ paramsDesc={['公告类型,详见表格']}> ### 选课信息教务通知 {#zhong-guo-hai-yang-da-xue-xuan-ke-xin-xi-jiao-wu-tong-zhi} - -:::caution 注意 + + +:::caution + 由于选课通知仅允许校园网访问,需自行部署。 + ::: + + ## 中国科学技术大学 {#zhong-guo-ke-xue-ji-shu-da-xue} ### 官网通知公告 {#zhong-guo-ke-xue-ji-shu-da-xue-guan-wang-tong-zhi-gong-gao} @@ -3857,7 +3883,7 @@ paramsDesc={['公告类型,详见表格']}> -:::tip 提示 +:::tip 分类字段处填写的是对应中国人民大学人事处分类页网址中介于 **** 和 **/index.htm** 中间的一段,并将其中的 `/` 修改为 `-`。 diff --git a/website/docs/usage.md b/website/docs/usage.md index 1b01f55621dd53..95687a07db09c1 100644 --- a/website/docs/usage.md +++ b/website/docs/usage.md @@ -22,29 +22,29 @@ Apart from serving as an information source hub, RSSHub is also made compatible ### Install - - + + ```bash pnpm add rsshub ``` - - + + ```bash yarn add rsshub ``` - - + + ```bash npm install rsshub --save ``` - - + + ### Usage diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index fa1c1a68d53987..6d8aa70e405a94 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -54,9 +54,9 @@ const config = { { from: '/joinus/use-cache', to: '/joinus/advanced/use-cache' }, ...Object.values(require('./sidebars').guideSidebar) .find((s) => s.label === 'Routes') - .items.map((category) => ({ - from: `/${category.split('/')[1]}`, - to: `/routes/${category.split('/')[1]}`, + .items.map(({ id }) => ({ + from: `/${id.split('/')[1]}`, + to: `/routes/${id.split('/')[1]}`, })), ], }), @@ -235,6 +235,7 @@ const config = { prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, + additionalLanguages: ['bash'], }, }), }; diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current.json b/website/i18n/zh/docusaurus-plugin-content-docs/current.json index 9a85dedd8eb8cb..b0a87a30079e0f 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current.json +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current.json @@ -38,5 +38,97 @@ "sidebar.joinusSidebar.category.Advanced": { "message": "高级用法", "description": "The label for category Advanced in sidebar joinusSidebar" + }, + "sidebar.guideSidebar.doc.💬 Social Media": { + "message": "💬 社交媒体", + "description": "The label for the doc item 💬 Social Media in sidebar guideSidebar, linking to the doc routes/social-media" + }, + "sidebar.guideSidebar.doc.📱 New media": { + "message": "📱 新媒体", + "description": "The label for the doc item 📱 New media in sidebar guideSidebar, linking to the doc routes/new-media" + }, + "sidebar.guideSidebar.doc.📰 News": { + "message": "📰 传统媒体", + "description": "The label for the doc item 📰 News in sidebar guideSidebar, linking to the doc routes/traditional-media" + }, + "sidebar.guideSidebar.doc.💬️ BBS": { + "message": "💬️ 论坛", + "description": "The label for the doc item 💬️ BBS in sidebar guideSidebar, linking to the doc routes/bbs" + }, + "sidebar.guideSidebar.doc.🖊️️ Blog": { + "message": "🖊️️ 博客", + "description": "The label for the doc item 🖊️️ Blog in sidebar guideSidebar, linking to the doc routes/blog" + }, + "sidebar.guideSidebar.doc.💻 Programming": { + "message": "💻 编程", + "description": "The label for the doc item 💻 Programming in sidebar guideSidebar, linking to the doc routes/programming" + }, + "sidebar.guideSidebar.doc.🎨️ Design": { + "message": "🎨️ 设计", + "description": "The label for the doc item 🎨️ Design in sidebar guideSidebar, linking to the doc routes/design" + }, + "sidebar.guideSidebar.doc.🎥 Live": { + "message": "🎥 直播", + "description": "The label for the doc item 🎥 Live in sidebar guideSidebar, linking to the doc routes/live" + }, + "sidebar.guideSidebar.doc.🔊 Multimedia": { + "message": "🔊 音视频", + "description": "The label for the doc item 🔊 Multimedia in sidebar guideSidebar, linking to the doc routes/multimedia" + }, + "sidebar.guideSidebar.doc.🖼️ Picture": { + "message": "🖼️ 图片", + "description": "The label for the doc item 🖼️ Picture in sidebar guideSidebar, linking to the doc routes/picture" + }, + "sidebar.guideSidebar.doc.🎨️ ACG": { + "message": "🎨️ 二次元", + "description": "The label for the doc item 🎨️ ACG in sidebar guideSidebar, linking to the doc routes/anime" + }, + "sidebar.guideSidebar.doc.🔄 Application Updates": { + "message": "🔄 程序更新", + "description": "The label for the doc item 🔄 Application Updates in sidebar guideSidebar, linking to the doc routes/program-update" + }, + "sidebar.guideSidebar.doc.🎓 University": { + "message": "🎓 大学通知", + "description": "The label for the doc item 🎓 University in sidebar guideSidebar, linking to the doc routes/university" + }, + "sidebar.guideSidebar.doc.❗️ Forecast and Alerts": { + "message": "❗️ 预报预警", + "description": "The label for the doc item ❗️ Forecast and Alerts in sidebar guideSidebar, linking to the doc routes/forecast" + }, + "sidebar.guideSidebar.doc.🛫 Travel": { + "message": "🛫 出行旅游", + "description": "The label for the doc item 🛫 Travel in sidebar guideSidebar, linking to the doc routes/travel" + }, + "sidebar.guideSidebar.doc.🛍️ Shopping": { + "message": "🛍️ 购物", + "description": "The label for the doc item 🛍️ Shopping in sidebar guideSidebar, linking to the doc routes/shopping" + }, + "sidebar.guideSidebar.doc.🎮 Gaming": { + "message": "🎮 游戏", + "description": "The label for the doc item 🎮 Gaming in sidebar guideSidebar, linking to the doc routes/game" + }, + "sidebar.guideSidebar.doc.📚 Reading": { + "message": "📚 阅读", + "description": "The label for the doc item 📚 Reading in sidebar guideSidebar, linking to the doc routes/reading" + }, + "sidebar.guideSidebar.doc.📢 Government": { + "message": "📢 政务消息", + "description": "The label for the doc item 📢 Government in sidebar guideSidebar, linking to the doc routes/government" + }, + "sidebar.guideSidebar.doc.📖 Study": { + "message": "📖 学习", + "description": "The label for the doc item 📖 Study in sidebar guideSidebar, linking to the doc routes/study" + }, + "sidebar.guideSidebar.doc.🔬 Scientific Journal": { + "message": "🔬 科学期刊", + "description": "The label for the doc item 🔬 Scientific Journal in sidebar guideSidebar, linking to the doc routes/journal" + }, + "sidebar.guideSidebar.doc.💰 Finance": { + "message": "💰 金融", + "description": "The label for the doc item 💰 Finance in sidebar guideSidebar, linking to the doc routes/finance" + }, + "sidebar.guideSidebar.doc.🔍 Uncategorized": { + "message": "🔍 其他", + "description": "The label for the doc item 🔍 Uncategorized in sidebar guideSidebar, linking to the doc routes/other" } } diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/api.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/api.md index df78a705635d8c..6c031db6103564 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/api.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/api.md @@ -1,15 +1,19 @@ # API -:::caution 注意 -API 仍处于开发状态中, 并可能会有改动。欢迎提供建议! +:::caution + +API 仍处于开发状态中,并可能会有改动。欢迎提供建议! + ::: RSSHub 提供下列 API: ## 可用公共路由列表 -:::tip 提示 +:::tip + `protected_router.js`下的路由**不会被**包含在此 API 返回的结果当中. + ::: 举例: diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md index f2ed94fee4802a..6244cdb0af95f6 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md @@ -89,7 +89,7 @@ $ docker pull diygod/rsshub ## Docker 部署 -:::tip 提示 +:::tip 如需启用 puppeteer,请在**每条**命令中均将 `diygod/rsshub` 替换为 `diygod/rsshub:chromium-bundled`。 @@ -186,29 +186,29 @@ $ cd RSSHub 下载完成后,需要安装依赖(开发不要加 `--production` 参数) - - + + ```bash pnpm install --prod ``` - - + + ```bash yarn --production ``` - - + + ```bash npm install --omit=dev ``` - - + + 由于众所周知的原因,在中国使用 `npm` 下载依赖十分缓慢,建议挂一个代理或者考虑使用 [NPM 镜像](https://npm.taobao.org/) @@ -238,7 +238,7 @@ $ pm2 start lib/index.js --name rsshub ### 添加配置 -:::tip 提示 +:::tip 在 arm/arm64 上,此部署方式不包含 puppeteer 依赖。要启用 puppeteer,你需要先从发行版安装 Chromium,然后设置 `CHROMIUM_EXECUTABLE_PATH` 为其可执行路径。 @@ -309,7 +309,7 @@ in pkgs.stdenv.mkDerivation { ### 注意 -:::caution 更新 +:::caution Heroku [不再](https://blog.heroku.com/next-chapter) 提供免费服务。 @@ -500,7 +500,7 @@ gcloud app deploy [![Try in PWD](https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png)](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml) -:::caution 注意 +:::caution - 需要 [DockerHub](https://hub.docker.com) 账号 - [Play with Docker](https://labs.play-with-docker.com/) 一次仅能使用 4 小时,不能作为持久化解决方案,应当用于测试 / 验证路由规则 @@ -585,7 +585,7 @@ RSSHub 支持 `memory` 和 `redis` 两种缓存方式 ### 反向代理 -:::caution 注意 +:::caution 这种代理方式无法代理包含 cookie 的请求。 @@ -734,7 +734,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 ### 部分 RSS 模块配置 -:::tip 提示 +:::tip 此处信息不完整。完整配置请参考路由对应的文档和 `lib/config.js`。 @@ -781,11 +781,17 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - Civitai - `CIVITAI_COOKIE`: Civitai 登录后的 cookie 值 -- discuz cookies 设定 +- Discourse + + - `DISCOURSE_CONFIG_{id}`: 一个 Discourse 驱动的论坛的配置信息, `id` 可自由设定为任意数字或字符串。值应形如`{"link":link,"key":key}`。其中: + - `link`:论坛的链接。 + - `key`访问论坛API的密钥,可参考[此处代码](https://pastebin.com/YbLCgdWW)以获取。需要确保有足够权限访问对应资源。 + +- Discuz cookies 设定 - `DISCUZ_COOKIE_{cid}`: 某 Discuz 驱动的论坛,用户注册后的 Cookie 值,cid 可自由设定,取值范围 \[00, 99], 使用 discuz 通用路由时,通过指定 cid 来调用该 cookie -- disqus 全部路由:[申请地址](https://disqus.com/api/applications/) +- Disqus 全部路由:[申请地址](https://disqus.com/api/applications/) - `DISQUS_API_KEY`: Disqus API @@ -977,6 +983,10 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - `HEFENG_KEY`:API key +- 今日热榜 + + - `TOPHUB_COOKIE`: 今日热榜登录后的 cookie,目前只需要 `itc_center_user=...` 以获取原始链接 + - 南方周末付费全文 - `INFZM_COOKIE`: infzm 账户登陆后的 cookie,目前只需要 `passport_session=...` 即可获取全文 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md index dad6050f43dc26..71ac7c90e4f065 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md @@ -2,8 +2,6 @@ sidebar_position: 1 --- -import Route from '@site/src/components/Route'; - # RSS 基础 本指南面向希望深入了解如何制作 RSS 订阅源的高级用户。如果您是第一次制作 RSS 订阅源,我们建议先阅读 [制作自己的 RSSHub 路由](/zh/joinus/new-rss/start-code)。 @@ -56,6 +54,7 @@ import Route from '@site/src/components/Route'; | **`doi`** | *(可选)* 条目的数字对象标识符 (DOI),应为格式为 `10.xxx/xxxxx.xxxx` 的字符串 | `undefinded` | R | :::caution 格式考虑 + 在指定 RSS 订阅源中的某些字段时,重要的是要注意一些格式考虑因素。具体来说,您应避免在以下字段中包含任何换行符、连续的空格或前导/尾随空格:**`title`**,**`subtitle`**(仅适用于 Atom),**`author`**(仅适用于 Atom),**`item.title`** 和 **`item.author`**。 虽然大多数 RSS 阅读器将自动修剪这些空字符,但有些阅读器可能无法正确处理它们。因此,为确保与所有 RSS 阅读器兼容,我们建议在输出这些字段之前将其修剪。如果您制作的路由无法容忍修剪这些空字符,您应考虑更改它们的格式。 @@ -63,6 +62,7 @@ import Route from '@site/src/components/Route'; 另外,虽然其他字段不会被强制修剪,但我们建议尽可能避免违反上述格式规则。如果您正在使用 Cheerio 从网页中提取内容,时刻谨记 Cheerio 会保留换行和缩进。特别是对于 **`item.description`** 字段,任何预期之内的换行都应转换为 `
` 标签,以防止其被 RSS 阅读器修剪。尤其是您从 JSON 数据中制作 RSS 订阅时,目标网站返回的 JSON 很有可能含有需要显示的换行符,在这种情况下,应将它们转换为 `
` 标签。 请牢记这些格式考虑因素,以确保您的 RSS 订阅源与所有 RSS 阅读器兼容。 + ::: ## 制作 BitTorrent/磁力订阅源 @@ -89,7 +89,7 @@ ctx.state.data = { 如果您要在 RSSHub 路由中添加对 BitTorrent/磁力订阅支持,最重要的是在文档以反映此功能。要做到这一点,您需要将 `Route` 组件的 `supportBT` 属性设置为 `"1"`。 以下是一个示例: -```vue +```tsx ``` @@ -115,7 +115,7 @@ ctx.state.data = { 要显示您制作的期刊订阅源支持 Sci-hub 功能,您需要将 `Route` 组件的 `supportScihub` 属性设置为 `"1"`。以下是一个示例: -```vue +```tsx ``` @@ -155,7 +155,7 @@ ctx.state.data = { 要显示您制作的订阅源与播客播放器兼容,您需要将 `Route` 组件的 `supportPodcast` 属性设置为 `"1"`。以下是一个示例: -```vue +```tsx ``` diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md index 26de7a84c22b7c..cf31ad71b24a3e 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md @@ -36,8 +36,10 @@ const pubDate = parseDate('2020/12/30'); const pubDate = parseDate('2020/12/30', 'YYYY/MM/DD'); ``` -:::tip 提示 +:::tip + 你可以参考 [day.js 文档](https://day.js.org/docs/zh-CN/parse/string-format#支持的解析占位符列表) 查看所有可用日期格式。 + ::: 如果你需要解析相对日期,请使用 `parseRelativeDate`。 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md index 1df1c36f7d1235..7f22d0bf04d119 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md @@ -109,8 +109,10 @@ RSSHub 会将所有路由命名空间的文件夹名附加到路由前面。路 要生成维护者列表,可使用以下命令:`pnpm run build:maintainer`,它将在 `assets/build/` 目录下一份维护者列表。 -:::danger 警告 +:::danger + 在 `@koa/router` 对象中的路由应该与相应的文档中添加命名空间前的 `path` 一致。 + ::: ### Radar 规则 @@ -119,8 +121,10 @@ RSSHub 会将所有路由命名空间的文件夹名附加到路由前面。路 要生成完整的 `radar-rules.js` 文件,可使用以下命令:`yarn build:radar`,它将在 `assets/build/` 目录下创建文件。 -:::tip 提示 +:::tip + 在提交代码之前,请记得删除所有在 `assets/build/` 中的生成的资源。 + ::: ### 渲染模板 @@ -156,7 +160,7 @@ const renderAuthor = (author) => art(path.join(__dirname, 'templates/author.art' ### v1 路由规范 -:::danger 警告 +:::danger v1 路由规范已被弃用。所有新路由都应遵循 [v2 路由规范](#v2-lu-you-gui-fan)。 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md index fefbe73cf42e10..2fba6c55f71f15 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md @@ -29,7 +29,8 @@ sidebar_position: 3 上一个语句返回的对象将被重复使用,并且会添加一个额外的 `description` 属性。每个 `item.link` 的返回缓存将是`{ title, link, pubDate, author, category, description }`。下一次请求相同路由时,将直接返回处理过后的缓存而不是向服务器发出请求并重新计算数据。 -:::caution 注意 +:::caution + 在 `tryGet()` 函数之外声明的变量的任何赋值都不会在缓存命中的情况下被处理。例如,以下代码将无法按预期工作: ```js @@ -62,10 +63,12 @@ sidebar_position: 3 [lib/middleware/cache/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/cache/index.js#L58) -:::tip 提示 +:::tip + 以下是使用缓存的高级方法。大多数情况下,您应使用 `ctx.cache.tryGet()`。 请注意,当使用 `ctx.cache.get()` 获取缓存时,您需要使用 `JSON.parse()`。 + ::: ### ctx.cache.get(key \[, refresh ]) diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-radar.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-radar.md index e992a50ac084df..e2d07781d4de6f 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-radar.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-radar.md @@ -40,13 +40,14 @@ module.exports = { 其余的内部对象键是网站的子域名。如果要匹配的网站没有子域名,或者想同时匹配 `www.example.com` 和 `example.com`,则应使用 `'.'`。在此示例中,我们将使用 `'.'`,因为我们希望匹配 `github.com`。请注意,每个子域名键应返回**一个对象数组**。 - - + + -```js{4} +```js module.exports = { 'github.com': { _name: 'GitHub', + // highlight-next-line '.': [ { title: '...', @@ -59,13 +60,14 @@ module.exports = { }; ``` - - + + -```js{4} +```js module.exports = { 'github.com': { _name: 'GitHub', + // highlight-next-line abc: [ { title: '...', @@ -78,13 +80,14 @@ module.exports = { }; ``` - - + + -```js{4} +```js module.exports = { 'github.com': { _name: 'GitHub', + // highlight-next-line 'abc.def': [ { title: '...', @@ -97,8 +100,8 @@ module.exports = { }; ``` - - + + ### `title` @@ -114,8 +117,10 @@ source 是*可选*字段,应指定 URL 路径。如果不想匹配任何 URL source 应为一个字符串数组。例如,如果 `GitHub 仓库 Issues` 的 source 是 `/:user/:repo`,则意味着当您访问 `https://github.com/DIYgod/RSSHub` 时将匹配 `/:user/:repo`,此时返回的结果 params 将是:`{user: 'DIYgod', repo: 'RSSHub'}`。浏览器扩展程序使用这些参数根据 target 字段建立 RSSHub 订阅地址。 -:::caution 注意 +:::caution + 如果要提取的值在 URL 参数或 URL hash 中,请使用 target 函数而不是 source 字段。 此外,请记住,source 字段仅匹配 URL 路径,而不匹配 URL 的任何其他部分。 + ::: 您也可以使用 `*` 符号执行通配符匹配。请注意,此处的语法与 [path-to-regexp](https://github.com/pillarjs/path-to-regexp) 不同。例如,`/:user/:repo/*` 将匹配 `https://github.com/DIYgod/RSSHub/issues` 和 `https://github.com/DIYgod/RSSHub/issues/1234`。如果要对匹配结果进行命名,可以在 `*` 符号后放置变量名。例如,`/user/:repo/*path`,在此情况下,`path` 将是 `issues` 和 `issues/1234`。 @@ -136,10 +141,10 @@ source 应为一个字符串数组。例如,如果 `GitHub 仓库 Issues` 的 下面是使用 `target` 字段作为函数的两个示例: - - + + -```js{9} +```js module.exports = { 'github.com': { _name: 'GitHub', @@ -148,6 +153,7 @@ module.exports = { title: '仓库 Issues', docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo/issues/:id', '/:user/:repo/issues', '/:user/:repo'], + // highlight-next-line target: (params) => `/github/issue/${params.user}/${params.repo}`, }, ], @@ -155,10 +161,10 @@ module.exports = { }; ``` - - + + -```js{9} +```js module.exports = { 'github.com': { _name: 'GitHub', @@ -167,6 +173,7 @@ module.exports = { title: '仓库 Issues', docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo'], + // highlight-next-line target: (_, url) => `/github/issue${new URL(url).pathname}` }, ], @@ -174,8 +181,8 @@ module.exports = { }; ``` - - + + 两个示例将返回与 [第一个示例](/zh/joinus/new-radar#编写规则) 相同的 RSSHub 订阅地址。 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/add-docs.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/add-docs.md index f5336894f4349f..2a3fc3147f982a 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/add-docs.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/add-docs.md @@ -2,67 +2,81 @@ sidebar_position: 4 --- -import Route from '@site/src/components/Route'; - # 添加文档 现在我们完成了代码,是时候为您的路由添加文档了。在 [文档 (/website/docs)](https://github.com/DIYgod/RSSHub/blob/master/website/docs) 中打开相应的文件,本例中是 `website/docs/routes/programming.md`。 为了实时预览文档,您需要在 **`website` 目录** 下安装文档的依赖项。在终端中输入以下命令: - - + + ```bash pnpm i ``` - - + + ```bash yarn ``` - - + + ```bash npm install ``` - - + + -您现在可以在 **`website` 目录** 下运行以下命令实时预览文档: +您现在可以在 **`website` 目录** 下运行以下命令实时预览中文文档: - - + + ```bash -pnpm run start +pnpm run start:zh +``` + + + + +```bash +yarn start:zh ``` - - + + ```bash -yarn start +npm run start:zh ``` - - + + + +:::tip 英文文档 + +运行以下命令实时预览英文文档 ```bash -npm run start +pnpm run start ``` - - +::: + +:::caution + +在开发模式下,您无法切换到其他语言。这是 Docusaurus 的 [技术限制](https://docusaurus.io/docs/i18n/tutorial#start-your-site)。 -文档使用 Markdown 编写,并使用 [VuePress v1](https://v1.vuepress.vuejs.org) 渲染。 +::: -要为您的路由添加文档,请使用 Vue 组件。它们类似于 HTML 标签。以下是最常用的组件: +文档使用 MDX 编写,并使用 [Docusaurus v2](https://docusaurus.io/docs) 渲染。 + +要为您的路由添加文档,请使用 `Route` React 组件。它类似于 HTML 标签。以下是最常用的组件属性: - `author`:路由维护者,用单个空格分隔。应与 [`maintainer.js`](/zh/joinus/new-rss/before-start#maintainerjs) 相同 - `example`:路由示例,以 `/` 开头 @@ -78,7 +92,7 @@ npm run start ### 仓库 Issues(无参数) -```vue +```tsx ``` @@ -90,7 +104,7 @@ npm run start ### 仓库 Issues(多个参数) -```vue +```tsx ``` @@ -102,7 +116,7 @@ npm run start ### 关键词(带表格的说明) -```vue +```tsx | 只看非 R18 内容 | 只看 R18 内容 | 不过滤 | @@ -129,46 +143,84 @@ npm run start 如果您想提供关于路由的更多信息,可以使用这些自定义容器: ```md +
+ 点击展开全文 + 这是一个详细块,标题 (summary) 是可选的,不支持 Markdown。 +
+ +:::note + +这是一个备注。 + +::: + :::tip 提示标题 -这是一个提示。 + +标题是可选的。 + ::: -:::caution 警告标题 -这是一个警告。 +:::info + +内容支持 Markdown。 + ::: -:::danger 危险标题 -这是一条危险的警告。 +:::caution + +开始和结束的 `:::` 周围需要空出一行 + ::: -:::note 详细标题 -这是一个详细块。 +:::danger + +否则内容可能无法正常渲染。 + ::: ``` --- +
+ 点击展开全文 + 这是一个详细块,标题 (summary) 是可选的,不支持 Markdown。 +
+ +:::note + +这是一个备注。 + +::: + :::tip 提示标题 -这是一个提示。 + +标题是可选的。 + ::: -:::caution 警告标题 -这是一个警告。 +:::info + +内容支持 Markdown。 + ::: -:::danger 危险标题 -这是一条危险的警告。 +:::caution + +开始和结束的 `:::` 周围需要空出一行 + ::: -:::note 详细标题 -这是一个详细块。 +:::danger + +否则内容可能无法正常渲染。 + ::: --- ### 其他组件 -除了路由组件之外,还有几个组件可用于提供有关路径的更多信息: +除了上述组件属性之外,还有几个组件属性可用于提供有关路径的更多信息: - `anticrawler`:如果目标网站有反爬机制,则设置为 `1`。 - `puppeteer`:如果源使用 puppeteer 抓取,则设置为 `1`。 @@ -179,9 +231,9 @@ npm run start - `supportPodcast`:如果源支持播客,则设置为 `1`。 - `supportScihub`:如果源支持 Sci-Hub,则设置为 `1`。 -通过添加这些组件,您可以向用户提供有用的信息,并使其更易于理解和使用您的路由。将这些组件添加到路由文档中将在其前面添加一个徽章。 +通过添加这些属性,您可以向用户提供有用的信息,并使其更易于理解和使用您的路由。将这些属性添加到路由文档中将在其前面添加一个徽章。 -```vue +```tsx ``` @@ -200,26 +252,26 @@ npm run start - **别忘了关闭标签!** - 在提交 Pull Request 之前,请务必运行在 RSSHub 的根目录运行以下命令检查和格式化您的代码: - - + + ```bash pnpm run format ``` - - + + ```bash yarn format ``` - - + + ```bash npm run format ``` - - + + diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md index 0ab39386dc611c..2485da79911711 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md @@ -10,57 +10,57 @@ sidebar_position: 2 开始之前,您需要安装 RSSHub 的依赖项。您可以在 RSSHub 的根目录下运行以下命令来完成安装: - - + + ```bash pnpm i ``` - - + + ```bash yarn ``` - - + + ```bash npm install ``` - - + + ## 开始调试 一旦您成功安装了依赖,您可以通过运行以下命令来开始调试 RSSHub: - - + + ```bash pnpm run dev ``` - - + + ```bash yarn dev ``` - - + + ```bash npm run dev ``` - - + + 请务必密切关注控制台输出的任何错误消息或其他有用的信息,这些信息可以帮助您诊断和解决问题。另外,如果您遇到任何困难,不要犹豫向 RSSHub 文档或社区寻求帮助。 @@ -78,8 +78,10 @@ npm run dev 制作新的 RSS 路由的第一步是创建命名空间。命名空间应该与您制作 RSS 源的主要网站的二级域名**相同**。例如,如果您正在为 制作 RSS 源,第二级域名是 `github`。因此,您应该在 `lib/v2` 下创建名为 `github` 的文件夹,作为您的 RSS 路由的命名空间。 -:::tip 提示 +:::tip + 在创建命名空间时,避免为同一命名空间的创建多个变体。例如,如果您为 `yahoo.co.jp` 和 `yahoo.com` 制作 RSS 源,则应该使用单个命名空间 `yahoo`,而不是创建多个命名空间如 `yahoo-jp`、`yahoojp`、`yahoo.jp`、`jp.yahoo`、`yahoocojp` 等。 + ::: ## 理解基础知识 @@ -90,26 +92,28 @@ npm run dev 例如,如果您为 [GitHub 仓库 Issues](/zh/routes/programming#github-yong-hu-cang-ku) 制作 RSS 源,并且假设您希望用户输入 GitHub 用户名和仓库名,如果他们没有输入仓库名,则返回到 `RSSHub`,您可以使用以下代码在 `github/router.js` 中注册您的新 RSS 路由: - - + + -```js{2} +```js module.exports = (router) => { + // highlight-next-line router.get('/issue/:user/:repo?', require('./issue')); }; ``` - - + + -```js{2} +```js module.exports = function (router) { + // highlight-next-line router.get('/issue/:user/:repo?', require('./issue')); }; ``` - - + + 在 `router.js` 中注册您的新 RSS 路由时,您可以定义路由路径并指定要执行的相应函数。在上面的代码中,`router.get()` 方法用于指定新的 RSS 路由的 HTTP 方法和路径。`router.get()` 的第一个参数是使用 [path-to-regexp](https://github.com/pillarjs/path-to-regexp) 语法的路由路径。第二个参数是您新的 RSS 规则 `issue.js` 中导出的函数。您可以省略 `.js` 扩展名。 @@ -121,16 +125,19 @@ module.exports = function (router) { 您可以使用 `*` 或 `+` 符号来匹配路径的其余部分,例如 `/some/path/:variable*`。请注意,`*` 和 `+` 分别意味着“零个或多个”和“一个或多个”。您还可以使用模式,例如 `/some/path/:variable(\\d+)?`,甚至是正则表达式。 -:::tip 提示 +:::tip + 有关 `router` 的更高级用法,请参阅 [@koa/router API 参考文档](https://github.com/koajs/router/blob/master/API.md)。 + ::: ### maintainer.js 该文件用于存储 RSS 路由的维护者信息。您可以将您的 GitHub 用户名添加到该值数组中。请注意,此处的键应与 `router.js` 中的路径完全匹配: -```js{2} +```js module.exports = { + // highlight-next-line '/issue/:user/:repo?': ['DIYgod'], }; ``` diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md index 63d58e4f780408..a7a81d817fe10a 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md @@ -23,8 +23,8 @@ sidebar_position: 3 以下是让您开始的基本代码: - - + + ```js // 导入所需模组 @@ -40,18 +40,19 @@ module.exports = async (ctx) => { }; ``` - - + + ### 获取用户输入 如前所述,我们需要从用户输入中获取 GitHub 用户名和仓库名称。如果请求 URL 中未提供仓库名称,则应默认为 `RSSHub`。您可以使用以下代码实现: - - + + -```js{2} +```js module.exports = async (ctx) => { + // highlight-next-line const { user, repo = 'RSSHub' } = ctx.params; ctx.state.data = { @@ -60,13 +61,15 @@ module.exports = async (ctx) => { }; ``` - - + + -```js{2,3} +```js module.exports = async (ctx) => { + // highlight-start const user = ctx.params.user; const repo = ctx.params.repo ?? 'RSSHub'; + // highlight-end ctx.state.data = { // 在此处输出您的 RSS @@ -74,8 +77,8 @@ module.exports = async (ctx) => { }; ``` - - + + 这两个代码片段都执行相同的操作。第一个使用对象解构将 `user` 和 `repo` 变量赋值,而第二个使用传统赋值和空值合并运算符在请求 URL 中未提供它的情况下将 `repo` 变量分配默认值 `RSSHub`。 @@ -83,12 +86,13 @@ module.exports = async (ctx) => { 在获取用户输入后,我们可以使用它向 API 发送请求。大多数情况下,您需要使用 `@/utils/got` 中的 `got`(一个自订的 [got](https://www.npmjs.com/package/got) 包装函数)发送 HTTP 请求。有关更多信息,请参阅 [got 文档](https://github.com/sindresorhus/got/tree/v11#usage)。 - - + + -```js{3-14} +```js module.exports = async (ctx) => { const { user, repo = 'RSSHub' } = ctx.params; + // highlight-start // 发送 HTTP GET 请求到 API 并解构返回的数据对象 const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { @@ -101,6 +105,7 @@ module.exports = async (ctx) => { per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, }, }); + // highlight-end ctx.state.data = { // 在此处输出您的 RSS @@ -108,13 +113,14 @@ module.exports = async (ctx) => { }; ``` - - + + -```js{4-14} +```js module.exports = async (ctx) => { const user = ctx.params.user; const repo = ctx.params.repo ?? 'RSSHub'; + // highlight-start // 发送 HTTP GET 请求到 API const response = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { @@ -126,6 +132,7 @@ module.exports = async (ctx) => { }); // response.data 是上述请求返回的数据对象 const data = response.data; + // highlight-end ctx.state.data = { // 在此处输出您的 RSS @@ -133,8 +140,8 @@ module.exports = async (ctx) => { }; ``` - - + + ### 生成 RSS 源 @@ -144,10 +151,10 @@ module.exports = async (ctx) => { 以下是应有的最终代码: - - + + -```js{16-30,32-39} +```js const got = require('@/utils/got'); const { parseDate } = require('@/utils/parse-date'); @@ -163,6 +170,7 @@ module.exports = async (ctx) => { }, }); + // highlight-start // 从 API 响应中提取相关数据 const items = data.map((item) => ({ // 文章标题 @@ -179,6 +187,7 @@ module.exports = async (ctx) => { category: item.labels.map((label) => label.name), })); + // highlight-start ctx.state.data = { // 源标题 title: `${user}/${repo} issues`, @@ -187,13 +196,14 @@ module.exports = async (ctx) => { // 源文章 item: items, }; + // highlight-end }; ``` - - + + -```js{16-36} +```js const got = require('@/utils/got'); const { parseDate } = require('@/utils/parse-date'); @@ -209,6 +219,7 @@ module.exports = async (ctx) => { }, }); + // highlight-start ctx.state.data = { // 源标题 title: `${user}/${repo} issues`, @@ -230,11 +241,12 @@ module.exports = async (ctx) => { category: item.labels.map((label) => label.name), })); }; + // highlight-end }; ``` - - + + ## 通过 got 从 HTML 获取数据 @@ -267,10 +279,12 @@ module.exports = async (ctx) => { 如前所述,我们需要从用户输入中获取 GitHub 用户名和仓库名称。如果请求 URL 中未提供仓库名称,则应默认为 `RSSHub`。您可以使用以下代码实现: -```js{2-3} +```js module.exports = async (ctx) => { + // highlight-start // 从 URL 参数中获取用户名和仓库名称 const { user, repo = 'RSSHub' } = ctx.params; + // highlight-end ctx.state.data = { // 在此处输出您的 RSS @@ -286,20 +300,23 @@ module.exports = async (ctx) => { 首先,我们将向 API 发送 HTTP GET 请求,并将 HTML 响应加载到 Cheerio 中,Cheerio 是一个帮助我们解析和操作 HTML 的库。 -```js{5-6} +```js const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; // 注意,".data" 属性包含了请求返回的目标页面的完整 HTML 源代码 + // highlight-start const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); + // highlight-end ``` 接下来,我们将使用 Cheerio 选择器选择相关的 HTML 元素,解析我们需要的数据,并将其转换为数组。 -```js{3-21} +```js // 我们使用 Cheerio 选择器选择所有带类名“js-navigation-container”的“div”元素, // 其中包含带类名“flex-auto”的子元素。 + // highlight-start const item = $('div.js-navigation-container .flex-auto') // 使用“toArray()”方法将选择的所有 DOM 元素以数组的形式返回。 .toArray() @@ -319,6 +336,7 @@ module.exports = async (ctx) => { .map((item) => $(item).text()), }; }); + // highlight-end ctx.state.data = { // 在此处输出您的 RSS @@ -333,7 +351,7 @@ module.exports = async (ctx) => { 以下是应有的最终代码: -```js{29-36} +```js const got = require('@/utils/got'); const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); @@ -362,6 +380,7 @@ module.exports = async (ctx) => { }; }); + // highlight-start ctx.state.data = { // 源标题 title: `${user}/${repo} issues`, @@ -370,6 +389,7 @@ module.exports = async (ctx) => { // 源文章 item: items, }; + // highlight-end }; ``` @@ -379,7 +399,7 @@ module.exports = async (ctx) => { 以下是更新后的代码: -```js{12,29-43,48} +```js const got = require('@/utils/got'); const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); @@ -391,6 +411,7 @@ module.exports = async (ctx) => { const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); + // highlight-next-line const list = $('div.js-navigation-container .flex-auto') .toArray() .map((item) => { @@ -408,6 +429,7 @@ module.exports = async (ctx) => { }; }); + // highlight-start const items = await Promise.all( list.map((item) => ctx.cache.tryGet(item.link, async () => { @@ -423,10 +445,12 @@ module.exports = async (ctx) => { }) ) ); + // highlight-end ctx.state.data = { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, + // highlight-next-line item: items, }; }; @@ -435,10 +459,12 @@ module.exports = async (ctx) => { 现在,这个 RSS 源将具有类似于原始网站的阅读体验。 -:::tip 提示 +:::tip + 请注意,在先前的部分中,我们仅需向 API 发送一个 HTTP 请求即可获得所需的所有数据。然而,在此部分中,我们需要发送 `1 + n` 个 HTTP 请求,其中 `n` 是从第一个请求获取的文章列表中的数量。 部分网站可能不喜欢在短时间内接收大量请求,并返回类似于“429 Too Many Requests”的错误。 + ::: ## 使用通用配置路由 @@ -476,7 +502,7 @@ module.exports = async (ctx) => { 我们的 RSS 订阅源目前缺少内容。必须设置 `item` 才能添加内容。以下是一个示例: -```js{15-22} +```js const buildData = require('@/utils/common-config'); module.exports = async (ctx) => { @@ -491,6 +517,7 @@ module.exports = async (ctx) => { title: `${user}/${repo} issues`, baseUrl: 'https://github.com', }, + // highlight-start item: { item: 'div.js-navigation-container .flex-auto', // 如果要使用变量,必须使用模板字符串 @@ -499,6 +526,7 @@ module.exports = async (ctx) => { // description: ..., 目前没有文章正文 pubDate: `parseDate($('relative-time').attr('datetime'))`, }, + // highlight-end }); }; ``` @@ -509,10 +537,12 @@ module.exports = async (ctx) => { 要获取每个 GitHub Issue 的正文,你需要添加一些代码。以下是一个示例: -```js{2-3,25-34} +```js const buildData = require('@/utils/common-config'); +// highlight-start const got = require('@/utils/got'); const cheerio = require('cheerio'); +// highlight-end module.exports = async (ctx) => { const { user, repo = 'RSSHub' } = ctx.params; @@ -534,6 +564,7 @@ module.exports = async (ctx) => { }, }); + // highlight-start await Promise.all( ctx.state.data.item.map((item) => ctx.cache.tryGet(item.link, async () => { @@ -544,6 +575,7 @@ module.exports = async (ctx) => { }) ) ); + // highlight-end }; ``` @@ -576,10 +608,10 @@ module.exports = async (ctx) => { 现在,我们将使用 `puppeteer` 代替 `got` 来从网页获取数据。 - - + + -```js{9-33,39-40} +```js const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); const logger = require('@/utils/logger'); @@ -588,6 +620,7 @@ module.exports = async (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; + // highlight-start // 导入 puppeteer 工具类并初始化浏览器实例 const browser = await require('@/utils/puppeteer')(); // 打开一个新标签页 @@ -613,13 +646,16 @@ module.exports = async (ctx) => { const response = await page.content(); // 关闭标签页 page.close(); + // highlight-end const $ = cheerio.load(response); // const item = ...; + // highlight-start // 不要忘记关闭浏览器实例 browser.close(); + // highlight-end ctx.state.data = { // 在此处输出您的 RSS @@ -627,10 +663,10 @@ module.exports = async (ctx) => { } ``` - - + + -```js{9} +```js const got = require('@/utils/got'); const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); @@ -639,6 +675,7 @@ module.exports = async (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; + // highlight-next-line const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); @@ -648,14 +685,14 @@ module.exports = async (ctx) => { } ``` - - + + ### 获取完整文章 使用浏览器新标签页获取每个 GitHub Issue 的正文,类似于 [上一节](#tong-guo-got-cong-html-huo-qu-shu-ju-geng-hao-de-yue-du-ti-yan)。我们可以使用以下代码: -```js{46-60,71-72} +```js const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); const logger = require('@/utils/logger'); @@ -701,6 +738,7 @@ module.exports = async (ctx) => { const items = await Promise.all( list.map((item) => ctx.cache.tryGet(item.link, async () => { + // highlight-start // 重用浏览器实例并打开新标签页 const page = await browser.newPage(); // 设置请求拦截,仅允许 HTML 请求 @@ -716,6 +754,7 @@ module.exports = async (ctx) => { const response = await page.content(); // 获取 HTML 内容后关闭标签页 page.close(); + // highlight-end const $ = cheerio.load(response); @@ -726,8 +765,10 @@ module.exports = async (ctx) => { ) ); + // highlight-start // 所有请求完成后关闭浏览器实例 browser.close(); + // highlight-end ctx.state.data = { title: `${user}/${repo} issues`, diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md index 731d21c4576f3f..a910e22c9e20ed 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md @@ -1,6 +1,6 @@ # 通用参数 -:::tip 提示 +:::tip 通用参数实际上是 URI 中的 query,可以使用 `&` 连接组合使用,效果叠加。 @@ -41,13 +41,13 @@ https://rsshub.app/twitter/user/durov/ ## 内容过滤 -:::caution 注意 +:::caution 请务必显式进行[彻底的 URL 编码](https://gchq.github.io/CyberChef/#recipe=URL_Encode\(true\))。切勿依赖浏览器的自动 URL 编码,某些字符,如 `+`, `&`,将不会被自动编码,进而导致最终解析结果不正确。 ::: -:::caution 注意 +:::caution filter 支持正则表达式。由于正则部分特性可被利用于 DoS (ReDOS),默认引擎`re2`屏蔽了部分`Regexp`功能,且在部分情况下表现不一致。具体差异可以[查看文档](https://github.com/uhop/node-re2#limitations-things-re2-does-not-support) @@ -142,7 +142,7 @@ Telegram 即时预览模式需要在官网制作页面处理模板,请前往[ ## 多媒体处理 -:::caution 注意 +:::caution 这是个测试中的 API diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/usage.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/usage.md index 8c499f1e93c064..c548fb4ba96d74 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/usage.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/usage.md @@ -22,29 +22,29 @@ RSSHub 的发展离不开社区的力量,欢迎编写你感兴趣的订阅源[ ### 安装 - - + + ```bash pnpm add rsshub ``` - - + + ```bash yarn add rsshub ``` - - + + ```bash npm install rsshub --save ``` - - + + ### 使用 diff --git a/website/sidebars.js b/website/sidebars.js index 49aebbed313acf..e38ac1f7e79533 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -45,29 +45,121 @@ const sidebars = { description: 'Routes are the access paths of RSSHub. Each route contains a RSSHub rule, which tells RSSHub how to extract content from the website and generate RSS subscription.', }, items: [ - 'routes/social-media', - 'routes/new-media', - 'routes/traditional-media', - 'routes/bbs', - 'routes/blog', - 'routes/programming', - 'routes/design', - 'routes/live', - 'routes/multimedia', - 'routes/picture', - 'routes/anime', - 'routes/program-update', - 'routes/university', - 'routes/forecast', - 'routes/travel', - 'routes/shopping', - 'routes/game', - 'routes/reading', - 'routes/government', - 'routes/study', - 'routes/journal', - 'routes/finance', - 'routes/other', + { + type: 'doc', + id: 'routes/social-media', + label: '💬 Social Media', + }, + { + type: 'doc', + id: 'routes/new-media', + label: '📱 New media', + }, + { + type: 'doc', + id: 'routes/traditional-media', + label: '📰 News', + }, + { + type: 'doc', + id: 'routes/bbs', + label: '💬️ BBS', + }, + { + type: 'doc', + id: 'routes/blog', + label: '🖊️️ Blog', + }, + { + type: 'doc', + id: 'routes/programming', + label: '💻 Programming', + }, + { + type: 'doc', + id: 'routes/design', + label: '🎨️ Design', + }, + { + type: 'doc', + id: 'routes/live', + label: '🎥 Live', + }, + { + type: 'doc', + id: 'routes/multimedia', + label: '🔊 Multimedia', + }, + { + type: 'doc', + id: 'routes/picture', + label: '🖼️ Picture', + }, + { + type: 'doc', + id: 'routes/anime', + label: '🎨️ ACG', + }, + { + type: 'doc', + id: 'routes/program-update', + label: '🔄 Application Updates', + }, + { + type: 'doc', + id: 'routes/university', + label: '🎓 University', + }, + { + type: 'doc', + id: 'routes/forecast', + label: '❗️ Forecast and Alerts', + }, + { + type: 'doc', + id: 'routes/travel', + label: '🛫 Travel', + }, + { + type: 'doc', + id: 'routes/shopping', + label: '🛍️ Shopping', + }, + { + type: 'doc', + id: 'routes/game', + label: '🎮 Gaming', + }, + { + type: 'doc', + id: 'routes/reading', + label: '📚 Reading', + }, + { + type: 'doc', + id: 'routes/government', + label: '📢 Government', + }, + { + type: 'doc', + id: 'routes/study', + label: '📖 Study', + }, + { + type: 'doc', + id: 'routes/journal', + label: '🔬 Scientific Journal', + }, + { + type: 'doc', + id: 'routes/finance', + label: '💰 Finance', + }, + { + type: 'doc', + id: 'routes/other', + label: '🔍 Uncategorized', + }, ], collapsible: false, }, diff --git a/website/src/theme/MDXComponents.js b/website/src/theme/MDXComponents.js new file mode 100644 index 00000000000000..65aef3383044cb --- /dev/null +++ b/website/src/theme/MDXComponents.js @@ -0,0 +1,14 @@ +import MDXComponents from '@theme-original/MDXComponents'; +import Badge from '@site/src/components/Badge'; +import Route from '@site/src/components/Route'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +// https://docusaurus.io/docs/markdown-features/react#mdx-component-scope +export default { + ...MDXComponents, + Badge, + Route, + Tabs, + TabItem, +};