diff --git a/.oxlintrc.json b/.oxlintrc.json index 08ae09ef4a..0c7e2ae920 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -195,6 +195,7 @@ "unicorn-js/no-array-sort-for-min-max": "error", "unicorn-js/no-array-splice": "error", "unicorn-js/no-async-promise-finally": "error", + "unicorn-js/no-async-iterator-callback": "error", // "unicorn/no-await-expression-member": "error", "unicorn/no-await-in-promise-methods": "error", // "unicorn-js/no-blob-to-file": "error", // unused @@ -292,7 +293,8 @@ "unicorn-js/no-unsafe-property-key": "error", // "unicorn-js/no-unsafe-sqlite-interpolation": "error", // unused "unicorn-js/no-unsafe-string-replacement": "error", - "unicorn-js/no-unused-array-method-return": "error", + "unicorn-js/no-unused-builtin-method-return": "error", + "unicorn-js/no-unused-iterator-helper": "error", "unicorn-js/no-useless-boolean-cast": "error", "unicorn-js/no-useless-coercion": "error", "unicorn/no-useless-collection-argument": "error", @@ -311,9 +313,11 @@ "unicorn-js/no-useless-re-export": "error", // "unicorn-js/no-useless-recursion": "error", unopinionated "unicorn/no-useless-spread": "error", + "unicorn-js/no-useless-set-construction": "error", // "unicorn/no-useless-switch-case": "error", "unicorn-js/no-useless-template-literals": "error", // "unicorn/no-useless-undefined": "error", + "unicorn-js/no-using-resource-escape": "error", "unicorn-js/no-xor-as-exponentiation": "error", "unicorn/no-zero-fractions": "error", // "unicorn/number-literal-case": "error", @@ -342,6 +346,7 @@ "unicorn-js/prefer-block-statement-over-iife": "error", "unicorn-js/prefer-boolean-return": "error", "unicorn/prefer-class-fields": "error", + "unicorn-js/prefer-combined-guards": "error", // "unicorn/prefer-classlist-toggle": "error", // unused // "unicorn/prefer-code-point": "error", "unicorn-js/prefer-continue": "error", @@ -372,6 +377,7 @@ "unicorn-js/prefer-iterable-in-constructor": "error", "unicorn-js/prefer-iterator-helpers": "error", "unicorn-js/prefer-iterator-to-array": "error", + "unicorn-js/prefer-iterator-zip": "error", // "unicorn-js/prefer-iterator-to-array-at-end": "error", // "unicorn/prefer-keyboard-event-key": "error", // unused "unicorn-js/prefer-location-assign": "error", @@ -431,6 +437,7 @@ // "unicorn/prefer-string-starts-ends-with": "error", use typescript/prefer-string-starts-ends-with "unicorn/prefer-string-trim-start-end": "error", "unicorn/prefer-structured-clone": "error", + "unicorn-js/prefer-temporal-conversion": "error", // "unicorn/prefer-switch": "error", "unicorn/prefer-ternary": "error", "unicorn-js/prefer-then-catch": "error", diff --git a/eslint-plugins/nsfw-flag.js b/eslint-plugins/nsfw-flag.js index a4cbc5eb19..1a0e7926d9 100644 --- a/eslint-plugins/nsfw-flag.js +++ b/eslint-plugins/nsfw-flag.js @@ -141,71 +141,73 @@ export default eslintCompatPlugin({ const routeDeclaration = node.declaration.declarations[0]; const routeObject = routeDeclaration.init; - if (routeObject && routeObject.type === 'ObjectExpression') { - let featuresProperty = null; - let nsfwProperty = null; + if (!routeObject || routeObject.type !== 'ObjectExpression') { + return; + } - // 查找 features 属性 - for (const prop of routeObject.properties) { - if (!(prop.type === 'Property' && prop.key && prop.key.name === 'features')) { - continue; - } + let featuresProperty = null; + let nsfwProperty = null; - featuresProperty = prop; + // 查找 features 属性 + for (const prop of routeObject.properties) { + if (!(prop.type === 'Property' && prop.key && prop.key.name === 'features')) { + continue; + } - // 在 features 中查找 nsfw 属性 - if (prop.value && prop.value.type === 'ObjectExpression') { - for (const featureProp of prop.value.properties) { - if (!(featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw')) { - continue; - } + featuresProperty = prop; - nsfwProperty = featureProp; - break; + // 在 features 中查找 nsfw 属性 + if (prop.value && prop.value.type === 'ObjectExpression') { + for (const featureProp of prop.value.properties) { + if (!(featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw')) { + continue; } + + nsfwProperty = featureProp; + break; } - break; } + break; + } - // 检查是否需要添加或修复 nsfw 标志 - if (!featuresProperty) { - // 没有 features 属性,需要添加整个 features 对象 - context.report({ - node: routeObject, - messageId: 'missingNsfwFlag', - fix(fixer) { - // 在对象的最后添加 features 属性 - const lastProperty = routeObject.properties.at(-1); + // 检查是否需要添加或修复 nsfw 标志 + if (!featuresProperty) { + // 没有 features 属性,需要添加整个 features 对象 + context.report({ + node: routeObject, + messageId: 'missingNsfwFlag', + fix(fixer) { + // 在对象的最后添加 features 属性 + const lastProperty = routeObject.properties.at(-1); - return lastProperty - ? fixer.insertTextAfter(lastProperty, ',\n features: {\n nsfw: true,\n }') - : // 空对象的情况 - fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n features: {\n nsfw: true,\n }\n'); - }, - }); - } else if (!nsfwProperty) { - // 有 features 属性但没有 nsfw 属性 - context.report({ - node: featuresProperty.value, - messageId: 'missingNsfwFlag', - fix(fixer) { - const featuresObject = featuresProperty.value; - if (featuresObject.properties.length > 0) { - const lastFeatureProp = featuresObject.properties.at(-1); - return fixer.insertTextAfter(lastFeatureProp, ',\n nsfw: true'); - } - // features 是空对象 - return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n nsfw: true,\n '); - }, - }); - } else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) { - // nsfw 属性存在但不是 true - context.report({ - node: nsfwProperty.value, - messageId: 'missingNsfwFlag', - fix: (fixer) => fixer.replaceText(nsfwProperty.value, 'true'), - }); - } + return lastProperty + ? fixer.insertTextAfter(lastProperty, ',\n features: {\n nsfw: true,\n }') + : // 空对象的情况 + fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n features: {\n nsfw: true,\n }\n'); + }, + }); + } else if (!nsfwProperty) { + // 有 features 属性但没有 nsfw 属性 + context.report({ + node: featuresProperty.value, + messageId: 'missingNsfwFlag', + fix(fixer) { + const featuresObject = featuresProperty.value; + if (featuresObject.properties.length > 0) { + const lastFeatureProp = featuresObject.properties.at(-1); + return fixer.insertTextAfter(lastFeatureProp, ',\n nsfw: true'); + } + // features 是空对象 + return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n nsfw: true,\n '); + }, + }); + } else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) { + // nsfw 属性存在但不是 true + context.report({ + node: nsfwProperty.value, + messageId: 'missingNsfwFlag', + fix: (fixer) => fixer.replaceText(nsfwProperty.value, 'true'), + }); } }, }), diff --git a/lib/api/radar/rules/utils.ts b/lib/api/radar/rules/utils.ts index 7291c28168..0c8b921616 100644 --- a/lib/api/radar/rules/utils.ts +++ b/lib/api/radar/rules/utils.ts @@ -21,25 +21,26 @@ export const getRadarRules = async (): Promise> => { const parsedDomain = parse(new URL('https://' + radarItem.source[0]).hostname); const subdomain = parsedDomain.subdomain || '.'; const domain = parsedDomain.domain; - if (domain) { - if (!Object.hasOwn(rules, domain)) { - rules[domain] = { - _name: namespaces[namespace].name, - } as RadarDomain; - } - if (!Object.hasOwn(rules[domain], subdomain)) { - rules[domain][subdomain] = []; - } - rules[domain][subdomain].push({ - title: radarItem.title || data.name, - docs: `https://docs.rsshub.app/routes/${data.categories?.[0] || 'other'}`, - source: radarItem.source.map((source) => { - const sourceURL = new URL('https://' + source); - return sourceURL.pathname + sourceURL.search + sourceURL.hash; - }), - target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath, - }); + if (!domain) { + continue; } + if (!Object.hasOwn(rules, domain)) { + rules[domain] = { + _name: namespaces[namespace].name, + } as RadarDomain; + } + if (!Object.hasOwn(rules[domain], subdomain)) { + rules[domain][subdomain] = []; + } + rules[domain][subdomain].push({ + title: radarItem.title || data.name, + docs: `https://docs.rsshub.app/routes/${data.categories?.[0] || 'other'}`, + source: radarItem.source.map((source) => { + const sourceURL = new URL('https://' + source); + return sourceURL.pathname + sourceURL.search + sourceURL.hash; + }), + target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath, + }); } } } diff --git a/lib/middleware/anti-hotlink.ts b/lib/middleware/anti-hotlink.ts index c028f70159..ab307d1d63 100644 --- a/lib/middleware/anti-hotlink.ts +++ b/lib/middleware/anti-hotlink.ts @@ -64,12 +64,14 @@ const replaceUrl = (template?: string, url?: string) => { const replaceUrls = ($: CheerioAPI, selector: string, template: string, attribute = 'src') => { $(selector).each((_, el) => { const oldSrc = $(el).attr(attribute); - if (oldSrc) { - const url = parseUrl(oldSrc); - if (url && url.protocol !== 'data:') { - // Cheerio will do the right thing to prohibit XSS. - $(el).attr(attribute, interpolate(template, url)); - } + if (!oldSrc) { + return; + } + + const url = parseUrl(oldSrc); + if (url && url.protocol !== 'data:') { + // Cheerio will do the right thing to prohibit XSS. + $(el).attr(attribute, interpolate(template, url)); } }); }; @@ -137,37 +139,39 @@ const middleware: MiddlewareHandler = async (ctx, next) => { // Use Cheerio to load the description as html and filter all // image link const data: Data = ctx.get('data'); - if (data) { - if (data.image) { - data.image = replaceUrl(imageHotlinkTemplate, data.image); - } - if (data.description) { - data.description = process(data.description, imageHotlinkTemplate, multimediaHotlinkTemplate); - } + if (!data) { + return; + } - if (data.item) { - for (const item of data.item) { - if (item.description) { - item.description = process(item.description, imageHotlinkTemplate, multimediaHotlinkTemplate); - } - if (item.enclosure_url && item.enclosure_type) { - if (item.enclosure_type.startsWith('image/')) { - item.enclosure_url = replaceUrl(imageHotlinkTemplate, item.enclosure_url); - } else if (/^(?:video|audio)\//.test(item.enclosure_type)) { - item.enclosure_url = replaceUrl(multimediaHotlinkTemplate, item.enclosure_url); - } - } - if (item.image) { - item.image = replaceUrl(imageHotlinkTemplate, item.image); - } - if (item.itunes_item_image) { - item.itunes_item_image = replaceUrl(imageHotlinkTemplate, item.itunes_item_image); + if (data.image) { + data.image = replaceUrl(imageHotlinkTemplate, data.image); + } + if (data.description) { + data.description = process(data.description, imageHotlinkTemplate, multimediaHotlinkTemplate); + } + + if (data.item) { + for (const item of data.item) { + if (item.description) { + item.description = process(item.description, imageHotlinkTemplate, multimediaHotlinkTemplate); + } + if (item.enclosure_url && item.enclosure_type) { + if (item.enclosure_type.startsWith('image/')) { + item.enclosure_url = replaceUrl(imageHotlinkTemplate, item.enclosure_url); + } else if (/^(?:video|audio)\//.test(item.enclosure_type)) { + item.enclosure_url = replaceUrl(multimediaHotlinkTemplate, item.enclosure_url); } } + if (item.image) { + item.image = replaceUrl(imageHotlinkTemplate, item.image); + } + if (item.itunes_item_image) { + item.itunes_item_image = replaceUrl(imageHotlinkTemplate, item.itunes_item_image); + } } - - ctx.set('data', data); } + + ctx.set('data', data); }; export default middleware; diff --git a/lib/middleware/template.tsx b/lib/middleware/template.tsx index cf26485248..a97726b7ab 100644 --- a/lib/middleware/template.tsx +++ b/lib/middleware/template.tsx @@ -79,17 +79,18 @@ const middleware: MiddlewareHandler = async (ctx, next) => { Math.floor(item.itunes_duration / 3600) + ':' + (Math.floor((item.itunes_duration % 3600) / 60) / 100).toFixed(2).slice(-2) + ':' + (((item.itunes_duration % 3600) % 60) / 100).toFixed(2).slice(-2); } - if (outputType !== 'rss') { - try { - item.pubDate &&= convertDateToISO8601(item.pubDate) || ''; - } catch { - item.pubDate = ''; - } - try { - item.updated &&= convertDateToISO8601(item.updated) || ''; - } catch { - item.updated = ''; - } + if (outputType === 'rss') { + continue; + } + try { + item.pubDate &&= convertDateToISO8601(item.pubDate) || ''; + } catch { + item.pubDate = ''; + } + try { + item.updated &&= convertDateToISO8601(item.updated) || ''; + } catch { + item.updated = ''; } } } diff --git a/lib/registry-helpers.ts b/lib/registry-helpers.ts index 5532f0057b..23899d3fb7 100644 --- a/lib/registry-helpers.ts +++ b/lib/registry-helpers.ts @@ -174,22 +174,24 @@ export function registerRssRoutes(app: Hono, namespaces: NamespacesType): void { for (const [path, routeData] of sortedRoutes) { const wrappedHandler: Handler = async (ctx) => { logger.debug(`Matched route: ${routePath(ctx)}`); - if (!ctx.get('data')) { - if (!routeData.handler) { - if (process.env.NODE_ENV === 'test') { - const { route } = await import(`./routes/${namespace}/${routeData.location}`); - routeData.handler = route.handler; - } else if (routeData.module) { - const { route } = await routeData.module(); - routeData.handler = route.handler; - } - } - const response = await routeData.handler(ctx); - if (response instanceof Response) { - return response; - } - ctx.set('data', response); + if (ctx.get('data')) { + return; } + + if (!routeData.handler) { + if (process.env.NODE_ENV === 'test') { + const { route } = await import(`./routes/${namespace}/${routeData.location}`); + routeData.handler = route.handler; + } else if (routeData.module) { + const { route } = await routeData.module(); + routeData.handler = route.handler; + } + } + const response = await routeData.handler(ctx); + if (response instanceof Response) { + return response; + } + ctx.set('data', response); }; subApp.get(path, wrappedHandler); } diff --git a/lib/routes/4khd/article.ts b/lib/routes/4khd/article.ts index 5f8ddf8ea0..575700ea78 100644 --- a/lib/routes/4khd/article.ts +++ b/lib/routes/4khd/article.ts @@ -8,10 +8,12 @@ const processImages = ($) => { $('a').each((_, elem) => { const $elem = $(elem); const largePhotoUrl = $elem.attr('href')?.replace('i0.wp.com', '').replace('pic.4khd.com', 'yt4.googleusercontent.com').replace('AsHYQ', 'AsYHQ').replace('l/AAA', 'I/AAA'); - if (largePhotoUrl) { - $elem.attr('href', largePhotoUrl); - $elem.find('img').attr('src', largePhotoUrl); + if (!largePhotoUrl) { + return; } + + $elem.attr('href', largePhotoUrl); + $elem.find('img').attr('src', largePhotoUrl); }); }; diff --git a/lib/routes/6v123/utils.ts b/lib/routes/6v123/utils.ts index 7ea686a78d..c9af0f9a43 100644 --- a/lib/routes/6v123/utils.ts +++ b/lib/routes/6v123/utils.ts @@ -45,12 +45,8 @@ export async function processItems(ctx, baseURL, exclude) { const pubDate = timezone(parseDate($(item).find('span').text().replaceAll(/[[\]]/g, ''), 'MM-DD'), 8); const text = link.text(); - if (href === undefined) { - return; - } - - if (exclude && exclude.some((e) => e.test(text))) { - // 过滤掉满足正则的标题条目 + // 过滤掉满足正则的标题条目 + if (href === undefined || (exclude && exclude.some((e) => e.test(text)))) { return; } diff --git a/lib/routes/ali213/news.ts b/lib/routes/ali213/news.ts index b33089a797..8dc4ced12f 100644 --- a/lib/routes/ali213/news.ts +++ b/lib/routes/ali213/news.ts @@ -97,19 +97,21 @@ export const handler = async (ctx: Context): Promise => { const mediaUrl: string | undefined = $$el.prop('src'); const mediaType: string | undefined = mediaUrl?.split(/\./).pop(); - if (mediaType && mediaUrl) { - media[mediaType] = { url: mediaUrl }; - - pEl.replaceWith( - renderDescription({ - images: [ - { - src: mediaUrl, - }, - ], - }) - ); + if (!(mediaType && mediaUrl)) { + return; } + + media[mediaType] = { url: mediaUrl }; + + pEl.replaceWith( + renderDescription({ + images: [ + { + src: mediaUrl, + }, + ], + }) + ); }); } diff --git a/lib/routes/ally/rail.ts b/lib/routes/ally/rail.ts index 8c47779818..315808c3d1 100644 --- a/lib/routes/ally/rail.ts +++ b/lib/routes/ally/rail.ts @@ -42,7 +42,7 @@ async function handler(ctx) { const response = await got.get(pageUrl); const $ = load(response.data); let title = ''; - const titleLinks = $('.container .regsiter a').toArray().slice(1); // what a typo... drop "首页" + const titleLinks = $('.container .regsiter a').slice(1).toArray(); // what a typo... drop "首页" for (const link of titleLinks) { const linkText = $(link).text(); title = title ? `${title} - ${linkText}` : linkText; diff --git a/lib/routes/bbc/learningenglish.ts b/lib/routes/bbc/learningenglish.ts index 048959b7ca..1cdfb9e885 100644 --- a/lib/routes/bbc/learningenglish.ts +++ b/lib/routes/bbc/learningenglish.ts @@ -54,8 +54,8 @@ async function handler(ctx: Context) { // get rest ul article links const restItems: DataItem[] = $('.threecol li') - .toArray() .slice(0, 10) + .toArray() .map((article) => { const $article = load(article); diff --git a/lib/routes/bbc/utils.tsx b/lib/routes/bbc/utils.tsx index 065e103f59..1a993778fe 100644 --- a/lib/routes/bbc/utils.tsx +++ b/lib/routes/bbc/utils.tsx @@ -295,10 +295,11 @@ const renderEmbedImages = (block: Block, index: number): JSX.Element | null => { const rawImageBlock = findBlocksByType(imageBlock.model?.blocks ?? imageBlock.blocks ?? imageBlock.items, 'rawImage')[0]; const width = rawImageBlock?.model?.width; - if (width && width > maxWidth) { - maxWidth = width; - largestImage = imageBlock; + if (!(width && width > maxWidth)) { + continue; } + maxWidth = width; + largestImage = imageBlock; } if (!largestImage) { diff --git a/lib/routes/bestofjs/monthly.tsx b/lib/routes/bestofjs/monthly.tsx index 7b247b44c1..db3969867c 100644 --- a/lib/routes/bestofjs/monthly.tsx +++ b/lib/routes/bestofjs/monthly.tsx @@ -170,8 +170,8 @@ const getMonthlyRankings = (year: string, month: string): Promise // Additional info (contributors, created date) const additionalInfo = $tr .find('td:nth-child(3) > div') - .toArray() .slice(1) + .toArray() .map((el) => $(el).text().trim()) .join('; '); return { diff --git a/lib/routes/bilibili/cache.ts b/lib/routes/bilibili/cache.ts index 9100d703a6..8166cb3507 100644 --- a/lib/routes/bilibili/cache.ts +++ b/lib/routes/bilibili/cache.ts @@ -28,10 +28,11 @@ const getConfiguredCookie = () => { // Update b_lsid in cookies for (const key of Object.keys(config.bilibili.cookies)) { const cookie = config.bilibili.cookies[key]; - if (cookie) { - const updatedCookie = cookie.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, () => `b_lsid=${utils.lsid()}`); - config.bilibili.cookies[key] = updatedCookie; + if (!cookie) { + continue; } + const updatedCookie = cookie.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, () => `b_lsid=${utils.lsid()}`); + config.bilibili.cookies[key] = updatedCookie; } return config.bilibili.cookies[Object.keys(config.bilibili.cookies)[Math.floor(Math.random() * Object.keys(config.bilibili.cookies).length)]] || ''; diff --git a/lib/routes/bilibili/wasm-exec.ts b/lib/routes/bilibili/wasm-exec.ts index 9a142d8cfb..a14b739bba 100644 --- a/lib/routes/bilibili/wasm-exec.ts +++ b/lib/routes/bilibili/wasm-exec.ts @@ -392,12 +392,14 @@ sp >>>= 0; const id = this.mem.getUint32(sp + 8, true); this._goRefCounts[id]--; - if (this._goRefCounts[id] === 0) { - const v = this._values[id]; - this._values[id] = null; - this._ids.delete(v); - this._idPool.push(id); + if (this._goRefCounts[id] !== 0) { + return; } + + const v = this._values[id]; + this._values[id] = null; + this._ids.delete(v); + this._idPool.push(id); }, // func stringVal(value string) ref diff --git a/lib/routes/bloomberg/utils.ts b/lib/routes/bloomberg/utils.ts index ee1c4459a9..136fce9c9c 100644 --- a/lib/routes/bloomberg/utils.ts +++ b/lib/routes/bloomberg/utils.ts @@ -287,18 +287,20 @@ const processLedeMedia = async (story_json) => { } return ''; } - if (story_json.type === 'Lede') { - const props = story_json.props; - - const media = { - kind: props.media, - caption: props.caption?.replaceAll(capRegex, '') ?? '', - description: props.dek?.replaceAll(capRegex, '') ?? '', - credit: props.credit?.replaceAll(capRegex, '') ?? '', - src: props.url, - }; - return renderLedeMedia(media); + if (story_json.type !== 'Lede') { + return; } + + const props = story_json.props; + + const media = { + kind: props.media, + caption: props.caption?.replaceAll(capRegex, '') ?? '', + description: props.dek?.replaceAll(capRegex, '') ?? '', + credit: props.credit?.replaceAll(capRegex, '') ?? '', + src: props.url, + }; + return renderLedeMedia(media); }; const processBody = async (body_html, story_json) => { diff --git a/lib/routes/blowstudio/work.ts b/lib/routes/blowstudio/work.ts index 09f8fe09ae..2ce08a6848 100644 --- a/lib/routes/blowstudio/work.ts +++ b/lib/routes/blowstudio/work.ts @@ -17,7 +17,7 @@ async function handler() { const rootUrl = 'https://www.blowstudio.es'; const response = await ofetch(`${rootUrl}/work/`); const $ = load(response); - const list = $('.portfolios.normal > ul > li').toArray().slice(0, 10); + const list = $('.portfolios.normal > ul > li').slice(0, 10).toArray(); const videostyle = 'width="640" height="360"'; const imgstyle = 'style="max-width: 650px; height: auto; object-fit: contain; flex: 0 0 auto;"'; diff --git a/lib/routes/buaa/sme.ts b/lib/routes/buaa/sme.ts index ac30ae1c0d..d61899352b 100755 --- a/lib/routes/buaa/sme.ts +++ b/lib/routes/buaa/sme.ts @@ -66,8 +66,8 @@ async function getList(url) { const { data } = await got(url); const $ = load(data); const title = $('.nytit .fr a') - .toArray() .slice(1) + .toArray() .map((item) => $(item).text().trim()) .join(' - '); const list = $("div[class='Newslist'] > ul > li") diff --git a/lib/routes/bwu/news.ts b/lib/routes/bwu/news.ts index 351d7583f1..b4c6e8c0ee 100644 --- a/lib/routes/bwu/news.ts +++ b/lib/routes/bwu/news.ts @@ -27,8 +27,8 @@ async function handler() { const $ = load(response); const list = $('div[class=subPage] div ul li') - .toArray() .slice(0, 25) + .toArray() .map((item) => { const $item = $(item); const aTag = $item.find('a'); diff --git a/lib/routes/caixin/utils-fulltext.ts b/lib/routes/caixin/utils-fulltext.ts index 1e80d71014..1f905d5b42 100644 --- a/lib/routes/caixin/utils-fulltext.ts +++ b/lib/routes/caixin/utils-fulltext.ts @@ -11,10 +11,7 @@ const rsaPrivateKey = '-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCLci8q2u3NGFyFlMUwjCP91PsvGjHdRAq9fmqZLxvue+n+RhzNxnKKYOv35pLgFKWXsGq2TV+5Xrv6xZgNx36IUkqbmrO+eCa8NFmti04wvMfG3DCNdKA7Lue880daNiK3BOhlQlZPykUXt1NftMNS/z+e70W+Vpv1ZxCx5BipqZkdoceM3uin0vUQmqmHqjxi5qKUuov90dXLaMxypCA0TDsIDnX8RPvPtqKff1p2TMW2a0XYe7CPYhRggaQMpmo0TcFutgrM1Vywyr2TPxYR+H/tpuuWRET7tUIQykBYoO1WKfL2dX6cxarjAJfnYnod3sMzppHouyp8Pt7gHVG7AgMBAAECggEAEFshSy6IrADKgWSUyH/3jMNZfwnchW6Ar/9O847CAPQJ2yhQIpa/Qpnhs58Y5S2myqcHrUBgFPcWp3BbyGn43naAh8XahWHEcVjWl/N6BV9vM1UKYN0oGikDR3dljCBDbCIoPBBO3WcFOaXoIpaqPmbwCG1aSdwQyPUA0UzG08eDbuHK6L5jvbe3xv5kLpWTVddrocW+SakbZRAX1Ykp7IujOce235nM7GOfoq4b8jmK5CLg6VIZGQV20wnn9YxuFOndRSjneFberzfzBMhVLpPsQ16M2xDLpZaDTggZnq2L6nZygds8Hda++ga3WbD3TcgjJNYuENu1S88IowYhSQKBgQDFqRA+38mo6KsxVDCNWcuEk2hSq8NEUzRHJpS7/QjZmEIYpFzDXgSGwhZJ0WNsQtaxJeBbc7B/OOqh8TL1reLl5AdTimS1OLHWVf/MUsLVS7Y82hx/hpYWxZnRSq41oI3P8FO/53FiQMYo2wbwqF6uQjB1y8h58aqL3OYpTH/5xQKBgQC0mobALJ+bU4nCPzkVDZuD6RyNWPwS1aE3+925wDSN2rJ0iLIb4N5czWZmHb66VlAtfGbp2q+amsCV4r6UR19A/y8k9SFB0mdtxix6mjEfaGhVJm4B1mkvsn0OHMAanKkohUvCjROQc3sziyp2gqSEQ98G7//VMPx/3dhgyQpVfwKBgQCycsqu6N0n+D6t/0MCKiJaI7bYhCd7JN8aqVM4UN5PjG2Hz8PLwbK2cr0qkbaAA+vN7NMb3Vtn0FvMLnUCZqVlRTP0EQqQrYmoZuXUcpdhd8QkNgnqe/g+wND4qcKTucquA1uo8mtj9/Su5+bhGDC6hBk6D+uDZFHDiX/loyIavQKBgQCXF6AcLjjpDZ52b8Yloti0JtXIOuXILAlQeNoqiG5vLsOVUrcPM7VUFlLQo5no8kTpiOXgRyAaS9VKkAO4sW0zR0n9tUY5dvkokV6sw0rNZ9/BPQFTcDlXug99OvhMSzwJtlqHTNdNRg+QM6E2vF0+ejmf6DEz/mN/5e0cK5UFqQKBgCR2hVfbRtDz9Cm/P8chPqaWFkH5ulUxBpc704Igc6bVH5DrEoWo6akbeJixV2obAZO3sFyeJqBUqaCvqG17Xei6jn3Hc3WMz9nLrAJEI9BTCfwvuxCOyY0IxqAAYT28xYv42I4+ADT/PpCq2Dj5u43X0dapAjZBZDfVVis7q1Bw-----END PRIVATE KEY-----'; export async function getFulltext(url: string) { - if (!config.caixin.cookie) { - return; - } - if (!/\d+\.html/.test(url)) { + if (!config.caixin.cookie || !/\d+\.html/.test(url)) { return; } const articleID = url.match(/(\d+)\.html/)![1]; diff --git a/lib/routes/capitalmind/utils.ts b/lib/routes/capitalmind/utils.ts index 3a09455ef5..156ddd7e72 100644 --- a/lib/routes/capitalmind/utils.ts +++ b/lib/routes/capitalmind/utils.ts @@ -98,14 +98,18 @@ export async function fetchArticles(path) { // Remove srcset attribute $img.removeAttr('srcset'); - if (src && src.startsWith('/_next/image')) { - // Extract the original URL from the Next.js image URL - const urlMatch = src.match(/url=([^&]+)/); - if (urlMatch && urlMatch[1]) { - const originalUrl = decodeURIComponent(urlMatch[1]); - $img.attr('src', originalUrl); - } + if (!src?.startsWith('/_next/image')) { + return; } + + // Extract the original URL from the Next.js image URL + const urlMatch = src.match(/url=([^&]+)/); + if (!urlMatch?.[1]) { + return; + } + + const originalUrl = decodeURIComponent(urlMatch[1]); + $img.attr('src', originalUrl); }); return { title, diff --git a/lib/routes/cczu/jwc.ts b/lib/routes/cczu/jwc.ts index 3762efc98a..e1e260b2fd 100644 --- a/lib/routes/cczu/jwc.ts +++ b/lib/routes/cczu/jwc.ts @@ -38,8 +38,8 @@ async function handler(ctx: Context) { link: pageUrl, title: category === 'all' ? baseTitle : `${baseTitle} ${$('title').text()}`, item: $('div[id^="wp_news_w"] a') - .toArray() .slice(0, 10) + .toArray() .filter((elem) => entryUrlRegex.test(elem.attribs.href)) .map((elem) => ({ link: new URL(elem.attribs.href, pageUrl).href, diff --git a/lib/routes/cczu/news.ts b/lib/routes/cczu/news.ts index 052cfe3d23..81539a76ad 100644 --- a/lib/routes/cczu/news.ts +++ b/lib/routes/cczu/news.ts @@ -35,8 +35,8 @@ async function handler(ctx: Context) { link: pageUrl, title: category === 'all' ? baseTitle : `${baseTitle} ${$('title').text()}`, item: $('.news_title a') - .toArray() .slice(0, 10) + .toArray() .filter((elem) => entryUrlRegex.test(elem.attribs.href)) .map((elem) => ({ link: new URL(elem.attribs.href, pageUrl).href, diff --git a/lib/routes/cfr/utils.ts b/lib/routes/cfr/utils.ts index 0d688cce24..53e6ed6359 100644 --- a/lib/routes/cfr/utils.ts +++ b/lib/routes/cfr/utils.ts @@ -245,14 +245,18 @@ function parseLinkData($: CheerioAPI) { function getVideoIframe($ele: Cheerio) { const setup = $ele.find('video').data('setup') as VideoSetup; - if (setup) { - const youtubeSource = setup.sources.find((i) => i.type === 'video/youtube'); - if (youtubeSource) { - const videoId = youtubeSource.src.match(/\?v=([^&]+)/)?.[1]; - if (videoId) { - return ``; - } - } + if (!setup) { + return; + } + + const youtubeSource = setup.sources.find((i) => i.type === 'video/youtube'); + if (!youtubeSource) { + return; + } + + const videoId = youtubeSource.src.match(/\?v=([^&]+)/)?.[1]; + if (videoId) { + return ``; } } diff --git a/lib/routes/cgtn/opinions.ts b/lib/routes/cgtn/opinions.ts index 4232d8fd82..3af753162c 100644 --- a/lib/routes/cgtn/opinions.ts +++ b/lib/routes/cgtn/opinions.ts @@ -23,8 +23,8 @@ async function handler() { $('.cg-pic').parent().remove(); const list = $('.cg-title h3') - .toArray() .slice(0, 15) + .toArray() .map((item): DataItem => { const a = $(item).find('a'); return { diff --git a/lib/routes/chinadegrees/province.tsx b/lib/routes/chinadegrees/province.tsx index 84bd0c2c64..8b3ff7eab5 100644 --- a/lib/routes/chinadegrees/province.tsx +++ b/lib/routes/chinadegrees/province.tsx @@ -100,8 +100,8 @@ async function handler(ctx) { return { title: $('caption').text().trim(), items: $('.datalist tr') - .toArray() .slice(1) + .toArray() .map((item): DataItem => { const $item = $(item); const title = $item.find('td').eq(1).text(); diff --git a/lib/routes/chinamoney/notice.ts b/lib/routes/chinamoney/notice.ts index 5c8ce37deb..aecedb23b0 100644 --- a/lib/routes/chinamoney/notice.ts +++ b/lib/routes/chinamoney/notice.ts @@ -94,10 +94,12 @@ async function handler(ctx) { }); article.find('.article-a-attach-body a').each((i, ele) => { const $ele = $(ele); - if ($ele.attr('onclick')?.startsWith("location.href=encodeURI($('#fileDownUrl').val()+'fileDownLoad.do")) { - $ele.attr('href', `${baseUrl}/dqs/cm-s-notice-query/fileDownLoad.do?mode=open&contentId=${item.contentId}&priority=${i}`); - $ele.removeAttr('onclick'); + if (!$ele.attr('onclick')?.startsWith("location.href=encodeURI($('#fileDownUrl').val()+'fileDownLoad.do")) { + return; } + + $ele.attr('href', `${baseUrl}/dqs/cm-s-notice-query/fileDownLoad.do?mode=open&contentId=${item.contentId}&priority=${i}`); + $ele.removeAttr('onclick'); }); item.description = article.html(); diff --git a/lib/routes/chnmuseum/zl.tsx b/lib/routes/chnmuseum/zl.tsx index 6c93e1a1cf..b2b5d8c50d 100644 --- a/lib/routes/chnmuseum/zl.tsx +++ b/lib/routes/chnmuseum/zl.tsx @@ -111,19 +111,21 @@ const fetchTargetElements = async (cleanType: string, subtype: string | undefine for (const el of pageElements) { const $item = $(el).closest('li'); - if ($item.length > 0) { - const rawLink = $(el).attr('href') || ''; - const rawZtzl = $(el).attr('ztzlurl') || ''; // some exhibition links have a separate detailed page, use ztzlurl to get the detailed exhibition link if available - - // Use exhibitionLink to remove the repeat ones - const itemLink = buildItemLink(rawLink, contextUrl, baseUrl); - const exhibitionLink = buildExhibitionLink(rawZtzl, itemLink, baseUrl); - - if (exhibitionLink && !seenLinks.has(exhibitionLink)) { - seenLinks.add(exhibitionLink); - items.push({ $item, contextUrl, itemLink, exhibitionLink, rawZtzl }); - } + if ($item.length === 0) { + continue; } + const rawLink = $(el).attr('href') || ''; + const rawZtzl = $(el).attr('ztzlurl') || ''; // some exhibition links have a separate detailed page, use ztzlurl to get the detailed exhibition link if available + + // Use exhibitionLink to remove the repeat ones + const itemLink = buildItemLink(rawLink, contextUrl, baseUrl); + const exhibitionLink = buildExhibitionLink(rawZtzl, itemLink, baseUrl); + + if (!exhibitionLink || seenLinks.has(exhibitionLink)) { + continue; + } + seenLinks.add(exhibitionLink); + items.push({ $item, contextUrl, itemLink, exhibitionLink, rawZtzl }); } }; diff --git a/lib/routes/cnki/author.ts b/lib/routes/cnki/author.ts index 1a9f0b43ee..8fcdbdbd10 100644 --- a/lib/routes/cnki/author.ts +++ b/lib/routes/cnki/author.ts @@ -122,8 +122,8 @@ async function handler(ctx) { }); const $ = load(response); const list = $('tr') - .toArray() .slice(1) + .toArray() .map((item) => { const title = $(item).find('a.fz14').text(); const filename = $(item).find('a.icon-collect').attr('data-filename'); diff --git a/lib/routes/consumer/shopping-guide.ts b/lib/routes/consumer/shopping-guide.ts index b95dffc361..518858c59b 100644 --- a/lib/routes/consumer/shopping-guide.ts +++ b/lib/routes/consumer/shopping-guide.ts @@ -66,10 +66,12 @@ async function handler(ctx) { const header = $('.article-img-blk'); header.find('img').each((_, ele) => { const $ele = $(ele); - if ($ele.attr('src') && $ele.attr('srcset')) { - $ele.removeAttr('srcset'); - $ele.attr('src', $ele.attr('src')!.replace(/\/\d+c\d+\//, '/0p0/')); + if (!($ele.attr('src') && $ele.attr('srcset'))) { + return; } + + $ele.removeAttr('srcset'); + $ele.attr('src', $ele.attr('src')!.replace(/\/\d+c\d+\//, '/0p0/')); }); item.description = header.html()! + $('article .ckec').html()!; diff --git a/lib/routes/coomer/index.tsx b/lib/routes/coomer/index.tsx index 81fc21ac9e..6116d96d12 100644 --- a/lib/routes/coomer/index.tsx +++ b/lib/routes/coomer/index.tsx @@ -97,10 +97,12 @@ async function handler(ctx) { const regex = /downloads.fanbox.cc/; $('a').each((_, el) => { const link = $(el).attr('href'); - if (regex.test(link!)) { - count++; - $(el).replaceWith(coomerFiles[count]); + if (!regex.test(link!)) { + return; } + + count++; + $(el).replaceWith(coomerFiles[count]); }); desc = (coomerFiles.length > 0 ? coomerFiles[0] : '') + $.html(); const remainingCoomerFiles = coomerFiles.slice(count + 1); diff --git a/lib/routes/cqust/jw.ts b/lib/routes/cqust/jw.ts index 3153036ae4..ad5bac7f86 100644 --- a/lib/routes/cqust/jw.ts +++ b/lib/routes/cqust/jw.ts @@ -36,8 +36,8 @@ async function handler(ctx: Context) { link, description: $('meta[name="description"]').attr('content') || '重科教务处', item: $('li[id^="lineu"]') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/cqust/lib.ts b/lib/routes/cqust/lib.ts index f938edcce5..86cba0ef8b 100644 --- a/lib/routes/cqust/lib.ts +++ b/lib/routes/cqust/lib.ts @@ -39,8 +39,8 @@ async function handler(ctx: Context) { link, description: $('meta[name="description"]').attr('content') || '重科图书馆公告', item: $('div[class="newsList"] li') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/daodu/index.ts b/lib/routes/daodu/index.ts index 90bc432e36..5c255076bd 100644 --- a/lib/routes/daodu/index.ts +++ b/lib/routes/daodu/index.ts @@ -29,8 +29,8 @@ async function handler(ctx: Context) { const $ = load(response); const list: DataItem[] = $('h2[itemprop="headline"] a, .post-header .archive__article__title a') - .toArray() .slice(0, 15) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/deadline/posts.tsx b/lib/routes/deadline/posts.tsx index 0df0900673..b7bb851a14 100644 --- a/lib/routes/deadline/posts.tsx +++ b/lib/routes/deadline/posts.tsx @@ -55,11 +55,13 @@ async function handler(ctx): Promise { $('.c-lazy-image__img').each((_, img) => { const $img = $(img); - if ($img.attr('data-lazy-src')) { - $img.attr('src', $img.attr('data-lazy-src')!.split('?', 1)[0]); - $img.removeAttr('data-lazy-src'); - $img.removeAttr('data-lazy-srcset'); + if (!$img.attr('data-lazy-src')) { + return; } + + $img.attr('src', $img.attr('data-lazy-src')!.split('?', 1)[0]); + $img.removeAttr('data-lazy-src'); + $img.removeAttr('data-lazy-srcset'); }); $('[class^="lrv-a-crop-"]').contents().unwrap(); diff --git a/lib/routes/dgut/xsc.ts b/lib/routes/dgut/xsc.ts index d11df6af2f..c3a75853c3 100644 --- a/lib/routes/dgut/xsc.ts +++ b/lib/routes/dgut/xsc.ts @@ -40,8 +40,8 @@ async function handler(ctx: Context) { link: `${host}${urlType}/index.shtml`, description: `东莞理工学院 ${name} ${info}`, item: $('#paging > ul li') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/discuz/discuz.ts b/lib/routes/discuz/discuz.ts index 800d43513a..744068a200 100644 --- a/lib/routes/discuz/discuz.ts +++ b/lib/routes/discuz/discuz.ts @@ -64,11 +64,13 @@ async function loadContent(itemLink, charset, header) { // fix lazyload image post.find('img').each((_, img) => { const $img = $(img); - if ($img.attr('src')?.endsWith('none.gif') && $img.attr('file')) { - $img.attr('src', $img.attr('file') || $img.attr('zoomfile')); - $img.removeAttr('file'); - $img.removeAttr('zoomfile'); + if (!($img.attr('src')?.endsWith('none.gif') && $img.attr('file'))) { + return; } + + $img.attr('src', $img.attr('file') || $img.attr('zoomfile')); + $img.removeAttr('file'); + $img.removeAttr('zoomfile'); }); // 只抓取论坛1楼消息 diff --git a/lib/routes/domp4/utils.ts b/lib/routes/domp4/utils.ts index 04ec09a53e..ed0f26f675 100644 --- a/lib/routes/domp4/utils.ts +++ b/lib/routes/domp4/utils.ts @@ -80,10 +80,11 @@ function decodeCipherText(p, a, c, k, e, d) { } while (c--) { const replacement = k[c]; - if (replacement) { - const token = e(c.toString()); - p = p.replaceAll(new RegExp(String.raw`\b` + token + String.raw`\b`, 'g'), () => replacement); + if (!replacement) { + continue; } + const token = e(c.toString()); + p = p.replaceAll(new RegExp(String.raw`\b` + token + String.raw`\b`, 'g'), () => replacement); } return p; } diff --git a/lib/routes/douban/other/discussion.ts b/lib/routes/douban/other/discussion.ts index 437339143b..764de59d7e 100644 --- a/lib/routes/douban/other/discussion.ts +++ b/lib/routes/douban/other/discussion.ts @@ -41,8 +41,8 @@ async function handler(ctx) { const $ = load(response); // 列表 const list = $('#posts-table>tbody>tr') - .toArray() .slice(1) + .toArray() .map((item): DataItem => { const $item = $(item); const a = $item.find('a').first(); diff --git a/lib/routes/dribbble/utils.tsx b/lib/routes/dribbble/utils.tsx index 97d78b72ab..74f24ca168 100644 --- a/lib/routes/dribbble/utils.tsx +++ b/lib/routes/dribbble/utils.tsx @@ -34,13 +34,15 @@ async function loadContent(link) { const $video = $(video); const dataSrc = $video.attr('data-src'); - if (!$video.attr('src') && dataSrc) { - $video.attr('src', dataSrc); - $video.removeAttr('data-src'); - $video.removeAttr('data-video-small'); - $video.removeAttr('data-video-medium'); - $video.removeAttr('data-video-large'); + if ($video.attr('src') || !dataSrc) { + return; } + + $video.attr('src', dataSrc); + $video.removeAttr('data-src'); + $video.removeAttr('data-video-small'); + $video.removeAttr('data-video-medium'); + $video.removeAttr('data-video-large'); }); object.find('img').each((_, img) => { const $img = $(img); diff --git a/lib/routes/dxy/utils.ts b/lib/routes/dxy/utils.ts index 1da76f9884..4c01f87333 100644 --- a/lib/routes/dxy/utils.ts +++ b/lib/routes/dxy/utils.ts @@ -63,10 +63,12 @@ const getPost = (item) => $img.attr('src', hsrc); $img.removeAttr('data-hsrc'); } - if (osrc) { - $img.attr('src', osrc); - $img.removeAttr('data-osrc'); + if (!osrc) { + return; } + + $img.attr('src', osrc); + $img.removeAttr('data-osrc'); }); item.description = $.html(); diff --git a/lib/routes/ehentai/ehapi.ts b/lib/routes/ehentai/ehapi.ts index 02609f6073..924c85bd53 100644 --- a/lib/routes/ehentai/ehapi.ts +++ b/lib/routes/ehentai/ehapi.ts @@ -108,36 +108,38 @@ async function parsePage(cache, data, get_bittorrent: string | boolean = false, thumbnail = await ehgot_thumb(cache, thumbnail); } const description = `thumbnail`; - if (title && link) { - const item: DataItem & { bittorrent_page_url?: string } = { - title, - description, - pubDate, - link, - }; - if (get_bittorrent) { - const el_down = el.find('div.gldown'); - const bittorrent_page_url = el_down.find('a').attr('href'); - if (bittorrent_page_url) { - const bittorrent_url = await getBittorrent(cache, bittorrent_page_url); - if (bittorrent_url) { - item.enclosure_url = bittorrent_url; - item.enclosure_type = 'application/x-bittorrent'; - item.bittorrent_page_url = bittorrent_page_url; - } + if (!title || !link) { + return; + } + + const item: DataItem & { bittorrent_page_url?: string } = { + title, + description, + pubDate, + link, + }; + if (get_bittorrent) { + const el_down = el.find('div.gldown'); + const bittorrent_page_url = el_down.find('a').attr('href'); + if (bittorrent_page_url) { + const bittorrent_url = await getBittorrent(cache, bittorrent_page_url); + if (bittorrent_url) { + item.enclosure_url = bittorrent_url; + item.enclosure_type = 'application/x-bittorrent'; + item.bittorrent_page_url = bittorrent_page_url; } } - if ('le'.includes(layout)) { - // artist tags will only show in Compact or Extended layout - // get artist names as author - item.author = $(el) - .find('div.gt[title^="artist:"]') - .toArray() - .map((tag) => $(tag).text()) - .join(' / '); - } - return item; } + if ('le'.includes(layout)) { + // artist tags will only show in Compact or Extended layout + // get artist names as author + item.author = $(el) + .find('div.gt[title^="artist:"]') + .toArray() + .map((tag) => $(tag).text()) + .join(' / '); + } + return item; } const item_Promises: Array> = []; @@ -167,15 +169,17 @@ function getBittorrent(cache, bittorrent_page_url) { for (const el_form of el_forms) { const el_a = $(el_form).find('a'); const onclick = el_a.attr('onclick'); - if (onclick) { - const match = onclick.match(/'(.*?)'/); - if (match) { - bittorrent_url = match[1]; - const match_p = bittorrent_url.match(/torrent\?p=(.*)$/); - if (match_p) { - p = match_p[1]; - } - } + if (!onclick) { + continue; + } + const match = onclick.match(/'(.*?)'/); + if (!match) { + continue; + } + bittorrent_url = match[1]; + const match_p = bittorrent_url.match(/torrent\?p=(.*)$/); + if (match_p) { + p = match_p[1]; } } return bittorrent_url; diff --git a/lib/routes/eprice/rss.tsx b/lib/routes/eprice/rss.tsx index e9da68d686..96e5617e73 100644 --- a/lib/routes/eprice/rss.tsx +++ b/lib/routes/eprice/rss.tsx @@ -68,17 +68,19 @@ async function handler(ctx) { // fix lazyload image $('a').each((_, e) => { const $e = $(e); - if ($e.attr('href') && $e.attr('href')!.endsWith('.jpg')) { - $e.after( - renderToString( -
- {$e.attr('title') -
{$e.attr('title') ?? ''}
-
- ) - ); - $e.remove(); + if (!$e.attr('href')?.endsWith('.jpg')) { + return; } + + $e.after( + renderToString( +
+ {$e.attr('title') +
{$e.attr('title') ?? ''}
+
+ ) + ); + $e.remove(); }); $('img').each((_, e) => { const $e = $(e); diff --git a/lib/routes/espn/news.tsx b/lib/routes/espn/news.tsx index c6a3a9cc99..aa938d90da 100644 --- a/lib/routes/espn/news.tsx +++ b/lib/routes/espn/news.tsx @@ -119,15 +119,17 @@ export const route: Route = { if (junkPattern.test(name)) { $(ele).remove(); } - if (mediaPattern.test(name)) { - const mediaType = name.match(mediaPattern)![1] === 'photo' ? 'images' : 'video'; - const mediaIndex = Number.parseInt(name.match(mediaPattern)![2]) - 1; - const media = article.content[mediaType][mediaIndex]; - if (media) { - $(ele).replaceWith(renderMedia(media)); - } else { - $(ele).remove(); - } + if (!mediaPattern.test(name)) { + return; + } + + const mediaType = name.match(mediaPattern)![1] === 'photo' ? 'images' : 'video'; + const mediaIndex = Number.parseInt(name.match(mediaPattern)![2]) - 1; + const media = article.content[mediaType][mediaIndex]; + if (media) { + $(ele).replaceWith(renderMedia(media)); + } else { + $(ele).remove(); } }); diff --git a/lib/routes/fx678/kx.ts b/lib/routes/fx678/kx.ts index 57c272ad56..a2d069bd85 100644 --- a/lib/routes/fx678/kx.ts +++ b/lib/routes/fx678/kx.ts @@ -39,8 +39,8 @@ async function handler() { // 页面新闻消息列表 const list = $('.body_zb ul .body_zb_li .zb_word') .find('.list_font_pic > a:first-child') - .toArray() .slice(0, 30) + .toArray() .map((e) => $(e).attr('href')); const out = await Promise.all( diff --git a/lib/routes/google/news.tsx b/lib/routes/google/news.tsx index 09acbec324..af29d83309 100644 --- a/lib/routes/google/news.tsx +++ b/lib/routes/google/news.tsx @@ -36,8 +36,8 @@ async function handler(ctx) { const $ = load(front_data); return [ ...$('a.brSCsc') - .toArray() .slice(3) // skip Home, For you and Following + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/gov/beijing/mhc.ts b/lib/routes/gov/beijing/mhc.ts index 8f58c779d7..12245b6aba 100644 --- a/lib/routes/gov/beijing/mhc.ts +++ b/lib/routes/gov/beijing/mhc.ts @@ -53,8 +53,8 @@ async function handler(ctx: Context) { const $ = load(response); const list = $('div.weinei_left_con div.weinei_left_con_line') - .toArray() .slice(0, 10) + .toArray() .map((item): DataItem => { const $item = $(item); const a = $item.find('a[title]'); diff --git a/lib/routes/gov/ccdi/utils.ts b/lib/routes/gov/ccdi/utils.ts index 66e1d9d17d..193882051f 100644 --- a/lib/routes/gov/ccdi/utils.ts +++ b/lib/routes/gov/ccdi/utils.ts @@ -58,16 +58,18 @@ export const parseNewsList = async (url, selector, ctx) => { const changeTrCookie = async () => { const cookies = await cookieJar.getCookies(rootUrl); const c = cookies.find((c) => c.key === 'HOY_TR'); - if (c) { - const value = c.value; - const tr_array = value.split(','); - const csr = tr_array[0]; - const cnv = [...tr_array[1]]; - const otr = [...tr_array[2]]; - otr[0] = csr.charAt(Number.parseInt(cnv[0], 16)); - const nc = new Cookie({ key: 'HOY_TR', value: csr + ',' + cnv.join('') + ',' + otr.join('') + ',0' }); - await cookieJar.setCookie(nc, rootUrl); + if (!c) { + return; } + + const value = c.value; + const tr_array = value.split(','); + const csr = tr_array[0]; + const cnv = [...tr_array[1]]; + const otr = [...tr_array[2]]; + otr[0] = csr.charAt(Number.parseInt(cnv[0], 16)); + const nc = new Cookie({ key: 'HOY_TR', value: csr + ',' + cnv.join('') + ',' + otr.join('') + ',0' }); + await cookieJar.setCookie(nc, rootUrl); }; export const parseArticle = async (item) => { diff --git a/lib/routes/gov/nsfc/index.ts b/lib/routes/gov/nsfc/index.ts index 482585c40e..02d8076aa8 100644 --- a/lib/routes/gov/nsfc/index.ts +++ b/lib/routes/gov/nsfc/index.ts @@ -112,8 +112,8 @@ async function handler(ctx) { return { item: items, title: `国家自然科学基金委员会 - ${$('#ess_essBREADCRUMB_lblBreadCrumb a.break') - .toArray() .slice(1) + .toArray() .map((a) => $(a).text()) .join(' - ')}`, link: currentUrl, diff --git a/lib/routes/govopendata/xinwenlianbo.ts b/lib/routes/govopendata/xinwenlianbo.ts index b2d1a53942..ef99de9bda 100644 --- a/lib/routes/govopendata/xinwenlianbo.ts +++ b/lib/routes/govopendata/xinwenlianbo.ts @@ -23,8 +23,8 @@ async function handler() { const $ = load(response); const list = $('article.news-card') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); const a = $item.find('h2.news-title a'); diff --git a/lib/routes/huijin-inv/news.ts b/lib/routes/huijin-inv/news.ts index 6ba1d575cb..6e25c65ff6 100644 --- a/lib/routes/huijin-inv/news.ts +++ b/lib/routes/huijin-inv/news.ts @@ -21,12 +21,14 @@ async function handler(): Promise { let redirectPath = DEFAULT_REDIRECT_PATH; $scripts.each((_, el) => { const redirectScript = $entry(el).text(); - if (redirectScript !== null) { - // Get the real index page by JS redirection href. The path may change. - const match = redirectScript.match(/window\.location\.href\s*=\s*["']([^"']+)["']/); - if (match) { - redirectPath = match[1]; - } + if (redirectScript === null) { + return; + } + + // Get the real index page by JS redirection href. The path may change. + const match = redirectScript.match(/window\.location\.href\s*=\s*["']([^"']+)["']/); + if (match) { + redirectPath = match[1]; } }); const redirectURL = `${BASE_URL}${redirectPath}`; diff --git a/lib/routes/iapp/news.ts b/lib/routes/iapp/news.ts index 03b9f52b44..ec8b96527d 100644 --- a/lib/routes/iapp/news.ts +++ b/lib/routes/iapp/news.ts @@ -36,11 +36,13 @@ async function handler(ctx: Context) { $('script').each((_, el) => { const text = $(el).text(); const match = text.match(/\\"appID\\":\\"(\w+)\\",\\"apiKey\\":\\"(\w+)\\"/); - if (match) { - appId = match[1]; - apiKey = match[2]; - return false; + if (!match) { + return; } + + appId = match[1]; + apiKey = match[2]; + return false; }); if (!appId || !apiKey) { throw new Error('Failed to extract Algolia credentials from iapp.org'); diff --git a/lib/routes/inuki-ichiba/utils.ts b/lib/routes/inuki-ichiba/utils.ts index 8be3570da9..4329e8ac0f 100644 --- a/lib/routes/inuki-ichiba/utils.ts +++ b/lib/routes/inuki-ichiba/utils.ts @@ -50,11 +50,8 @@ export const parseJpy = (text: string | null): number | null => { if (/無償|なし|無し/.test(s)) { return 0; } - if (isUnknown(s)) { - return null; - } // Without 円 / 万 only a bare number is accepted ('3ヶ月' is not an amount). - if (!/[円万億]/.test(s) && !/^\d+(?:\.\d+)?$/.test(s)) { + if (isUnknown(s) || (!/[円万億]/.test(s) && !/^\d+(?:\.\d+)?$/.test(s))) { return null; } const oku = s.match(/^(\d+(?:\.\d+)?)億(?:(\d+(?:\.\d+)?)万)?/); diff --git a/lib/routes/ithome/zt.tsx b/lib/routes/ithome/zt.tsx index 8ca1ce8b94..f081e1afa8 100644 --- a/lib/routes/ithome/zt.tsx +++ b/lib/routes/ithome/zt.tsx @@ -63,10 +63,12 @@ export const handler = async (ctx) => { const src = $el.prop('data-original'); - if (src) { - const alt = $el.prop('alt'); - $el.replaceWith(renderToString(
{alt ? {alt} : }
)); + if (!src) { + return; } + + const alt = $el.prop('alt'); + $el.replaceWith(renderToString(
{alt ? {alt} : }
)); }); const title = $$('h1').text(); diff --git a/lib/routes/jike/topic-text.ts b/lib/routes/jike/topic-text.ts index cff9914905..5b903fc01a 100644 --- a/lib/routes/jike/topic-text.ts +++ b/lib/routes/jike/topic-text.ts @@ -38,17 +38,19 @@ async function handler(ctx) { const data = await constructTopicEntry(ctx, topicUrl); - if (data) { - const result = data.result; - result.item = data.posts.map((item) => { - const date = dayjs(item.createdAt); - return { - title: `${data.topic.content} ${date.format('MM月DD日')}`, - description: item.content.replaceAll('\n', '
'), - pubDate: date.toDate(), - link: `https://m.okjike.com/originalPosts/${item.id}`, - }; - }); - return result; + if (!data) { + return; } + + const result = data.result; + result.item = data.posts.map((item) => { + const date = dayjs(item.createdAt); + return { + title: `${data.topic.content} ${date.format('MM月DD日')}`, + description: item.content.replaceAll('\n', '
'), + pubDate: date.toDate(), + link: `https://m.okjike.com/originalPosts/${item.id}`, + }; + }); + return result; } diff --git a/lib/routes/jike/topic.ts b/lib/routes/jike/topic.ts index 463f922320..b2d9ebd695 100644 --- a/lib/routes/jike/topic.ts +++ b/lib/routes/jike/topic.ts @@ -51,36 +51,38 @@ async function handler(ctx) { const data = await constructTopicEntry(ctx, topicUrl); - if (data) { - const result = data.result; - result.item = topicDataHanding(data, ctx); - if (id === '553870e8e4b0cafb0a1bef68' || id === '55963702e4b0d84d2c30ce6f') { - result.item = await Promise.all( - result.item.map(async (one) => { - const item = { ...one }; - const regResult = /https:\/\/www\.okjike\.com\/medium\/[\dA-Za-z]*/.exec(item.description); - if (regResult) { - const newsUrl = regResult[0]; - item.description = await cache.tryGet(newsUrl, async () => { - const { data } = await got(newsUrl); - const $ = load(data); - const upper = $('ul.main > li.item'); - const links = upper.find('a').map((_, ele) => $(ele).attr('href')); - const texts = upper.find('span.text').map((_, ele) => $(ele).text()); - let description = ''; - for (let i = 0; i < links.length; i++) { - description += `${i + 1}、${texts[i]}
`; - } - description = description.replace(/
$/, ''); - return description; - }); - } - item.description = item.description.replaceAll(urlRegex, (url) => `${url}`); - item.title = `${data.topic.content} ${dayjs(one.pubDate).format('MM月DD日')}`; - return item; - }) - ); - } - return result; + if (!data) { + return; } + + const result = data.result; + result.item = topicDataHanding(data, ctx); + if (id === '553870e8e4b0cafb0a1bef68' || id === '55963702e4b0d84d2c30ce6f') { + result.item = await Promise.all( + result.item.map(async (one) => { + const item = { ...one }; + const regResult = /https:\/\/www\.okjike\.com\/medium\/[\dA-Za-z]*/.exec(item.description); + if (regResult) { + const newsUrl = regResult[0]; + item.description = await cache.tryGet(newsUrl, async () => { + const { data } = await got(newsUrl); + const $ = load(data); + const upper = $('ul.main > li.item'); + const links = upper.find('a').map((_, ele) => $(ele).attr('href')); + const texts = upper.find('span.text').map((_, ele) => $(ele).text()); + let description = ''; + for (let i = 0; i < links.length; i++) { + description += `${i + 1}、${texts[i]}
`; + } + description = description.replace(/
$/, ''); + return description; + }); + } + item.description = item.description.replaceAll(urlRegex, (url) => `${url}`); + item.title = `${data.topic.content} ${dayjs(one.pubDate).format('MM月DD日')}`; + return item; + }) + ); + } + return result; } diff --git a/lib/routes/kaoyan/kaoyan.ts b/lib/routes/kaoyan/kaoyan.ts index 397d36fbe0..335ba849bd 100644 --- a/lib/routes/kaoyan/kaoyan.ts +++ b/lib/routes/kaoyan/kaoyan.ts @@ -20,8 +20,8 @@ async function handler() { const $ = load(response); const items = $('.areaZslist li') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/kemono/index.tsx b/lib/routes/kemono/index.tsx index 6120567254..cf2e908e8f 100644 --- a/lib/routes/kemono/index.tsx +++ b/lib/routes/kemono/index.tsx @@ -164,13 +164,15 @@ function generateEnclosureInfo(htmlContent: string): { enclosure_url?: string; e const extension = extractFileExtension(src); const mimeType = MIME_TYPE_MAP[extension as keyof typeof MIME_TYPE_MAP]; - if (mimeType) { - enclosureInfo = { - enclosure_url: new URL(src, KEMONO_ROOT_URL).href, - enclosure_type: mimeType, - }; - return false; + if (!mimeType) { + return; } + + enclosureInfo = { + enclosure_url: new URL(src, KEMONO_ROOT_URL).href, + enclosure_type: mimeType, + }; + return false; }); return enclosureInfo; @@ -332,10 +334,12 @@ function processPosts(posts: KemonoPost[], authorName: string, limit: number) { const fanboxRegex = /downloads\.fanbox\.cc/; $('a').each((_, el) => { const link = $(el).attr('href'); - if (link && fanboxRegex.test(link)) { - $(el).replaceWith(kemonoFileElements[replacementCount] || ''); - replacementCount++; + if (!(link && fanboxRegex.test(link))) { + return; } + + $(el).replaceWith(kemonoFileElements[replacementCount] || ''); + replacementCount++; }); description = (kemonoFileElements[0] || '') + $.html(); diff --git a/lib/routes/kenshin/index.ts b/lib/routes/kenshin/index.ts index 8e087c26f6..e8fb37154b 100644 --- a/lib/routes/kenshin/index.ts +++ b/lib/routes/kenshin/index.ts @@ -63,8 +63,8 @@ async function handler(ctx: Context) { const $ = load(response); const list = $('.entry-title a') - .toArray() .slice(0, 10) + .toArray() .map((item): DataItem & { link: string } => { const $item = $(item); return { diff --git a/lib/routes/keylol/index.ts b/lib/routes/keylol/index.ts index d8971c8fa5..8dc86375ce 100644 --- a/lib/routes/keylol/index.ts +++ b/lib/routes/keylol/index.ts @@ -192,11 +192,13 @@ function getDescription($) { // handle lazyload image descriptionEl.find('img').each((_, img) => { const $img = $(img); - if ($img.attr('src')?.endsWith('none.gif') && $img.attr('file')) { - $img.attr('src', $img.attr('file')); - $img.removeAttr('file'); - $img.removeAttr('zoomfile'); + if (!($img.attr('src')?.endsWith('none.gif') && $img.attr('file'))) { + return; } + + $img.attr('src', $img.attr('file')); + $img.removeAttr('file'); + $img.removeAttr('zoomfile'); }); return descriptionEl.length > 0 ? descriptionEl.html() : $('div.alert_info').html(); diff --git a/lib/routes/kleinanzeigen/utils/get-product-page.ts b/lib/routes/kleinanzeigen/utils/get-product-page.ts index 0f4562c06f..3fb123e915 100644 --- a/lib/routes/kleinanzeigen/utils/get-product-page.ts +++ b/lib/routes/kleinanzeigen/utils/get-product-page.ts @@ -58,8 +58,8 @@ export const getProductPage = (url: string): Promise => const category = [ ...$('.breadcrump .breadcrump-link') - .toArray() .slice(1) + .toArray() .map((x) => $(x).text().trim()), product .find('.addetailslist--detail') diff --git a/lib/routes/latexstudio/home.ts b/lib/routes/latexstudio/home.ts index 27e4d985e6..a26eb763e0 100644 --- a/lib/routes/latexstudio/home.ts +++ b/lib/routes/latexstudio/home.ts @@ -23,8 +23,8 @@ async function handler() { const list = $('div.article-list') .find('h3.article-title') - .toArray() .slice(0, 20) + .toArray() .map((item): DataItem & { link: string } => { const a = $(item).find('a'); return { diff --git a/lib/routes/lfsyd/utils.tsx b/lib/routes/lfsyd/utils.tsx index 1ef1f2fc57..dfc45c074d 100644 --- a/lib/routes/lfsyd/utils.tsx +++ b/lib/routes/lfsyd/utils.tsx @@ -78,16 +78,18 @@ const cleanHtml = (htmlString) => { const bvid = $(e) .attr('src')! .match(/bvid=(.*?)&/)![1]; - if (bvid) { - const url = `https://www.bilibili.com/video/${bvid}`; - $(e).after( - renderToString( -

- {url} -

- ) - ); + if (!bvid) { + return; } + + const url = `https://www.bilibili.com/video/${bvid}`; + $(e).after( + renderToString( +

+ {url} +

+ ) + ); }); // 用户头像 diff --git a/lib/routes/lifetimes/index.ts b/lib/routes/lifetimes/index.ts index 4f64b0f031..bd80ee3d1c 100644 --- a/lib/routes/lifetimes/index.ts +++ b/lib/routes/lifetimes/index.ts @@ -53,8 +53,8 @@ async function handler(ctx: Context) { list = $('.list-block ul li, .firstCon-r ul li') .find('a') - .toArray() .slice(0, 10) + .toArray() .map((item) => ({ link: `https:${$(item).attr('href')}`, })); diff --git a/lib/routes/locals/feed.ts b/lib/routes/locals/feed.ts index 548586f013..7038546bae 100644 --- a/lib/routes/locals/feed.ts +++ b/lib/routes/locals/feed.ts @@ -407,11 +407,12 @@ async function fetchFeedData(communityId: number, community: string, session: st } const existing = items.get(item.link); - if (existing) { - existing.category = [...new Set([...(existing.category ?? []), ...(item.category ?? [])])]; - existing.description ||= item.description; - existing.itunes_item_image ||= item.itunes_item_image; + if (!existing) { + continue; } + existing.category = [...new Set([...(existing.category ?? []), ...(item.category ?? [])])]; + existing.description ||= item.description; + existing.itunes_item_image ||= item.itunes_item_image; } } diff --git a/lib/routes/lorientlejour/index.tsx b/lib/routes/lorientlejour/index.tsx index ae0bb8d972..7c63fb7845 100644 --- a/lib/routes/lorientlejour/index.tsx +++ b/lib/routes/lorientlejour/index.tsx @@ -161,10 +161,12 @@ async function handler(ctx) { article.find('.inlineImage').each((_, el) => { const inlineImageSrc = $(el).attr('src'); const inlineAttachment = item.inline_attachments.find((inlineAttachment) => inlineAttachment.url === inlineImageSrc); - if (inlineAttachment && inlineAttachment.description) { - $(el).wrap('
'); - $(el).after(`
${inlineAttachment.description}
`); + if (!(inlineAttachment && inlineAttachment.description)) { + return; } + + $(el).wrap('
'); + $(el).after(`
${inlineAttachment.description}
`); }); } item.description = renderToString( diff --git a/lib/routes/mashiro/index.ts b/lib/routes/mashiro/index.ts index b2a0a24afa..a05957cff4 100644 --- a/lib/routes/mashiro/index.ts +++ b/lib/routes/mashiro/index.ts @@ -27,8 +27,8 @@ export const route: Route = { const response = await ofetch(targetLink); const $ = load(response); const links = $('.archives-group article') - .toArray() .slice(0, 10) + .toArray() .map((item): DataItem => { const $item = $(item); const a = $item.find('a').first(); diff --git a/lib/routes/metacritic/release.ts b/lib/routes/metacritic/release.ts index 4153e87368..74dc012647 100644 --- a/lib/routes/metacritic/release.ts +++ b/lib/routes/metacritic/release.ts @@ -32,7 +32,7 @@ const handler = async (ctx) => { const data = response.body; const $ = load(data); - const list = $('.list_products > li').toArray().slice(0, 10); + const list = $('.list_products > li').slice(0, 10).toArray(); const result = list.map((item) => { const $ = load(item); diff --git a/lib/routes/nankai/graduate-notice.ts b/lib/routes/nankai/graduate-notice.ts index 90a3377fa0..e66b29e16b 100644 --- a/lib/routes/nankai/graduate-notice.ts +++ b/lib/routes/nankai/graduate-notice.ts @@ -99,14 +99,16 @@ export const route: Route = { const sudyfileAttr = ($el.attr('sudyfile-attr') || '{}').replaceAll("'", '"'); const sudyfileAttrJson = JSON.parse(sudyfileAttr); const fileName = sudyfileAttrJson.title || '未命名文件.pdf'; - if (pdfSrc) { - let pdfUrl = pdfSrc; - if (!pdfUrl.startsWith('http')) { - pdfUrl = `${baseUrl}${pdfUrl}`; - } - // 替换PDF播放器为下载链接 - $el.replaceWith(`

📄 ${fileName}

`); + if (!pdfSrc) { + return; } + + let pdfUrl = pdfSrc; + if (!pdfUrl.startsWith('http')) { + pdfUrl = `${baseUrl}${pdfUrl}`; + } + // 替换PDF播放器为下载链接 + $el.replaceWith(`

📄 ${fileName}

`); }); } diff --git a/lib/routes/nature/utils.ts b/lib/routes/nature/utils.ts index 40d9dfa50a..85a69e691e 100644 --- a/lib/routes/nature/utils.ts +++ b/lib/routes/nature/utils.ts @@ -11,32 +11,40 @@ const fixFigure = (html) => { html('picture source').each((_, i) => { const $i = html(i); if ( - $i.attr('srcset') && - ($i.attr('srcset').startsWith('//media.springernature.com/lw685/') || - $i.attr('srcset').startsWith('//media.springernature.com/m312/') || - $i.attr('srcset').startsWith('//media.springernature.com/relative-r300-703_m1050/') || - $i.attr('srcset').startsWith('//media.springernature.com/w300/')) + !( + $i.attr('srcset') && + ($i.attr('srcset').startsWith('//media.springernature.com/lw685/') || + $i.attr('srcset').startsWith('//media.springernature.com/m312/') || + $i.attr('srcset').startsWith('//media.springernature.com/relative-r300-703_m1050/') || + $i.attr('srcset').startsWith('//media.springernature.com/w300/')) + ) ) { - $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/')); - $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/m312/', '//media.springernature.com/full/')); - $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/')); - $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/w300/', '//media.springernature.com/full/')); + return; } + + $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/')); + $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/m312/', '//media.springernature.com/full/')); + $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/')); + $i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/w300/', '//media.springernature.com/full/')); }); html('img').each((_, i) => { const $i = html(i); if ( - $i.attr('src') && - ($i.attr('src').startsWith('//media.springernature.com/lw685/') || - $i.attr('src').startsWith('//media.springernature.com/m312/') || - $i.attr('src').startsWith('//media.springernature.com/relative-r300-703_m1050/') || - $i.attr('src').startsWith('//media.springernature.com/w300/')) + !( + $i.attr('src') && + ($i.attr('src').startsWith('//media.springernature.com/lw685/') || + $i.attr('src').startsWith('//media.springernature.com/m312/') || + $i.attr('src').startsWith('//media.springernature.com/relative-r300-703_m1050/') || + $i.attr('src').startsWith('//media.springernature.com/w300/')) + ) ) { - $i.attr('src', $i.attr('src').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/')); - $i.attr('src', $i.attr('src').replace('//media.springernature.com/m312/', '//media.springernature.com/full/')); - $i.attr('src', $i.attr('src').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/')); - $i.attr('src', $i.attr('src').replace('//media.springernature.com/w300/', '//media.springernature.com/full/')); + return; } + + $i.attr('src', $i.attr('src').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/')); + $i.attr('src', $i.attr('src').replace('//media.springernature.com/m312/', '//media.springernature.com/full/')); + $i.attr('src', $i.attr('src').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/')); + $i.attr('src', $i.attr('src').replace('//media.springernature.com/w300/', '//media.springernature.com/full/')); }); }; diff --git a/lib/routes/naver/search.ts b/lib/routes/naver/search.ts index aeeb9fe00b..a65a694c05 100644 --- a/lib/routes/naver/search.ts +++ b/lib/routes/naver/search.ts @@ -170,11 +170,7 @@ function extractGenericItem(segment: string, templateId: string) { bodyText = cleanText(bodyMatch[1]); } - if (!title || !link) { - return null; - } - - if (['더보기', '관련도순', '최신순'].includes(title)) { + if (!title || !link || ['더보기', '관련도순', '최신순'].includes(title)) { return null; } @@ -252,11 +248,7 @@ function parseKoreanRelativeTime(timeText: string): Date | undefined { } const match = timeText.match(/(\d+)\s*(시간|[분일주]) 전|(\d+)분 이내|(\d+)시간 이내|방금/); - if (!match) { - return; - } - - if (match[0] === '방금') { + if (!match || match[0] === '방금') { return; } diff --git a/lib/routes/ncu/jwc.ts b/lib/routes/ncu/jwc.ts index 3efff1afed..43ab5d9f64 100644 --- a/lib/routes/ncu/jwc.ts +++ b/lib/routes/ncu/jwc.ts @@ -74,10 +74,12 @@ async function handler(): Promise { attachments.each((_, el) => { const href = $detail(el).attr('href'); const text = $detail(el).text().trim(); - if (href && text) { - const absoluteHref = href.startsWith('http') ? href : new URL(href, baseUrl).href; - description += `
  • ${text}
  • `; + if (!href || !text) { + return; } + + const absoluteHref = href.startsWith('http') ? href : new URL(href, baseUrl).href; + description += `
  • ${text}
  • `; }); description += ''; } diff --git a/lib/routes/neu/yz.ts b/lib/routes/neu/yz.ts index 4f93ad332d..0892ae3ee6 100644 --- a/lib/routes/neu/yz.ts +++ b/lib/routes/neu/yz.ts @@ -120,20 +120,22 @@ const cleanEntryContent = ($) => { entry.find('.wp_video_player').each((_, el) => { const div = $(el); const src = div.attr('sudy-wp-src'); - if (src) { - const videoUrl = BASE_URL + src; - const widthMatch = div.attr('style')?.match(/width:\s*(\d+)px/); - const width = widthMatch && widthMatch[1] ? widthMatch[1] : '600'; - const heightMatch = div.attr('style')?.match(/height:\s*(\d+)px/); - const height = heightMatch && heightMatch[1] ? heightMatch[1] : '400'; - const videoTag = ` - - `; - div.replaceWith(videoTag); + if (!src) { + return; } + + const videoUrl = BASE_URL + src; + const widthMatch = div.attr('style')?.match(/width:\s*(\d+)px/); + const width = widthMatch && widthMatch[1] ? widthMatch[1] : '600'; + const heightMatch = div.attr('style')?.match(/height:\s*(\d+)px/); + const height = heightMatch && heightMatch[1] ? heightMatch[1] : '400'; + const videoTag = ` + + `; + div.replaceWith(videoTag); }); return entry.html(); }; diff --git a/lib/routes/nextjs/blog.ts b/lib/routes/nextjs/blog.ts index 532033d09c..70479beab8 100644 --- a/lib/routes/nextjs/blog.ts +++ b/lib/routes/nextjs/blog.ts @@ -12,8 +12,8 @@ const handler: Route['handler'] = async () => { const item = await Promise.all( $('article') - .toArray() .slice(0, 20) + .toArray() .map((item) => { const $ = load(item); const link = `https://nextjs.org${$('a[href^="/blog"]').attr('href')}`; diff --git a/lib/routes/notion/release.ts b/lib/routes/notion/release.ts index e39136725e..8e4e74bd8e 100644 --- a/lib/routes/notion/release.ts +++ b/lib/routes/notion/release.ts @@ -24,8 +24,8 @@ const handler: Route['handler'] = async () => { // archive const item = await Promise.all( $('div[class^="releasePreviewsSection"] h3 a[href^="/releases/"]') - .toArray() .slice(0, 5) + .toArray() .map((item) => { const link = `https://notion.so${item.attribs.href}`; diff --git a/lib/routes/pawchive/index.tsx b/lib/routes/pawchive/index.tsx index 2b9e25d92b..0a23fed0ec 100644 --- a/lib/routes/pawchive/index.tsx +++ b/lib/routes/pawchive/index.tsx @@ -24,13 +24,15 @@ function generateEnclosureInfo(htmlContent: string): { enclosure_url?: string; e const extension = src.replace(/.*\./, '').toLowerCase(); const mimeType = MIME_TYPE_MAP[extension as keyof typeof MIME_TYPE_MAP]; - if (mimeType) { - enclosureInfo = { - enclosure_url: src, - enclosure_type: mimeType, - }; - return false; + if (!mimeType) { + return; } + + enclosureInfo = { + enclosure_url: src, + enclosure_type: mimeType, + }; + return false; }); return enclosureInfo; diff --git a/lib/routes/picnob/user.ts b/lib/routes/picnob/user.ts index 80525a8647..3a841c50ac 100644 --- a/lib/routes/picnob/user.ts +++ b/lib/routes/picnob/user.ts @@ -89,8 +89,6 @@ async function handler(ctx) { const items = await Promise.all( list.map((item) => cache.tryGet(item.link, async () => { - let media = ''; - if (item.slideOrVideo) { const page = await context.newPage(); await page.route('**/*', (route) => { @@ -105,7 +103,7 @@ async function handler(ctx) { const html = await page.content(); const $ = load(html); - media = $('.slide-item').length + const media = $('.slide-item').length ? $('.slide-item div:first-of-type') .toArray() .map((item) => { diff --git a/lib/routes/pixiv/novel-series.ts b/lib/routes/pixiv/novel-series.ts index 35e687f152..d36911e02d 100644 --- a/lib/routes/pixiv/novel-series.ts +++ b/lib/routes/pixiv/novel-series.ts @@ -55,11 +55,8 @@ async function handler(ctx): Promise { const seriesInfo: SeriesDetail = seriesInfoResponse.data; // xRestrict: 0=All ages, 1=R18, 2=R18G - if (seriesInfo.body.xRestrict > 0) { - return await getNSFWSeriesNovels(id, limit); - } // All-ages: prefer NSFW handler if authenticated - if (hasPixivAuth()) { + if (seriesInfo.body.xRestrict > 0 || hasPixivAuth()) { return await getNSFWSeriesNovels(id, limit); } return await getSFWSeriesNovels(id, limit); diff --git a/lib/routes/pixiv/pixiv-got.ts b/lib/routes/pixiv/pixiv-got.ts index a6cfda3a33..568a02bd1b 100644 --- a/lib/routes/pixiv/pixiv-got.ts +++ b/lib/routes/pixiv/pixiv-got.ts @@ -47,17 +47,19 @@ const pixivGot = got.extend({ logger.warn(`No IPv4 address resolved from ${config.pixiv.bypassCdnHostname}`); } } - if (hostname) { - const actualHost = options.url.host; - options.headers = { - ...options.headers, - host: actualHost, - }; - options.url.hostname = hostname; - options.checkServerIdentity = function (host, certificate) { - return tls.checkServerIdentity(actualHost, certificate); - }; + if (!hostname) { + return; } + + const actualHost = options.url.host; + options.headers = { + ...options.headers, + host: actualHost, + }; + options.url.hostname = hostname; + options.checkServerIdentity = function (host, certificate) { + return tls.checkServerIdentity(actualHost, certificate); + }; }, ], }, diff --git a/lib/routes/pixivision/utils.ts b/lib/routes/pixivision/utils.ts index cd0f4c2770..e467e0e541 100644 --- a/lib/routes/pixivision/utils.ts +++ b/lib/routes/pixivision/utils.ts @@ -58,25 +58,29 @@ export function processContent($: CheerioAPI, lang: string): string { const $link = $elem.find('blockquote > a'); const href = $link.attr('href'); - if (href) { - const match = href.match(/\/status\/(\d+)/); - if (match) { - const tweetId = match[1]; - $elem.html(` - - `); - $elem.find('blockquote').remove(); - } + if (!href) { + return; } + + const match = href.match(/\/status\/(\d+)/); + if (!match) { + return; + } + + const tweetId = match[1]; + $elem.html(` + + `); + $elem.find('blockquote').remove(); }); return ( diff --git a/lib/routes/plurk/utils.ts b/lib/routes/plurk/utils.ts index 895f7f4f37..0a8bb20ac7 100644 --- a/lib/routes/plurk/utils.ts +++ b/lib/routes/plurk/utils.ts @@ -32,10 +32,12 @@ const getPlurk = (plurkGuid, item, author) => { $('img').each((_, e) => { const $e = $(e); $e.removeAttr('height').removeAttr('width'); - if ($e.attr('alt') && $e.attr('alt')!.startsWith('http')) { - $e.attr('src', $e.attr('alt')); - $e.removeAttr('alt'); + if (!($e.attr('alt') && $e.attr('alt')!.startsWith('http'))) { + return; } + + $e.attr('src', $e.attr('alt')); + $e.removeAttr('alt'); }); return { diff --git a/lib/routes/proletar/index.ts b/lib/routes/proletar/index.ts index e230b0565f..15c444e8c4 100644 --- a/lib/routes/proletar/index.ts +++ b/lib/routes/proletar/index.ts @@ -29,8 +29,8 @@ async function handler(ctx: Context) { const $ = load(response); const list: DataItem[] = $('.archive-item-link') - .toArray() .slice(0, 15) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/qnap/release-notes.ts b/lib/routes/qnap/release-notes.ts index 979f0189ed..51e981d916 100644 --- a/lib/routes/qnap/release-notes.ts +++ b/lib/routes/qnap/release-notes.ts @@ -28,8 +28,8 @@ async function handler(ctx: Context) { const $ = load(response); const list: DataItem[] = $('.release-notes-content__versions li') - .toArray() .slice(0, 20) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/qzcea/index.ts b/lib/routes/qzcea/index.ts index fd5fe1b6a0..2c297bfe55 100644 --- a/lib/routes/qzcea/index.ts +++ b/lib/routes/qzcea/index.ts @@ -32,8 +32,8 @@ async function handler(ctx: Context) { $('a.news-more').remove(); const list = $('li.clearfix div.news-right a') - .toArray() .slice(0, 10) + .toArray() .map((item): DataItem => { const $item = $(item); return { diff --git a/lib/routes/react/blog.ts b/lib/routes/react/blog.ts index c24a04741a..7d07ec856e 100644 --- a/lib/routes/react/blog.ts +++ b/lib/routes/react/blog.ts @@ -12,8 +12,8 @@ const handler: Route['handler'] = async () => { const item = await Promise.all( $('a[href^="/blog/"]') - .toArray() .slice(0, 20) + .toArray() .map((item) => { const link = `https://react.dev${item.attribs.href}`; diff --git a/lib/routes/rsshub/transform/html.ts b/lib/routes/rsshub/transform/html.ts index e674032493..1d21823c4e 100644 --- a/lib/routes/rsshub/transform/html.ts +++ b/lib/routes/rsshub/transform/html.ts @@ -77,8 +77,8 @@ Parsing of \`routeParams\` parameter: const rssTitle = routeParams.get('title') || $('title').text(); const item = routeParams.get('item') || 'html'; let items: DataItem[] = $(item) - .toArray() .slice(0, 20) + .toArray() .map((item) => { try { const $item = $(item); diff --git a/lib/routes/saraba1st/digest.tsx b/lib/routes/saraba1st/digest.tsx index 1efbcd6d8c..73191e5ec1 100644 --- a/lib/routes/saraba1st/digest.tsx +++ b/lib/routes/saraba1st/digest.tsx @@ -105,13 +105,15 @@ async function fetchContent(url) { stubS.find('img').each((_, el) => { const img = subind(el); const file = img.attr('file'); - if (file) { - img.attr('src', file); - img.removeAttr('zoomfile'); - img.removeAttr('file'); - img.removeAttr('onmouseover'); - img.removeAttr('onclick'); + if (!file) { + return; } + + img.attr('src', file); + img.removeAttr('zoomfile'); + img.removeAttr('file'); + img.removeAttr('onmouseover'); + img.removeAttr('onclick'); }); return stubS.html(); diff --git a/lib/routes/saraba1st/thread.ts b/lib/routes/saraba1st/thread.ts index a60befc90e..e5a87d8713 100644 --- a/lib/routes/saraba1st/thread.ts +++ b/lib/routes/saraba1st/thread.ts @@ -50,8 +50,8 @@ async function handler(ctx) { const staticUrl = new URL('/image/common/none.gif', host); staticUrl.hostname = `static.${staticUrl.hostname.split('.').slice(-2).join('.')}`; const resultItems = list - .toArray() .slice(0, 20) + .toArray() .map((post) => { const each = $(post); const floor = each.find('td.plc .pi a > em').text(); diff --git a/lib/routes/sigsac/ccs.ts b/lib/routes/sigsac/ccs.ts index 93ce105de2..5445ad32ec 100644 --- a/lib/routes/sigsac/ccs.ts +++ b/lib/routes/sigsac/ccs.ts @@ -60,8 +60,8 @@ async function handler() { }; }); const paperTable = $('tbody tr') - .toArray() .slice(1) // skip table header + .toArray() .map((item) => { const $item = $(item); const title = $item.find('td').eq(0).text().trim(); diff --git a/lib/routes/simpread/changelog.ts b/lib/routes/simpread/changelog.ts index f91f4e4628..97eb60f023 100644 --- a/lib/routes/simpread/changelog.ts +++ b/lib/routes/simpread/changelog.ts @@ -68,13 +68,15 @@ async function handler() { const text = span.html(); span.remove(); - if (spanClass !== undefined) { - const type = spanClass.split(' ', 2)[1]; - if (type === 'empty') { - $li.wrap('
      '); - } else { - $li.prepend(`${text}: `); - } + if (spanClass === undefined) { + return; + } + + const type = spanClass.split(' ', 2)[1]; + if (type === 'empty') { + $li.wrap('
        '); + } else { + $li.prepend(`${text}: `); } }); diff --git a/lib/routes/sis001/forum.ts b/lib/routes/sis001/forum.ts index f08f7f0dae..1718615d53 100644 --- a/lib/routes/sis001/forum.ts +++ b/lib/routes/sis001/forum.ts @@ -38,8 +38,8 @@ async function handler(ctx: Context) { const threads = $('form table') .last() .find('tbody') - .toArray() .slice(1) // skip first empty row + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/smzdm/utils.ts b/lib/routes/smzdm/utils.ts index 3df7a5b6b7..d01ff54ebd 100644 --- a/lib/routes/smzdm/utils.ts +++ b/lib/routes/smzdm/utils.ts @@ -6,11 +6,13 @@ export const parseSearchDate = (value: string, now = new Date()): Date | undefin if (/^\d{2}:\d{2}$/.test(value)) { return parseDateInTimezone(`${today}T${value}`, 8); } - if (/^\d{2}-\d{2} \d{2}:\d{2}$/.test(value)) { - // Search results omit the year; a later month/day belongs to last year. - const year = Number(today.slice(0, 4)) - Number(value.slice(0, 5) > today.slice(5)); - return parseDateInTimezone(`${year}-${value}`, 8); + if (!/^\d{2}-\d{2} \d{2}:\d{2}$/.test(value)) { + return; } + + // Search results omit the year; a later month/day belongs to last year. + const year = Number(today.slice(0, 4)) - Number(value.slice(0, 5) > today.slice(5)); + return parseDateInTimezone(`${year}-${value}`, 8); }; export const getHeaders = () => ({ diff --git a/lib/routes/snnu/ccs.ts b/lib/routes/snnu/ccs.ts index cf9cfcdf30..612d05270f 100644 --- a/lib/routes/snnu/ccs.ts +++ b/lib/routes/snnu/ccs.ts @@ -58,7 +58,7 @@ export const route: Route = { const configTarget = urlMap[type] || urlMap.tzgg; const response = await ofetch(configTarget.url); const $ = load(response); - const list = $('.lunwen dl dd').toArray().slice(0, 10); + const list = $('.lunwen dl dd').slice(0, 10).toArray(); const items = await Promise.all( list.map((item) => { diff --git a/lib/routes/snnu/index.ts b/lib/routes/snnu/index.ts index 5ce63aef0d..b887a8a890 100644 --- a/lib/routes/snnu/index.ts +++ b/lib/routes/snnu/index.ts @@ -31,7 +31,7 @@ export const route: Route = { const url = 'https://www.snnu.edu.cn/tzgg.htm'; const response = await ofetch(url); const $ = load(response); - const list = $('.ul-txtq3 li').toArray().slice(0, 10); + const list = $('.ul-txtq3 li').slice(0, 10).toArray(); const items = await Promise.all( list.map((item) => { diff --git a/lib/routes/snnu/yjs.ts b/lib/routes/snnu/yjs.ts index 76313269a5..dd5f030a34 100644 --- a/lib/routes/snnu/yjs.ts +++ b/lib/routes/snnu/yjs.ts @@ -31,7 +31,7 @@ export const route: Route = { const url = 'https://newyjs.snnu.edu.cn/tzgg1.htm'; const response = await ofetch(url); const $ = load(response); - const list = $('.n_bt li').toArray().slice(0, 10); + const list = $('.n_bt li').slice(0, 10).toArray(); const items = await Promise.all( list.map((item) => { diff --git a/lib/routes/socialbeta/home.ts b/lib/routes/socialbeta/home.ts index 0b39d721d8..9b9134aeed 100644 --- a/lib/routes/socialbeta/home.ts +++ b/lib/routes/socialbeta/home.ts @@ -29,7 +29,7 @@ async function handler() { link: a.attr('href')!, }; }); - const uniqueList = new Map(list.map((item) => [item.link, item])).values().toArray().slice(0, 15); + const uniqueList = new Map(list.map((item) => [item.link, item])).values().take(15).toArray(); const items = await Promise.all( uniqueList.map((item) => diff --git a/lib/routes/sohu/mp.tsx b/lib/routes/sohu/mp.tsx index a0400cd6ed..7418ed7657 100644 --- a/lib/routes/sohu/mp.tsx +++ b/lib/routes/sohu/mp.tsx @@ -89,10 +89,12 @@ function fetchArticle(item) { }); article.find('img').each((_, e) => { const $e = $(e); - if ($e.attr('data-src') && !$e.attr('src')) { - $e.attr('src', decryptImageUrl($e.attr('data-src'))); - $e.removeAttr('data-src'); + if (!$e.attr('data-src') || $e.attr('src')) { + return; } + + $e.attr('src', decryptImageUrl($e.attr('data-src'))); + $e.removeAttr('data-src'); }); item.description = article.html(); diff --git a/lib/routes/solidot/_article.ts b/lib/routes/solidot/_article.ts index 8f93f7f670..9354b6d5d7 100644 --- a/lib/routes/solidot/_article.ts +++ b/lib/routes/solidot/_article.ts @@ -5,9 +5,8 @@ import { parseDate } from '@/utils/parse-date'; import timezone from '@/utils/timezone'; export default async function get_article(url) { - const domain = 'https://www.solidot.org'; - if (/^\/.*$/.test(url)) { + const domain = 'https://www.solidot.org'; url = domain + url; } const response = await got({ diff --git a/lib/routes/techpowerup/utils.ts b/lib/routes/techpowerup/utils.ts index 249f44b72f..0b64b05c03 100644 --- a/lib/routes/techpowerup/utils.ts +++ b/lib/routes/techpowerup/utils.ts @@ -24,10 +24,12 @@ const fixImages = ($) => { const hdImage = (img) => { img.attribs.src = img.attribs.src.replace('_thm', '').replace('_small', ''); - if (img.parentNode.name === 'a' && img.parentNode.attribs['data-width'] && img.parentNode.attribs['data-height']) { - img.attribs.width = img.parentNode.attribs['data-width']; - img.attribs.height = img.parentNode.attribs['data-height']; + if (!(img.parentNode.name === 'a' && img.parentNode.attribs['data-width'] && img.parentNode.attribs['data-height'])) { + return; } + + img.attribs.width = img.parentNode.attribs['data-width']; + img.attribs.height = img.parentNode.attribs['data-height']; }; const removeFigureStyle = (f) => { delete f.attribs.style; diff --git a/lib/routes/telegram/channel-media.ts b/lib/routes/telegram/channel-media.ts index 91f028aaaa..469a475935 100644 --- a/lib/routes/telegram/channel-media.ts +++ b/lib/routes/telegram/channel-media.ts @@ -50,10 +50,7 @@ function ExpandInlineBytes(bytes: Buffer) { } function sortThumb(thumb: Api.TypePhotoSize) { - if (thumb instanceof Api.PhotoStrippedSize) { - return thumb.bytes.length; - } - if (thumb instanceof Api.PhotoCachedSize) { + if (thumb instanceof Api.PhotoStrippedSize || thumb instanceof Api.PhotoCachedSize) { return thumb.bytes.length; } if (thumb instanceof Api.PhotoSize) { diff --git a/lib/routes/telegram/channel.ts b/lib/routes/telegram/channel.ts index 555b083829..b86d499173 100644 --- a/lib/routes/telegram/channel.ts +++ b/lib/routes/telegram/channel.ts @@ -507,10 +507,12 @@ async function handler(ctx) { } tag_media += backgroundUrlSrc ? `` : ''; } - if (tag_media) { - tag_media_all += tag_media; - $node.find('.message_media_not_supported').remove(); + if (!tag_media) { + return; } + + tag_media_all += tag_media; + $node.find('.message_media_not_supported').remove(); }); return tag_media_all; }; @@ -622,16 +624,18 @@ async function handler(ctx) { attachmentTitle += _attachmentTitle; attachmentHtml += _attachmentHtml ? `
        ${_attachmentHtml}
        ` : ''; const wrapNext = $wrap.next('.tgme_widget_message_text'); - if (wrapNext.length) { - const captionHtml = wrapNext.html(); - if (captionHtml!.length) { - attachmentHtml += `

        ${captionHtml}

        `; - } - // remove them, avoid being duplicated - wrapNext.each((_, caption) => { - $(caption).remove(); - }); + if (!wrapNext.length) { + return; } + + const captionHtml = wrapNext.html(); + if (captionHtml!.length) { + attachmentHtml += `

        ${captionHtml}

        `; + } + // remove them, avoid being duplicated + wrapNext.each((_, caption) => { + $(caption).remove(); + }); }); } diff --git a/lib/routes/telegram/tglib/channel.ts b/lib/routes/telegram/tglib/channel.ts index 72b832a3cc..e2efab6c7b 100644 --- a/lib/routes/telegram/tglib/channel.ts +++ b/lib/routes/telegram/tglib/channel.ts @@ -188,23 +188,24 @@ export default async function handler(ctx: Context) { } } } - if (text !== '' || ++i === messages.length - 1) { - let description = attachments.join('
        \n'); - attachments = []; // emitting these, buffer other ones - - if (text) { - description += `

        ${HTMLParser.unparse(message.message, message.entities).replaceAll('\n', '
        ')}

        `; - } - - const title = message.text ? message.text.slice(0, 80) + (message.text.length > 80 ? '...' : '') : new Date(message.date * 1000).toUTCString(); - item.push({ - title, - description, - pubDate: new Date(message.date * 1000).toUTCString(), - link: `https://t.me/s/${username}/${message.id}`, - author: getDisplayName(message.sender ?? entity), - }); + if (text === '' && ++i !== messages.length - 1) { + continue; } + let description = attachments.join('
        \n'); + attachments = []; // emitting these, buffer other ones + + if (text) { + description += `

        ${HTMLParser.unparse(message.message, message.entities).replaceAll('\n', '
        ')}

        `; + } + + const title = message.text ? message.text.slice(0, 80) + (message.text.length > 80 ? '...' : '') : new Date(message.date * 1000).toUTCString(); + item.push({ + title, + description, + pubDate: new Date(message.date * 1000).toUTCString(), + link: `https://t.me/s/${username}/${message.id}`, + author: getDisplayName(message.sender ?? entity), + }); } return { diff --git a/lib/routes/temposmart/utils.ts b/lib/routes/temposmart/utils.ts index 3dda604c46..8324f29a15 100644 --- a/lib/routes/temposmart/utils.ts +++ b/lib/routes/temposmart/utils.ts @@ -72,11 +72,8 @@ export const parseJpy = (text: string | null): number | null => { if (/無償|なし|無し/.test(s)) { return 0; } - if (isUnknown(s)) { - return null; - } // Without 円 / 万 only a bare number is accepted ('3ヶ月' is not an amount). - if (!/[円万億]/.test(s) && !/^\d+(?:\.\d+)?$/.test(s)) { + if (isUnknown(s) || (!/[円万億]/.test(s) && !/^\d+(?:\.\d+)?$/.test(s))) { return null; } const oku = s.match(/^(\d+(?:\.\d+)?)億(?:(\d+(?:\.\d+)?)万)?/); diff --git a/lib/routes/the/index.ts b/lib/routes/the/index.ts index 5b06a0fe33..9a0afe84f1 100644 --- a/lib/routes/the/index.ts +++ b/lib/routes/the/index.ts @@ -82,10 +82,12 @@ function findArticleLink($: CheerioAPI, block: Cheerio): string | undef const hasTitle = $el.find('h3').length > 0; const isMainImage = $el.hasClass('u-block') && $el.find('.graf-image').length > 0; - if (hasTitle || isMainImage) { - link = href; - return false; + if (!(hasTitle || isMainImage)) { + return; } + + link = href; + return false; }); return link; diff --git a/lib/routes/theinitium/utils.ts b/lib/routes/theinitium/utils.ts index bda270564e..55be81238c 100644 --- a/lib/routes/theinitium/utils.ts +++ b/lib/routes/theinitium/utils.ts @@ -96,11 +96,8 @@ async function scrapeFullArticle(url: string, cookie: string): Promise 0) { + if (article.length === 0 || article.find('.gh-post-upgrade-cta').length > 0) { return null; } return article.html(); diff --git a/lib/routes/treasury/press-releases.ts b/lib/routes/treasury/press-releases.ts index 8743227d68..a7aba423ac 100644 --- a/lib/routes/treasury/press-releases.ts +++ b/lib/routes/treasury/press-releases.ts @@ -31,8 +31,8 @@ async function handler(ctx: Context) { const $ = load(response); const list = $('.featured-stories__headline a') - .toArray() .slice(0, 10) + .toArray() .map((item): DataItem => { const $item = $(item); return { diff --git a/lib/routes/twitter/api/developer-api/api.ts b/lib/routes/twitter/api/developer-api/api.ts index 61d49020f1..93c1a7c788 100644 --- a/lib/routes/twitter/api/developer-api/api.ts +++ b/lib/routes/twitter/api/developer-api/api.ts @@ -81,10 +81,7 @@ const appClients: ClientWrapper[] = []; let index = -1; const init = () => { - if (appClients.length) { - return; - } - if (!config.twitter.consumerKey || !config.twitter.consumerSecret) { + if (appClients.length || !config.twitter.consumerKey || !config.twitter.consumerSecret) { return; } diff --git a/lib/routes/twitter/api/mobile-api/api.ts b/lib/routes/twitter/api/mobile-api/api.ts index 1e569d175f..6e60ab4a7f 100644 --- a/lib/routes/twitter/api/mobile-api/api.ts +++ b/lib/routes/twitter/api/mobile-api/api.ts @@ -134,13 +134,14 @@ function gatherLegacyFromData(entries, filterNested?, userId?) { const filteredEntries: any[] = []; for (const entry of entries) { const entryId = entry.entryId; - if (entryId) { - if (entryId.startsWith('tweet-')) { - filteredEntries.push(entry); - } - if (filterNested && filterNested.some((f) => entryId.startsWith(f))) { - filteredEntries.push(...entry.content.items); - } + if (!entryId) { + continue; + } + if (entryId.startsWith('tweet-')) { + filteredEntries.push(entry); + } + if (filterNested && filterNested.some((f) => entryId.startsWith(f))) { + filteredEntries.push(...entry.content.items); } } for (const entry of filteredEntries) { @@ -153,37 +154,40 @@ function gatherLegacyFromData(entries, filterNested?, userId?) { if (tweet && tweet.tweet) { tweet = tweet.tweet; } - if (tweet) { - const retweet = tweet.legacy?.retweeted_status_result?.result; - for (const t of [tweet, retweet]) { - if (!t?.legacy) { - continue; - } - t.legacy.user = t.core?.user_result?.result?.legacy || t.core?.user_results?.result?.legacy; - t.legacy.id_str = t.rest_id; // avoid falling back to conversation_id_str elsewhere - const quote = t.quoted_status_result?.result; - if (quote) { - t.legacy.quoted_status = quote.legacy; - t.legacy.quoted_status.user = quote.core.user_result?.result?.legacy || quote.core.user_results?.result?.legacy; - } - if (t.note_tweet) { - const tmp = t.note_tweet.note_tweet_results.result; - t.legacy.entities.hashtags = tmp.entity_set.hashtags; - t.legacy.entities.symbols = tmp.entity_set.symbols; - t.legacy.entities.urls = tmp.entity_set.urls; - t.legacy.entities.user_mentions = tmp.entity_set.user_mentions; - t.legacy.full_text = tmp.text; - } + if (!tweet) { + continue; + } + const retweet = tweet.legacy?.retweeted_status_result?.result; + for (const t of [tweet, retweet]) { + if (!t?.legacy) { + continue; } - const legacy = tweet.legacy; - if (legacy) { - if (retweet) { - legacy.retweeted_status = retweet.legacy; - } - if (userId === undefined || legacy.user_id_str === userId + '') { - tweets.push(legacy); - } + t.legacy.user = t.core?.user_result?.result?.legacy || t.core?.user_results?.result?.legacy; + t.legacy.id_str = t.rest_id; // avoid falling back to conversation_id_str elsewhere + const quote = t.quoted_status_result?.result; + if (quote) { + t.legacy.quoted_status = quote.legacy; + t.legacy.quoted_status.user = quote.core.user_result?.result?.legacy || quote.core.user_results?.result?.legacy; } + if (!t.note_tweet) { + continue; + } + const tmp = t.note_tweet.note_tweet_results.result; + t.legacy.entities.hashtags = tmp.entity_set.hashtags; + t.legacy.entities.symbols = tmp.entity_set.symbols; + t.legacy.entities.urls = tmp.entity_set.urls; + t.legacy.entities.user_mentions = tmp.entity_set.user_mentions; + t.legacy.full_text = tmp.text; + } + const legacy = tweet.legacy; + if (!legacy) { + continue; + } + if (retweet) { + legacy.retweeted_status = retweet.legacy; + } + if (userId === undefined || legacy.user_id_str === userId + '') { + tweets.push(legacy); } } return tweets; diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts index bb51941788..da484cdf4c 100644 --- a/lib/routes/twitter/api/web-api/utils.ts +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -313,13 +313,14 @@ export function gatherLegacyFromData(entries: any[], filterNested?: string[], us const filteredEntries: any[] = []; for (const entry of entries) { const entryId = entry.entryId; - if (entryId) { - if (entryId.startsWith('tweet-') || entryId.startsWith('profile-grid-0-tweet-')) { - filteredEntries.push(entry); - } - if (filterNested && filterNested.some((f) => entryId.startsWith(f))) { - filteredEntries.push(...entry.content.items); - } + if (!entryId) { + continue; + } + if (entryId.startsWith('tweet-') || entryId.startsWith('profile-grid-0-tweet-')) { + filteredEntries.push(entry); + } + if (filterNested && filterNested.some((f) => entryId.startsWith(f))) { + filteredEntries.push(...entry.content.items); } } for (const entry of filteredEntries) { @@ -354,37 +355,40 @@ export function gatherLegacyFromData(entries: any[], filterNested?: string[], us if (tweet && tweet.tweet) { tweet = tweet.tweet; } - if (tweet) { - const retweet = tweet.legacy?.retweeted_status_result?.result; - for (const t of [tweet, retweet]) { - if (!t?.legacy) { - continue; - } - hydrateLegacyUser(t.legacy, t); - t.legacy.id_str = t.rest_id; // avoid falling back to conversation_id_str elsewhere - const quote = t.quoted_status_result?.result?.tweet || t.quoted_status_result?.result; - if (quote?.legacy) { - t.legacy.quoted_status = quote.legacy; - hydrateLegacyUser(t.legacy.quoted_status, quote); - } - if (t.note_tweet) { - const tmp = t.note_tweet.note_tweet_results.result; - t.legacy.entities.hashtags = tmp.entity_set.hashtags; - t.legacy.entities.symbols = tmp.entity_set.symbols; - t.legacy.entities.urls = tmp.entity_set.urls; - t.legacy.entities.user_mentions = tmp.entity_set.user_mentions; - t.legacy.full_text = tmp.text; - } + if (!tweet) { + continue; + } + const retweet = tweet.legacy?.retweeted_status_result?.result; + for (const t of [tweet, retweet]) { + if (!t?.legacy) { + continue; } - const legacy = tweet.legacy; - if (legacy) { - if (retweet) { - legacy.retweeted_status = retweet.legacy; - } - if (userId === undefined || legacy.user_id_str === userId + '') { - tweets.push(legacy); - } + hydrateLegacyUser(t.legacy, t); + t.legacy.id_str = t.rest_id; // avoid falling back to conversation_id_str elsewhere + const quote = t.quoted_status_result?.result?.tweet || t.quoted_status_result?.result; + if (quote?.legacy) { + t.legacy.quoted_status = quote.legacy; + hydrateLegacyUser(t.legacy.quoted_status, quote); } + if (!t.note_tweet) { + continue; + } + const tmp = t.note_tweet.note_tweet_results.result; + t.legacy.entities.hashtags = tmp.entity_set.hashtags; + t.legacy.entities.symbols = tmp.entity_set.symbols; + t.legacy.entities.urls = tmp.entity_set.urls; + t.legacy.entities.user_mentions = tmp.entity_set.user_mentions; + t.legacy.full_text = tmp.text; + } + const legacy = tweet.legacy; + if (!legacy) { + continue; + } + if (retweet) { + legacy.retweeted_status = retweet.legacy; + } + if (userId === undefined || legacy.user_id_str === userId + '') { + tweets.push(legacy); } } diff --git a/lib/routes/twitter/utils.ts b/lib/routes/twitter/utils.ts index e593176d92..a660d7ae4c 100644 --- a/lib/routes/twitter/utils.ts +++ b/lib/routes/twitter/utils.ts @@ -14,10 +14,7 @@ const getOriginalImg = (url) => { } if ((m = url.match(/^(https?:\/\/\w+\.twimg\.com\/[^?]+)(\?.+)$/i))) { const pars = getQueryParams(url); - if (!pars.format || !pars.name) { - return url; - } - if (pars.name === 'orig') { + if (!pars.format || !pars.name || pars.name === 'orig') { return url; } return m[1] + '?format=' + pars.format + '&name=orig'; @@ -186,10 +183,11 @@ const ProcessFeed = (ctx, { data = [] }: { data?: any[] }, params: ProcessFeedPa img += content; - if (mediaNumber) { - img += `

        ${index}/${mediaCount}

        `; - index++; + if (!mediaNumber) { + continue; } + img += `

        ${index}/${mediaCount}

        `; + index++; } } diff --git a/lib/routes/weibo/utils.ts b/lib/routes/weibo/utils.ts index 67ee0bdc8b..438e230e42 100644 --- a/lib/routes/weibo/utils.ts +++ b/lib/routes/weibo/utils.ts @@ -612,13 +612,14 @@ const weiboUtils = { if (matches) { for (const match of matches) { const hrefMatch = match.match(/href="https:\/\/weibo\.cn\/sinaurl\?u=([^"]+)"/); - if (hrefMatch) { - // 获取并解码 href 中的图片 URL - const imgSrc = decodeURIComponent(hrefMatch[1]); - const imgTag = ``; - // 用替换后的 img 标签替换原来的 标签部分 - replyText = replyText.replaceAll(match, () => imgTag); + if (!hrefMatch) { + continue; } + // 获取并解码 href 中的图片 URL + const imgSrc = decodeURIComponent(hrefMatch[1]); + const imgTag = ``; + // 用替换后的 img 标签替换原来的 标签部分 + replyText = replyText.replaceAll(match, () => imgTag); } } replyText = formatDescriptionText(replyText, descriptionRenderParams); diff --git a/lib/routes/wenxuecity/bbs.ts b/lib/routes/wenxuecity/bbs.ts index c8164781ac..7f2b740981 100644 --- a/lib/routes/wenxuecity/bbs.ts +++ b/lib/routes/wenxuecity/bbs.ts @@ -33,8 +33,8 @@ async function handler(ctx: Context) { const response = await ofetch(baseUrl); const $ = load(response); const list = $('div.odd,div.even') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/wenxuecity/hot.ts b/lib/routes/wenxuecity/hot.ts index d239bf114d..291e4281ca 100644 --- a/lib/routes/wenxuecity/hot.ts +++ b/lib/routes/wenxuecity/hot.ts @@ -23,8 +23,8 @@ async function handler(ctx: Context) { const $ = load(response); const list = $('div.item') - .toArray() .slice(0, 10) + .toArray() .map((item) => { const $item = $(item); return { diff --git a/lib/routes/wenxuecity/news.ts b/lib/routes/wenxuecity/news.ts index e9f77f228d..aa578f7b5e 100644 --- a/lib/routes/wenxuecity/news.ts +++ b/lib/routes/wenxuecity/news.ts @@ -22,8 +22,8 @@ async function handler() { const $ = load(response); const list = $('div.mainwrap div.block div.wrapper ul li a') - .toArray() .slice(0, 15) + .toArray() .map((item): DataItem => { const $item = $(item); return { diff --git a/lib/routes/whu/cs.ts b/lib/routes/whu/cs.ts index 228f474c28..c592e9ad08 100644 --- a/lib/routes/whu/cs.ts +++ b/lib/routes/whu/cs.ts @@ -93,12 +93,14 @@ async function handler(ctx) { content.find('img').each((_, e) => { const $e = $(e); - if ($e.attr('orisrc')) { - const newUrl = new URL($e.attr('orisrc')!, 'https://cs.whu.edu.cn'); - $e.attr('src', newUrl.href); - $e.removeAttr('orisrc'); - $e.removeAttr('vurl'); + if (!$e.attr('orisrc')) { + return; } + + const newUrl = new URL($e.attr('orisrc')!, 'https://cs.whu.edu.cn'); + $e.attr('src', newUrl.href); + $e.removeAttr('orisrc'); + $e.removeAttr('vurl'); }); item.description = content.html(); diff --git a/lib/routes/wikipedia/current-events.ts b/lib/routes/wikipedia/current-events.ts index 2a88ecf1ef..511f4b61d7 100644 --- a/lib/routes/wikipedia/current-events.ts +++ b/lib/routes/wikipedia/current-events.ts @@ -297,16 +297,17 @@ async function fetchMultipleWikiContent(pageNames: string[]): Promise 0) { - const stream = streams[0]; - if (stream.masterUrl) { - videoUrls.push(stream.masterUrl); - } - if (stream.backupUrls?.length) { - videoUrls.push(...stream.backupUrls); - } + if (!streams?.length) { + continue; + } + const stream = streams[0]; + if (stream.masterUrl) { + videoUrls.push(stream.masterUrl); + } + if (stream.backupUrls?.length) { + videoUrls.push(...stream.backupUrls); } } @@ -264,13 +265,14 @@ async function getFullNote(link, displayLivePhoto) { const streamTypes = ['av1', 'h264', 'h265', 'h266']; for (const type of streamTypes) { const streams = image.stream?.[type]; - if (streams?.length > 0) { - if (streams[0].masterUrl) { - videoUrls.push(streams[0].masterUrl); - } - if (streams[0].backupUrls?.length) { - videoUrls.push(...streams[0].backupUrls); - } + if (!streams?.length) { + continue; + } + if (streams[0].masterUrl) { + videoUrls.push(streams[0].masterUrl); + } + if (streams[0].backupUrls?.length) { + videoUrls.push(...streams[0].backupUrls); } } diff --git a/lib/routes/xjtu/zs.ts b/lib/routes/xjtu/zs.ts index f352bda59d..550f2cf76d 100644 --- a/lib/routes/xjtu/zs.ts +++ b/lib/routes/xjtu/zs.ts @@ -63,7 +63,7 @@ export const handler = async (ctx: Context): Promise => { const pubDateStr: string | undefined = $$('div.show01 i') .text() ?.match(/(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})/)?.[1]; - const categoryEls: Element[] = $$('div.mianbao a').toArray().slice(1); + const categoryEls: Element[] = $$('div.mianbao a').slice(1).toArray(); const categories: string[] = [...new Set(categoryEls.map((el) => $$(el).text()).filter(Boolean))]; const upDatedStr: string | undefined = pubDateStr; diff --git a/lib/routes/yahoo/author.ts b/lib/routes/yahoo/author.ts index 2810d26915..bae80f31cb 100644 --- a/lib/routes/yahoo/author.ts +++ b/lib/routes/yahoo/author.ts @@ -52,10 +52,12 @@ async function handler(ctx: Context) { content('div.story-cover img, div.content-body img').each((_, img) => { const src = content(img).attr('src'); - if (src?.startsWith('https://s.yimg.com/lo/mysterio/')) { - content(img).attr('src', decodeURIComponent(src.split('/').at(-1)!)); - content(img).siblings('source').remove(); + if (!src?.startsWith('https://s.yimg.com/lo/mysterio/')) { + return; } + + content(img).attr('src', decodeURIComponent(src.split('/').at(-1)!)); + content(img).siblings('source').remove(); }); return { diff --git a/lib/routes/yahoo/news/utils.tsx b/lib/routes/yahoo/news/utils.tsx index ac5ab22709..5c2de378c7 100644 --- a/lib/routes/yahoo/news/utils.tsx +++ b/lib/routes/yahoo/news/utils.tsx @@ -164,34 +164,38 @@ const parseItem = (item) => const $ele = $(ele); let dataSrc = $ele.attr('data-src'); - if (dataSrc) { - const match = dataSrc.match(/.*--\/.*--\/(.*)/); - if (match?.[1]) { - dataSrc = match?.[1]; - } - $ele.attr('src', dataSrc); - $ele.removeAttr('data-src'); + if (!dataSrc) { + return; } + + const match = dataSrc.match(/.*--\/.*--\/(.*)/); + if (match?.[1]) { + dataSrc = match?.[1]; + } + $ele.attr('src', dataSrc); + $ele.removeAttr('data-src'); }); // fix blockquote iframe body.find('.caas-iframe').each((_, ele) => { const $ele = $(ele); - if ($ele.data('type') === 'youtube') { - const blockquoteSrc = $ele.find('blockquote').attr('data-src')!; - $ele.replaceWith( - renderToString( - - ) - ); + if ($ele.data('type') !== 'youtube') { + return; } + + const blockquoteSrc = $ele.find('blockquote').attr('data-src')!; + $ele.replaceWith( + renderToString( + + ) + ); }); item.description = body diff --git a/lib/routes/yamibo/utils.ts b/lib/routes/yamibo/utils.ts index ba54ceacc9..31362018a4 100644 --- a/lib/routes/yamibo/utils.ts +++ b/lib/routes/yamibo/utils.ts @@ -95,16 +95,18 @@ export class ThreadFetcher { } catch { // Article failures have already been reported to their callers. } - if (this.browser) { - let browser: BrowserPage; - try { - browser = await this.browser; - } catch { - // openBrowser cleans up failed initialization before rejecting. - return; - } - await browser.destroy(); + if (!this.browser) { + return; } + + let browser: BrowserPage; + try { + browser = await this.browser; + } catch { + // openBrowser cleans up failed initialization before rejecting. + return; + } + await browser.destroy(); } } diff --git a/lib/routes/youtube/utils.tsx b/lib/routes/youtube/utils.tsx index 6b026a5532..1547d209f2 100644 --- a/lib/routes/youtube/utils.tsx +++ b/lib/routes/youtube/utils.tsx @@ -138,16 +138,9 @@ export const getVideoUrl = (id: string) => `https://www.youtube-nocookie.com/emb // Get the appropriate playlist ID with or without shorts export const getPlaylistWithShortsFilter = (id: string, filterShorts = true): string => { - // If filtering shorts is enabled - if (filterShorts) { - if (id.startsWith('UC')) { - // For channel IDs (UC...), convert to playlist format without shorts (UULF...) - return 'UULF' + id.slice(2); - } - if (id.startsWith('UU')) { - // For playlist IDs (UU...), convert to playlist format without shorts (UULF...) - return 'UULF' + id.slice(2); - } + // If filtering shorts is enabled, convert channel IDs (UC...) and playlist IDs (UU...) to playlist format without shorts (UULF...) + if (filterShorts && (id.startsWith('UC') || id.startsWith('UU'))) { + return 'UULF' + id.slice(2); } // If filterShorts is false or the ID format doesn't match known patterns, return original ID return id; diff --git a/lib/routes/yuque/book.ts b/lib/routes/yuque/book.ts index 49db19a621..8708460dd6 100644 --- a/lib/routes/yuque/book.ts +++ b/lib/routes/yuque/book.ts @@ -99,15 +99,16 @@ async function handler(ctx) { for await (const v of $('video').toArray()) { const $v = $(v); const src = $v.attr('src'); - if (src!.startsWith('inputs')) { - const { data } = await got(`${baseUrl}/api/video`, { - searchParams: { - video_id: src, - }, - }); - const { info } = data.data; - $v.replaceWith(``); + if (!src!.startsWith('inputs')) { + continue; } + const { data } = await got(`${baseUrl}/api/video`, { + searchParams: { + video_id: src, + }, + }); + const { info } = data.data; + $v.replaceWith(``); } item.description = $.html(); diff --git a/lib/routes/zhihu/execlib/x-zse-96-v3.ts b/lib/routes/zhihu/execlib/x-zse-96-v3.ts index fe2c48e559..359845d837 100644 --- a/lib/routes/zhihu/execlib/x-zse-96-v3.ts +++ b/lib/routes/zhihu/execlib/x-zse-96-v3.ts @@ -115,10 +115,11 @@ export const encrypt = (md5Str) => { current |= e; - if (i_mod_3 === 2) { - resultStr += encode(current); - current = 0; + if (i_mod_3 !== 2) { + continue; } + resultStr += encode(current); + current = 0; } return resultStr; }; diff --git a/lib/routes/zhihu/utils.ts b/lib/routes/zhihu/utils.ts index 7110741c25..7088bdcdd4 100644 --- a/lib/routes/zhihu/utils.ts +++ b/lib/routes/zhihu/utils.ts @@ -25,14 +25,16 @@ export const processImage = (content: string) => { $('a').each((_, elem) => { const href = $(elem).attr('href'); - if (href?.startsWith('http://link.zhihu.com/?target=') || href?.startsWith('https://link.zhihu.com/?target=')) { - const url = new URL(href); - const target = url.searchParams.get('target') || ''; - try { - $(elem).attr('href', decodeURIComponent(target)); - } catch { - // sometimes the target is not a valid url - } + if (!href?.startsWith('http://link.zhihu.com/?target=') && !href?.startsWith('https://link.zhihu.com/?target=')) { + return; + } + + const url = new URL(href); + const target = url.searchParams.get('target') || ''; + try { + $(elem).attr('href', decodeURIComponent(target)); + } catch { + // sometimes the target is not a valid url } }); diff --git a/lib/routes/zhishifenzi/innovation.ts b/lib/routes/zhishifenzi/innovation.ts index 698dc4d37f..8b514fabf0 100644 --- a/lib/routes/zhishifenzi/innovation.ts +++ b/lib/routes/zhishifenzi/innovation.ts @@ -39,8 +39,8 @@ async function handler(ctx: Context) { const title = navTitle === '' ? '全部創新' : `創新「${navTitle}」`; const list: DataItem[] = $('div.inner_news_list > ul > li.clearfix') - .toArray() .slice(0, 4) + .toArray() .map((elem) => { const $elem = $(elem); return { diff --git a/lib/routes/zzu/dzb.ts b/lib/routes/zzu/dzb.ts index 34ea91a0b4..5fd251bafa 100644 --- a/lib/routes/zzu/dzb.ts +++ b/lib/routes/zzu/dzb.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.new_list3 dd') - .toArray() .slice(0, 20) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a'); diff --git a/lib/routes/zzu/gs.ts b/lib/routes/zzu/gs.ts index 6f4ecaa495..10d6b8bf1a 100644 --- a/lib/routes/zzu/gs.ts +++ b/lib/routes/zzu/gs.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.r_list ul li') - .toArray() .slice(0, 20) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a').first(); diff --git a/lib/routes/zzu/jwc.ts b/lib/routes/zzu/jwc.ts index 99e74a9ab1..2d696e7d0a 100644 --- a/lib/routes/zzu/jwc.ts +++ b/lib/routes/zzu/jwc.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('ul.list li') - .toArray() .slice(0, 15) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a.tit').first(); diff --git a/lib/routes/zzu/kjc.ts b/lib/routes/zzu/kjc.ts index 4f51a193b2..f38c3b6a77 100644 --- a/lib/routes/zzu/kjc.ts +++ b/lib/routes/zzu/kjc.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.list_guild') - .toArray() .slice(0, 14) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a'); diff --git a/lib/routes/zzu/math.ts b/lib/routes/zzu/math.ts index c5eb55e0de..242ce2a57e 100644 --- a/lib/routes/zzu/math.ts +++ b/lib/routes/zzu/math.ts @@ -44,8 +44,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.text-list ul li') - .toArray() .slice(0, 16) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a'); diff --git a/lib/routes/zzu/news.ts b/lib/routes/zzu/news.ts index 1d6ba0284b..84ba8fe310 100644 --- a/lib/routes/zzu/news.ts +++ b/lib/routes/zzu/news.ts @@ -48,8 +48,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.new-item') - .toArray() .slice(0, 15) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('h3 a'); diff --git a/lib/routes/zzu/rsc.ts b/lib/routes/zzu/rsc.ts index c55804f095..611bb735ad 100644 --- a/lib/routes/zzu/rsc.ts +++ b/lib/routes/zzu/rsc.ts @@ -46,8 +46,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.list_guild') - .toArray() .slice(0, 14) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a'); diff --git a/lib/routes/zzu/ss.ts b/lib/routes/zzu/ss.ts index 6eaa7fd500..fa5b62a052 100644 --- a/lib/routes/zzu/ss.ts +++ b/lib/routes/zzu/ss.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.list_notice > a') - .toArray() .slice(0, 10) + .toArray() .map((element) => { const $element = $(element); const link = new URL($element.attr('href')!, typeDict[type][1]).href; diff --git a/lib/routes/zzu/student.ts b/lib/routes/zzu/student.ts index f79dbf283c..27df996256 100644 --- a/lib/routes/zzu/student.ts +++ b/lib/routes/zzu/student.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.part-list ul li') - .toArray() .slice(0, 10) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a').first(); diff --git a/lib/routes/zzu/sxy.ts b/lib/routes/zzu/sxy.ts index e8c5886a9f..df5f65d74c 100644 --- a/lib/routes/zzu/sxy.ts +++ b/lib/routes/zzu/sxy.ts @@ -55,8 +55,8 @@ async function handler(ctx) { function parseXyxwList($, typeDict, type) { return $('section.n_titu ul li') - .toArray() .slice(0, 6) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a'); @@ -79,8 +79,8 @@ function parseXyxwList($, typeDict, type) { function parseOtherList($, typeDict, type) { return $('.n_notice ul.ul li') - .toArray() .slice(0, 16) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a'); diff --git a/lib/routes/zzu/tzhb.ts b/lib/routes/zzu/tzhb.ts index 66a9237201..1668877759 100644 --- a/lib/routes/zzu/tzhb.ts +++ b/lib/routes/zzu/tzhb.ts @@ -42,8 +42,8 @@ async function handler(ctx) { // 解析页面内容并提取文章信息 const list = $('.main_conR li') - .toArray() .slice(0, 15) + .toArray() .map((element) => { const $element = $(element); const $link = $element.find('a').first(); diff --git a/lib/utils/cache/http.test.ts b/lib/utils/cache/http.test.ts index d96d01df51..b1bfd37dac 100644 --- a/lib/utils/cache/http.test.ts +++ b/lib/utils/cache/http.test.ts @@ -48,10 +48,7 @@ describe('http cache module', () => { url: input.toString(), }); - if (init?.method === 'PUT') { - return new Response(null, { status: 204 }); - } - if (init?.method === 'HEAD') { + if (init?.method === 'PUT' || init?.method === 'HEAD') { return new Response(null, { status: 204 }); } diff --git a/lib/utils/cache/kv.ts b/lib/utils/cache/kv.ts index 3e77685173..8b0bd801e3 100644 --- a/lib/utils/cache/kv.ts +++ b/lib/utils/cache/kv.ts @@ -57,16 +57,18 @@ export default { return; } const stored = stringify(value); - if (key) { - const promises: Array> = [kvNamespace.put(key, stored, { expirationTtl: maxAge })]; - - if (maxAge !== config.cache.contentExpire) { - // Store the cache ttl if it is not the default value - promises.push(kvNamespace.put(getCacheTtlKey(key), String(maxAge), { expirationTtl: maxAge })); - } - - await Promise.all(promises); + if (!key) { + return; } + + const promises: Array> = [kvNamespace.put(key, stored, { expirationTtl: maxAge })]; + + if (maxAge !== config.cache.contentExpire) { + // Store the cache ttl if it is not the default value + promises.push(kvNamespace.put(getCacheTtlKey(key), String(maxAge), { expirationTtl: maxAge })); + } + + await Promise.all(promises); }, clients: {}, status, diff --git a/lib/utils/cache/redis.ts b/lib/utils/cache/redis.ts index 9ae79c6077..2aec26661c 100644 --- a/lib/utils/cache/redis.ts +++ b/lib/utils/cache/redis.ts @@ -64,13 +64,15 @@ export default { return; } const stored = stringify(value); - if (key) { - if (maxAge !== config.cache.contentExpire) { - // intentionally store the cache ttl if it is not the default value - clients.redisClient.set(getCacheTtlKey(key), maxAge, 'EX', maxAge); - } - return clients.redisClient.set(key, stored, 'EX', maxAge); // setMode: https://redis.io/commands/set + if (!key) { + return; } + + if (maxAge !== config.cache.contentExpire) { + // intentionally store the cache ttl if it is not the default value + clients.redisClient.set(getCacheTtlKey(key), maxAge, 'EX', maxAge); + } + return clients.redisClient.set(key, stored, 'EX', maxAge); // setMode: https://redis.io/commands/set }, clients, status, diff --git a/lib/utils/evaluate-script.ts b/lib/utils/evaluate-script.ts index fa950efcc9..0b187503ba 100644 --- a/lib/utils/evaluate-script.ts +++ b/lib/utils/evaluate-script.ts @@ -353,16 +353,18 @@ const readScriptData = async (source: string, target: string[], argumentIndex if (value instanceof ScriptDataError) { throw value; } - if (isObject(value)) { - if (ancestors.has(value)) { - throw new ScriptDataError('Cyclic script data is not supported'); - } - ancestors.add(value); - for (const child of Object.values(value)) { - validate(child, ancestors, depth + 1); - } - ancestors.delete(value); + if (!isObject(value)) { + return; } + + if (ancestors.has(value)) { + throw new ScriptDataError('Cyclic script data is not supported'); + } + ancestors.add(value); + for (const child of Object.values(value)) { + validate(child, ancestors, depth + 1); + } + ancestors.delete(value); }; if (source.length > maxScriptLength) { diff --git a/lib/utils/header-generator.ts b/lib/utils/header-generator.ts index 9a974ede69..b6e30c15f7 100644 --- a/lib/utils/header-generator.ts +++ b/lib/utils/header-generator.ts @@ -14,13 +14,17 @@ const isValidHeader = (headers: Record, browser: string): boolea browser = browser.toLowerCase(); const userAgent = headers['user-agent']; - if (browser === 'chrome') { - if (userAgent.includes('Chrome-Lighthouse') || userAgent.includes('Gener8') || userAgent.includes('HeadlessChrome') || userAgent.includes('SMTBot') || userAgent.includes('Electron') || userAgent.includes('Code')) { - return false; - } - if (!(headers['sec-ch-ua'] && headers['sec-ch-ua-mobile'] && headers['sec-ch-ua-platform'])) { - return false; - } + if ( + browser === 'chrome' && + (userAgent.includes('Chrome-Lighthouse') || + userAgent.includes('Gener8') || + userAgent.includes('HeadlessChrome') || + userAgent.includes('SMTBot') || + userAgent.includes('Electron') || + userAgent.includes('Code') || + !(headers['sec-ch-ua'] && headers['sec-ch-ua-mobile'] && headers['sec-ch-ua-platform'])) + ) { + return false; } return !(browser === 'safari' && userAgent.includes('Applebot')); diff --git a/lib/utils/parse-date.ts b/lib/utils/parse-date.ts index c77f931928..8d7981a381 100644 --- a/lib/utils/parse-date.ts +++ b/lib/utils/parse-date.ts @@ -181,11 +181,12 @@ const parseDuration = (str: string): plugin.Duration => { for (const { unit, regExp } of UNIT_PATTERNS) { const match = regExp.exec(cleanStr); - if (match) { - const val = Number(match[1]); - if (!Number.isNaN(val)) { - totalDuration = totalDuration.add(val, unit); - } + if (!match) { + continue; + } + const val = Number(match[1]); + if (!Number.isNaN(val)) { + totalDuration = totalDuration.add(val, unit); } } return totalDuration; diff --git a/lib/utils/proxy/multi-proxy.ts b/lib/utils/proxy/multi-proxy.ts index 35042abe77..48eb7f737a 100644 --- a/lib/utils/proxy/multi-proxy.ts +++ b/lib/utils/proxy/multi-proxy.ts @@ -93,35 +93,41 @@ const createMultiProxy = (proxyUris: string[], proxyObj: Config['proxy']): Multi const markProxyFailed = (proxyUri: string) => { const proxy = proxies.find((p) => p.uri === proxyUri); - if (proxy) { - proxy.failureCount++; - proxy.lastFailureTime = Date.now(); - if (proxy.failureCount >= maxFailures) { - proxy.isActive = false; - logger.warn(`Proxy ${proxyUri} marked as inactive after ${maxFailures} failures`); - } else { - logger.warn(`Proxy ${proxyUri} failed (${proxy.failureCount}/${maxFailures})`); - } + if (!proxy) { + return; + } - const activeProxies = proxies.filter((p) => p.isActive); - if (activeProxies.length > 0) { - currentProxyIndex = (currentProxyIndex + 1) % activeProxies.length; - const nextProxy = getNextProxy(); - if (nextProxy) { - logger.info(`Switching to proxy: ${nextProxy.uri}`); - } - } + proxy.failureCount++; + proxy.lastFailureTime = Date.now(); + if (proxy.failureCount >= maxFailures) { + proxy.isActive = false; + logger.warn(`Proxy ${proxyUri} marked as inactive after ${maxFailures} failures`); + } else { + logger.warn(`Proxy ${proxyUri} failed (${proxy.failureCount}/${maxFailures})`); + } + + const activeProxies = proxies.filter((p) => p.isActive); + if (activeProxies.length === 0) { + return; + } + + currentProxyIndex = (currentProxyIndex + 1) % activeProxies.length; + const nextProxy = getNextProxy(); + if (nextProxy) { + logger.info(`Switching to proxy: ${nextProxy.uri}`); } }; const resetProxy = (proxyUri: string) => { const proxy = proxies.find((p) => p.uri === proxyUri); - if (proxy) { - proxy.isActive = true; - proxy.failureCount = 0; - delete proxy.lastFailureTime; - logger.info(`Proxy ${proxyUri} manually reset`); + if (!proxy) { + return; } + + proxy.isActive = true; + proxy.failureCount = 0; + delete proxy.lastFailureTime; + logger.info(`Proxy ${proxyUri} manually reset`); }; const currentProxy = getNextProxy(); diff --git a/lib/utils/wechat-mp.ts b/lib/utils/wechat-mp.ts index e26ad11ef7..7f0fe04fee 100644 --- a/lib/utils/wechat-mp.ts +++ b/lib/utils/wechat-mp.ts @@ -356,20 +356,24 @@ const fixArticleContent = (html?: string | Cheerio, skipImg = false): s $('img[data-src]').each((_, img) => { const $img = $(img); const realSrc = $img.attr('data-src'); - if (realSrc) { - $img.attr('src', realSrc); - $img.removeAttr('data-src'); + if (!realSrc) { + return; } + + $img.attr('src', realSrc); + $img.removeAttr('data-src'); }); } // fix audio: https://mp.weixin.qq.com/s/FnjcMXZ1xdS-d6n-pUUyyw $('mpvoice[voice_encode_fileid]').each((_, voice) => { const $voice = $(voice); const voiceId = $voice.attr('voice_encode_fileid'); - if (voiceId) { - const title = $voice.attr('name') || 'Audio'; - $voice.replaceWith(genAudioTag(genAudioSrc(voiceId), title)); + if (!voiceId) { + return; } + + const title = $voice.attr('name') || 'Audio'; + $voice.replaceWith(genAudioTag(genAudioSrc(voiceId), title)); }); // fix iframe: https://mp.weixin.qq.com/s/FnjcMXZ1xdS-d6n-pUUyyw $('iframe.video_iframe[data-src]').each((_, iframe) => { @@ -380,18 +384,22 @@ const fixArticleContent = (html?: string | Cheerio, skipImg = false): s } const srcUrlObj = new URL(dataSrc); const vid = srcUrlObj.searchParams.get('vid'); - if (srcUrlObj.host === 'v.qq.com' && vid !== null) { - const newSrc = genVideoSrc(vid); - $iframe.attr('src', newSrc); - $iframe.removeAttr('data-src'); - const width = $iframe.attr('data-w'); - const ratio = $iframe.attr('data-ratio'); - if (width && ratio) { - const width_ = Math.min(Number.parseInt(width), 677); - $iframe.attr('width', width_.toString()); - $iframe.attr('height', (width_ / Number(ratio)).toString()); - } - } // else {} FIXME: https://mp.weixin.qq.com/s?__biz=Mzg5Mjk3MzE4OQ==&mid=2247549515&idx=2&sn=a608fca597f0589c1aebd6d0b82ff6e9 + if (srcUrlObj.host !== 'v.qq.com' || vid === null) { + // FIXME: https://mp.weixin.qq.com/s?__biz=Mzg5Mjk3MzE4OQ==&mid=2247549515&idx=2&sn=a608fca597f0589c1aebd6d0b82ff6e9 + return; + } + const newSrc = genVideoSrc(vid); + $iframe.attr('src', newSrc); + $iframe.removeAttr('data-src'); + const width = $iframe.attr('data-w'); + const ratio = $iframe.attr('data-ratio'); + if (!width || !ratio) { + return; + } + + const width_ = Math.min(Number.parseInt(width), 677); + $iframe.attr('width', width_.toString()); + $iframe.attr('height', (width_ / Number(ratio)).toString()); }); // fix section $('section').each((_, section) => { diff --git a/package.json b/package.json index b56a6a0271..17644074a0 100644 --- a/package.json +++ b/package.json @@ -180,7 +180,7 @@ "eslint-plugin-n": "18.3.0", "eslint-plugin-regexp": "3.3.0", "eslint-plugin-simple-import-sort": "14.0.0", - "eslint-plugin-unicorn": "74.0.0", + "eslint-plugin-unicorn": "75.0.0", "eslint-plugin-yml": "3.8.1", "fast-string-width": "3.0.2", "fs-extra": "11.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 27b9831ac3..a950f57f6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -390,8 +390,8 @@ importers: specifier: 14.0.0 version: 14.0.0(eslint@10.10.0(jiti@2.7.0)) eslint-plugin-unicorn: - specifier: 74.0.0 - version: 74.0.0(eslint@10.10.0(jiti@2.7.0)) + specifier: 75.0.0 + version: 75.0.0(eslint@10.10.0(jiti@2.7.0)) eslint-plugin-yml: specifier: 3.8.1 version: 3.8.1(eslint@10.10.0(jiti@2.7.0)) @@ -466,10 +466,10 @@ importers: version: 0.3.1 vite-tsconfig-paths: specifier: 7.0.0-alpha.3 - version: 7.0.0-alpha.3(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)) + version: 7.0.0-alpha.3(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)) vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)) wrangler: specifier: 4.131.2 version: 4.131.2(@cloudflare/workers-types@5.20260915.1)(@types/node@26.6.1)(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -1198,8 +1198,8 @@ packages: resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/css-tree@4.0.5': - resolution: {integrity: sha512-iPmijIAq4hlIJB86PYmY/fcZORHtjphSqICDbwuw32A/JmkhZQ/K/6TjHE03zqf3n5yABpVcbRAMG8Mi9ojy8g==} + '@eslint/css-tree@4.1.1': + resolution: {integrity: sha512-A+s89eP+yDAPkKjnIOfjlkGifg5J7GPn01nWx14UjBVWktfkxOU4975F9ZZ13xNxkGiblNcBaAqgKhnQrW6SWA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/js@10.0.1': @@ -3349,6 +3349,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-browser-mapping@2.11.25: + resolution: {integrity: sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==} + engines: {node: '>=6.0.0'} + hasBin: true + basic-ftp@5.3.1: resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} engines: {node: '>=10.0.0'} @@ -3396,6 +3401,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.29.0: + resolution: {integrity: sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -3406,8 +3416,8 @@ packages: resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} engines: {node: '>=6.14.2'} - builtin-modules@5.3.0: - resolution: {integrity: sha512-hMQUl2bUFG339QygPM97E+mc8OY1IAchORZxm4a/frcYwKzozMzRVDBwHW0NjOqGElLm2O37AVQE8ikxlZHrMQ==} + builtin-modules@5.4.0: + resolution: {integrity: sha512-JCWSCdun+4Ovd9BhM/Vtlmwb7oD6Wl4YiPRXXwhAuwlPhW1un/MKgXn7GZoFm53ginnoNzus69V8JWx0K393jg==} engines: {node: '>=18.20'} byte-counter@0.1.0: @@ -3556,10 +3566,6 @@ packages: resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} engines: {node: '>=18'} - convert-hrtime@5.0.0: - resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} - engines: {node: '>=12'} - convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -3789,6 +3795,9 @@ packages: electron-to-chromium@1.5.416: resolution: {integrity: sha512-K6bvB2BjnNrugtIih6ewlbBI9DXa976jIdiIlRLHhBoEI9a4JaQjjHyF+A1IQI543aQYR4LnmOrT/K5fZj0aPA==} + electron-to-chromium@1.5.431: + resolution: {integrity: sha512-AAVihz2YwJeOdAynX8MUtqpvjY0gaiARp/7+r4kwqgzqXMrfG1qDN7vwT80uxAoOQRPcZH8t73EI+CA/1OJN8A==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -3937,8 +3946,8 @@ packages: peerDependencies: eslint: '>=5.0.0' - eslint-plugin-unicorn@74.0.0: - resolution: {integrity: sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==} + eslint-plugin-unicorn@75.0.0: + resolution: {integrity: sha512-72I7eSn+/z5CpgValFBl9mp2JE5UPD+nUUyB/VIGUMF1rCP1i37mA05zfIAVIU312A+qCZ38T8tSZr3oaMv4Mw==} engines: {node: '>=22'} peerDependencies: eslint: '>=10.4' @@ -4135,10 +4144,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-timeout@1.0.2: - resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} - engines: {node: '>=18'} - gaxios@7.3.1: resolution: {integrity: sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==} engines: {node: '>=18'} @@ -4445,10 +4450,6 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-identifier@1.1.0: - resolution: {integrity: sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==} - engines: {node: '>=18'} - is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -4757,10 +4758,6 @@ packages: magicast@0.5.4: resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} - make-asynchronous@1.1.0: - resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} - engines: {node: '>=18'} - make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -4819,8 +4816,8 @@ packages: mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - mdn-data@2.29.0: - resolution: {integrity: sha512-pVxQFCcaYUEAH853+v7yoI/qzhxXSq1bTb9obMYGYAN1c3Hen+XDCEvr296XhstrwlSTNgOR7mCSD4JPjbJe5A==} + mdn-data@2.35.0: + resolution: {integrity: sha512-k+1+dEIm2z/BEfdvYzT/fIyAGeDBo/1AJNJI4ilFXJRYoxP/3Ds+GP8shAOIq8jYXY9N5nGB3Ag104NsagmLAA==} mdurl@2.1.0: resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==} @@ -5057,6 +5054,10 @@ packages: resolution: {integrity: sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==} engines: {node: '>=18'} + node-releases@2.0.56: + resolution: {integrity: sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A==} + engines: {node: '>=18'} + nopt@10.0.1: resolution: {integrity: sha512-df3sBr/6ax9hSGuC3CspvLlbnX8cP5L5nZwXF8cGN8l0zSWR6BvzmQ6jPUKjvo6+/xdpkNvEcucBNUdBeeV13g==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} @@ -5182,10 +5183,6 @@ packages: resolution: {integrity: sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==} engines: {node: '>=14.16'} - p-event@6.0.1: - resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} - engines: {node: '>=16.17'} - p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -5198,10 +5195,6 @@ packages: resolution: {integrity: sha512-MitaVsCuCFIvOLLPIU7NnfrZvS9H9h7kwMUkDo+T2pEISaJD48IV9S8iIdXB7PsvvdxyYcsSTTrr90XKsbulNw==} engines: {node: '>=18'} - p-timeout@6.1.4: - resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} - engines: {node: '>=14.16'} - pac-proxy-agent@9.1.0: resolution: {integrity: sha512-1aU+1mpj3DrQPfo3gh+3Gap3G5x+axnMx1P/y0ZF2ch7kb2meyOCAH8K2k9d27ROsTE7TnAerzxqF9aon2jqnA==} engines: {node: '>= 20'} @@ -5721,10 +5714,6 @@ packages: striptags@3.2.0: resolution: {integrity: sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==} - super-regex@1.1.0: - resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} - engines: {node: '>=18'} - supports-color@10.2.2: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} @@ -5763,10 +5752,6 @@ packages: resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==} engines: {node: '>=20'} - time-span@5.1.0: - resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} - engines: {node: '>=12'} - timers-ext@0.1.8: resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} engines: {node: '>=0.12'} @@ -6051,6 +6036,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.3.3: + resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -6215,9 +6206,6 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} - web-worker@1.5.0: - resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} - webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -6362,6 +6350,11 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -6566,7 +6559,7 @@ snapshots: cjs-module-lexer: 1.2.3 esbuild: 0.28.1 miniflare: 5.20260911.1-alpha(@types/node@26.6.1)(bufferutil@4.1.0)(utf-8-validate@5.0.10) - vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)) + vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)) wrangler: 4.131.2(@cloudflare/workers-types@5.20260915.1)(@types/node@26.6.1)(bufferutil@4.1.0)(utf-8-validate@5.0.10) zod: 4.4.3 transitivePeerDependencies: @@ -6921,9 +6914,9 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/css-tree@4.0.5': + '@eslint/css-tree@4.1.1': dependencies: - mdn-data: 2.29.0 + mdn-data: 2.35.0 source-map-js: 1.2.1 '@eslint/js@10.0.1(eslint@10.10.0(jiti@2.7.0))': @@ -8373,7 +8366,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)) + vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)) '@vitest/expect@4.1.11': dependencies: @@ -8384,14 +8377,14 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.11(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0))': + '@vitest/mocker@4.1.11(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1))': dependencies: '@vitest/spy': 4.1.11 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2) - vite: 7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0) + vite: 7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1) '@vitest/pretty-format@4.1.11': dependencies: @@ -8576,6 +8569,8 @@ snapshots: baseline-browser-mapping@2.11.20: {} + baseline-browser-mapping@2.11.25: {} + basic-ftp@5.3.1: {} bcrypt-pbkdf@1.0.2: @@ -8619,6 +8614,14 @@ snapshots: node-releases: 2.0.54 update-browserslist-db: 1.3.2(browserslist@4.28.8) + browserslist@4.29.0: + dependencies: + baseline-browser-mapping: 2.11.25 + caniuse-lite: 1.0.30001810 + electron-to-chromium: 1.5.431 + node-releases: 2.0.56 + update-browserslist-db: 1.3.3(browserslist@4.29.0) + buffer-equal-constant-time@1.0.1: {} bufferutil@1.1.0: @@ -8631,7 +8634,7 @@ snapshots: dependencies: node-gyp-build: 4.8.4 - builtin-modules@5.3.0: {} + builtin-modules@5.4.0: {} byte-counter@0.1.0: {} @@ -8773,15 +8776,13 @@ snapshots: content-type@2.0.0: {} - convert-hrtime@5.0.0: {} - convert-source-map@2.0.0: {} cookie@1.1.1: {} core-js-compat@3.50.0: dependencies: - browserslist: 4.28.8 + browserslist: 4.29.0 core-js@2.6.12: {} @@ -8973,6 +8974,8 @@ snapshots: electron-to-chromium@1.5.416: {} + electron-to-chromium@1.5.431: {} + emoji-regex@8.0.0: {} empathic@2.0.1: {} @@ -9197,11 +9200,11 @@ snapshots: dependencies: eslint: 10.10.0(jiti@2.7.0) - eslint-plugin-unicorn@74.0.0(eslint@10.10.0(jiti@2.7.0)): + eslint-plugin-unicorn@75.0.0(eslint@10.10.0(jiti@2.7.0)): dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.10.0(jiti@2.7.0)) - '@eslint/css-tree': 4.0.5 - browserslist: 4.28.8 + '@eslint/css-tree': 4.1.1 + browserslist: 4.29.0 change-case: 5.4.4 ci-info: 4.4.0 core-js-compat: 3.50.0 @@ -9210,16 +9213,16 @@ snapshots: eslint: 10.10.0(jiti@2.7.0) find-up-simple: 1.0.1 globals: 17.12.0 + identifier-regex: 1.1.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 - is-identifier: 1.1.0 pluralize: 8.0.0 quote-js-string: 0.1.0 regjsparser: 0.13.2 reserved-identifiers: 1.2.0 semver: 7.8.5 strip-indent: 4.1.1 - yaml: 2.9.0 + yaml: 2.9.1 eslint-plugin-yml@3.8.1(eslint@10.10.0(jiti@2.7.0)): dependencies: @@ -9449,8 +9452,6 @@ snapshots: fsevents@2.3.3: optional: true - function-timeout@1.0.2: {} - gaxios@7.3.1: dependencies: extend: 3.0.2 @@ -9796,7 +9797,7 @@ snapshots: is-builtin-module@5.0.0: dependencies: - builtin-modules: 5.3.0 + builtin-modules: 5.4.0 is-docker@2.2.1: {} @@ -9810,11 +9811,6 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-identifier@1.1.0: - dependencies: - identifier-regex: 1.1.0 - super-regex: 1.1.0 - is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -10103,12 +10099,6 @@ snapshots: '@babel/types': 7.29.8 source-map-js: 1.2.1 - make-asynchronous@1.1.0: - dependencies: - p-event: 6.0.1 - type-fest: 4.41.0 - web-worker: 1.5.0 - make-dir@4.0.0: dependencies: semver: 7.8.5 @@ -10236,7 +10226,7 @@ snapshots: mdn-data@2.27.1: {} - mdn-data@2.29.0: {} + mdn-data@2.35.0: {} mdurl@2.1.0: {} @@ -10570,6 +10560,8 @@ snapshots: node-releases@2.0.54: {} + node-releases@2.0.56: {} + nopt@10.0.1: dependencies: abbrev: 5.0.0 @@ -10631,7 +10623,7 @@ snapshots: openapi3-ts@4.6.1: dependencies: - yaml: 2.9.0 + yaml: 2.9.1 optionator@0.9.4: dependencies: @@ -10769,10 +10761,6 @@ snapshots: p-cancelable@4.0.1: {} - p-event@6.0.1: - dependencies: - p-timeout: 6.1.4 - p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -10783,8 +10771,6 @@ snapshots: p-map@7.0.8: {} - p-timeout@6.1.4: {} - pac-proxy-agent@9.1.0: dependencies: agent-base: 9.0.0 @@ -11398,12 +11384,6 @@ snapshots: striptags@3.2.0: {} - super-regex@1.1.0: - dependencies: - function-timeout: 1.0.2 - make-asynchronous: 1.1.0 - time-span: 5.1.0 - supports-color@10.2.2: {} supports-color@7.2.0: @@ -11440,10 +11420,6 @@ snapshots: dependencies: real-require: 1.0.0 - time-span@5.1.0: - dependencies: - convert-hrtime: 5.0.0 - timers-ext@0.1.8: dependencies: es5-ext: 0.10.64 @@ -11699,6 +11675,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.3.3(browserslist@4.29.0): + dependencies: + browserslist: 4.29.0 + escalade: 3.2.0 + picocolors: 1.1.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -11756,16 +11738,16 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-tsconfig-paths@7.0.0-alpha.3(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)): + vite-tsconfig-paths@7.0.0-alpha.3(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)): dependencies: debug: 4.4.3 get-tsconfig: 5.0.0-beta.6 oxc-resolver: 11.24.2 - vite: 7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0) + vite: 7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1) transitivePeerDependencies: - supports-color - vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0): + vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.7) @@ -11779,12 +11761,12 @@ snapshots: jiti: 2.7.0 lightningcss: 1.32.0 tsx: 4.23.13 - yaml: 2.9.0 + yaml: 2.9.1 - vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)): + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.1)(@vitest/coverage-v8@4.1.11)(jsdom@30.1.0(@noble/hashes@2.3.0))(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)): dependencies: '@vitest/expect': 4.1.11 - '@vitest/mocker': 4.1.11(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0)) + '@vitest/mocker': 4.1.11(msw@2.15.0(@types/node@26.6.1)(@typescript/typescript6@6.0.2))(vite@7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1)) '@vitest/pretty-format': 4.1.11 '@vitest/runner': 4.1.11 '@vitest/snapshot': 4.1.11 @@ -11801,7 +11783,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.0) + vite: 7.3.1(@types/node@26.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.13)(yaml@2.9.1) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 @@ -11822,8 +11804,6 @@ snapshots: web-streams-polyfill@3.3.3: {} - web-worker@1.5.0: {} - webidl-conversions@3.0.1: {} webidl-conversions@8.0.1: {} @@ -11978,6 +11958,8 @@ snapshots: yaml@2.9.0: {} + yaml@2.9.1: {} + yargs-parser@21.1.1: {} yargs-parser@22.0.0: {} diff --git a/scripts/workflow/build-routes.ts b/scripts/workflow/build-routes.ts index 89f77b0b95..6c318efc1c 100644 --- a/scripts/workflow/build-routes.ts +++ b/scripts/workflow/build-routes.ts @@ -69,25 +69,26 @@ for (const namespace in namespaces) { const parsedDomain = parse(new URL('https://' + radarItem.source[0]).hostname); const subdomain = parsedDomain.subdomain || '.'; const domain = parsedDomain.domain; - if (domain) { - if (!Object.hasOwn(radar, domain)) { - radar[domain] = { - _name: namespaceData.name, - }; - } - if (!Object.hasOwn(radar[domain], subdomain)) { - radar[domain][subdomain] = []; - } - radar[domain][subdomain].push({ - title: radarItem.title || data.name, - docs: `https://docs.rsshub.app/routes/${categories[0]}`, - source: radarItem.source.map((source) => { - const sourceURL = new URL('https://' + source); - return sourceURL.pathname + sourceURL.search + sourceURL.hash; - }), - target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath, - }); + if (!domain) { + continue; } + if (!Object.hasOwn(radar, domain)) { + radar[domain] = { + _name: namespaceData.name, + }; + } + if (!Object.hasOwn(radar[domain], subdomain)) { + radar[domain][subdomain] = []; + } + radar[domain][subdomain].push({ + title: radarItem.title || data.name, + docs: `https://docs.rsshub.app/routes/${categories[0]}`, + source: radarItem.source.map((source) => { + const sourceURL = new URL('https://' + source); + return sourceURL.pathname + sourceURL.search + sourceURL.hash; + }), + target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath, + }); } } data.module = `() => import('@/routes/${namespace}/${data.location}')`; diff --git a/scripts/workflow/test-issue/call-maintainer.mjs b/scripts/workflow/test-issue/call-maintainer.mjs index 1e35f3b1df..06a1cd669e 100644 --- a/scripts/workflow/test-issue/call-maintainer.mjs +++ b/scripts/workflow/test-issue/call-maintainer.mjs @@ -143,18 +143,19 @@ export default async function callMaintainer({ github, context, core }) { continue; } - if (main.length > 0) { - const pingStr = main - .map((e) => { - if (dndUsernames.has(e)) { - return `\`@${e}\``; // Wrap in an inline code block to make sure no mention will be sent - } - return `@${e}`; - }) - .join(' '); - comments += `- \`${route}\`: ${pingStr}\n`; - successCount += 1; + if (main.length === 0) { + continue; } + const pingStr = main + .map((e) => { + if (dndUsernames.has(e)) { + return `\`@${e}\``; // Wrap in an inline code block to make sure no mention will be sent + } + return `@${e}`; + }) + .join(' '); + comments += `- \`${route}\`: ${pingStr}\n`; + successCount += 1; } const labels = ['']; diff --git a/tests/cache-atomic-backends.test.ts b/tests/cache-atomic-backends.test.ts index c68a91e5d5..665d37be85 100644 --- a/tests/cache-atomic-backends.test.ts +++ b/tests/cache-atomic-backends.test.ts @@ -47,9 +47,11 @@ describe('atomic cache backends', () => { await cache.globalCache.set('same-request', '0', 60); expect(await cache.globalCache.claim('same-request', 60)).toBe(true); - if (backend === 'redis') { - expect(state.eval).toHaveBeenCalledTimes(3); - expect(state.eval).toHaveBeenCalledWith(expect.stringContaining("redis.call('GET', KEYS[1])"), 1, 'same-request', 60); + if (backend !== 'redis') { + return; } + + expect(state.eval).toHaveBeenCalledTimes(3); + expect(state.eval).toHaveBeenCalledWith(expect.stringContaining("redis.call('GET', KEYS[1])"), 1, 'same-request', 60); }); });