style: replace unicorn/no-for-loop w/ typescript/prefer-for-of (#20798)

* style: replace unicorn/no-for-loop w/ typescript/prefer-for-of

* style: fix typescript-eslint/prefer-for-of

* style: fix typescript/no-inferrable-types

* style: fix typescript-eslint/consistent-generic-constructors

* style: typescript-eslint/consistent-type-assertions

* style: fix typescript-eslint/array-type

* fix: revert .entries() in d96ca62d3d
This commit is contained in:
Tony
2026-01-02 09:42:24 +08:00
committed by GitHub
parent 1352d30978
commit b84bb92a8a
214 changed files with 575 additions and 566 deletions
+12 -1
View File
@@ -29,7 +29,7 @@ export default [
{
ignores: ['**/coverage', '**/.vscode', '**/docker-compose.yml', '!.github', 'assets/build', 'lib/routes-deprecated', 'lib/router.js', '**/babel.config.js', 'scripts/docker/minify-docker.js', 'dist', 'dist-lib'],
},
...compat.extends('eslint:recommended', 'plugin:yml/recommended', 'plugin:@typescript-eslint/recommended'),
...compat.extends('eslint:recommended', 'plugin:yml/recommended', 'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/stylistic'),
n.configs['flat/recommended-script'],
unicorn.configs.recommended,
{
@@ -147,8 +147,16 @@ export default [
'require-await': 'error',
// typescript
'@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off', // stylistic
'@typescript-eslint/consistent-type-definitions': 'off', // stylistic
'@typescript-eslint/no-empty-function': 'off', // stylistic && tests
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-inferrable-types': ['error', { ignoreParameters: true, ignoreProperties: true }],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unused-expressions': [
@@ -167,6 +175,8 @@ export default [
},
],
'@typescript-eslint/prefer-for-of': 'error',
// unicorn
'unicorn/consistent-function-scoping': 'warn',
'unicorn/explicit-length-check': 'off',
@@ -184,6 +194,7 @@ export default [
'unicorn/no-array-sort': 'warn',
'unicorn/no-await-expression-member': 'off',
'unicorn/no-empty-file': 'warn',
'unicorn/no-for-loop': 'off',
'unicorn/no-hex-escape': 'warn',
'unicorn/no-null': 'off',
'unicorn/no-object-as-default-parameter': 'warn',
+2 -2
View File
@@ -223,13 +223,13 @@ for (const namespace in namespaces) {
continue;
}
const sortedRoutes = Object.entries(namespaceData.apiRoutes) as [
const sortedRoutes = Object.entries(namespaceData.apiRoutes) as Array<[
string,
APIRoute & {
location: string;
module?: () => Promise<{ apiRoute: APIRoute }>;
},
][];
]>;
for (const [path, routeData] of sortedRoutes) {
const wrappedHandler: Handler = async (ctx) => {
+2 -2
View File
@@ -10,8 +10,8 @@ module.exports = async (ctx) => {
const name = data[0].feedNews.footer.source;
const newData = [];
let pubDate = [];
for (const [i, datum] of data.entries()) {
newData[i] = datum.feedNews.body;
for (let i = 0; i < data.length; i++) {
newData[i] = data[i].feedNews.body;
newData[i].link = 'https://mlol.qt.qq.com/go/mlol_news/varcache_article?is_lqt=true&docid=' + newData[i].commentID;
pubDate[i] = getPublishedDate(newData[i].link);
}
+1 -1
View File
@@ -51,7 +51,7 @@ async function checkRSS(response) {
checkDate(parsed.lastBuildDate);
// check items
const guids: (string | undefined)[] = [];
const guids: Array<string | undefined> = [];
for (const item of parsed.items) {
expect(item).toEqual(expect.any(Object));
expect(item.title).toEqual(expect.any(String));
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { filter } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
const baseUrl: string = 'https://0xxx.ws';
const baseUrl = 'https://0xxx.ws';
const targetUrl: string = new URL(filter ? `?${filter}` : '', baseUrl).href;
const response = await ofetch(targetUrl);
+2 -2
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'newslists', id } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://info.10000link.com';
const baseUrl = 'https://info.10000link.com';
const targetUrl: string = new URL(`${category}.aspx${id ? `?chid=${id}` : ''}`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -109,7 +109,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
)
).filter((_): _ is DataItem => true);
const author: string = '10000万联网';
const author = '10000万联网';
const title: string = $('h1').contents().first().text();
return {
+3 -3
View File
@@ -27,8 +27,8 @@ const renderDescription = (description, images) =>
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
const baseUrl: string = 'https://tf.121.com.cn';
const imgBaseUrl: string = 'https://wx.121.com.cn';
const baseUrl = 'https://tf.121.com.cn';
const imgBaseUrl = 'https://wx.121.com.cn';
const targetUrl: string = new URL('web/weatherLive/', baseUrl).href;
const apiUrl: string = new URL('weather/weibo/message.js', baseUrl).href;
@@ -52,7 +52,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
);
const pubDate: number | string = item.DDatetime;
const linkUrl: string | undefined = targetUrl;
const guid: string = `121-${title}-${pubDate}`;
const guid = `121-${title}-${pubDate}`;
const image: string | undefined = item.Img?.length > 0 ? new URL(`WeChat/data/weiweb/images/lwspic/${item.Img[0]}`, imgBaseUrl).href : undefined;
const updated: number | string = pubDate;
+1 -1
View File
@@ -14,7 +14,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'newly' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://www.199it.com';
const baseUrl = 'https://www.199it.com';
const targetUrl: string = new URL(category, baseUrl).href;
const response = await ofetch(targetUrl);
+4 -4
View File
@@ -45,9 +45,9 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { name = '热点' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const domain: string = 'm.21jingji.com';
const baseUrl: string = `https://${domain}`;
const staticBaseUrl: string = 'https://static.21jingji.com';
const domain = 'm.21jingji.com';
const baseUrl = `https://${domain}`;
const staticBaseUrl = 'https://static.21jingji.com';
const menuUrl: string = new URL('m/webMenu.json', staticBaseUrl).href;
const menuResponse = await ofetch(menuUrl);
@@ -97,7 +97,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const authors: DataItem['author'] = [...new Set([item.mp?.name, item.author, item.editor, item.source].filter(Boolean))].map((name) => ({
name,
}));
const guid: string = `21jingji-${item.id}`;
const guid = `21jingji-${item.id}`;
const image: string | undefined = item.image ?? item.thumb ?? item.listthumb;
const updated: number | string = item.updatetime;
+2 -3
View File
@@ -16,11 +16,10 @@ const getAcwScV2ByArg1 = (arg1) => {
const unsbox = function (str: string) {
const code = [15, 35, 29, 24, 33, 16, 1, 38, 10, 9, 19, 31, 40, 27, 22, 23, 25, 13, 6, 11, 39, 18, 20, 8, 14, 21, 32, 26, 2, 30, 7, 4, 17, 5, 3, 28, 34, 37, 12, 36];
const res: string[] = [];
// eslint-disable-next-line unicorn/no-for-loop
for (let i = 0; i < str.length; i++) {
const cur = str[i];
for (const [j, element] of code.entries()) {
if (element === i + 1) {
for (let j = 0; j < code.length; j++) {
if (code[j] === i + 1) {
res[j] = cur;
}
}
+4 -4
View File
@@ -14,9 +14,9 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'dy' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '25', 10);
const encoding: string = 'gb2312';
const encoding = 'gb2312';
const baseUrl: string = 'https://www.hao6v.me';
const baseUrl = 'https://www.hao6v.me';
const targetUrl: string = new URL(category.startsWith('gvod') ? `${category}.html` : category, baseUrl).href;
const response = await ofetch(targetUrl, {
@@ -39,7 +39,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
.text()
.replaceAll(/(\[|\])/g, '');
const linkUrl: string | undefined = $el.find('a').attr('href');
const guid: string = `${linkUrl}#${title}`;
const guid = `${linkUrl}#${title}`;
const upDatedStr: string | undefined = pubDateStr;
const processedItem: DataItem = {
@@ -101,7 +101,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const enclosureUrl: string | undefined = $enclosureEl.attr('href');
if (enclosureUrl) {
const enclosureType: string = 'application/x-bittorrent';
const enclosureType = 'application/x-bittorrent';
const enclosureTitle: string = $enclosureEl.text();
processedItem = {
+1 -1
View File
@@ -12,7 +12,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
const apiSlug = 'wp-json/wp/v2';
const baseUrl: string = 'https://60s.aa1.cn';
const baseUrl = 'https://60s.aa1.cn';
const apiUrl = new URL(`${apiSlug}/posts`, baseUrl).href;
const apiSearchUrl = new URL(`${apiSlug}/categories`, baseUrl).href;
+1 -1
View File
@@ -15,7 +15,7 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '24', 10);
const baseUrl: string = 'https://www.adquan.com';
const baseUrl = 'https://www.adquan.com';
const targetUrl: string = new URL('case_library/index', baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -15,7 +15,7 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://www.adquan.com';
const baseUrl = 'https://www.adquan.com';
const targetUrl: string = baseUrl;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -12,7 +12,7 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '5', 10);
const baseUrl: string = 'https://aflcio.org';
const baseUrl = 'https://aflcio.org';
const targetUrl: string = new URL('blog', baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -16,7 +16,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'new' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const rootUrl: string = 'https://www.ali213.net';
const rootUrl = 'https://www.ali213.net';
const targetUrl: string = new URL(`news/${category.endsWith('/') ? category : `${category}/`}`, rootUrl).href;
const response = await ofetch(targetUrl);
+3 -3
View File
@@ -15,8 +15,8 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '1', 10);
const rootUrl: string = 'https://www.ali213.net';
const apiRootUrl: string = 'https://mp.ali213.net';
const rootUrl = 'https://www.ali213.net';
const apiRootUrl = 'https://mp.ali213.net';
const targetUrl: string = new URL(`/news/zl/${category ? (category.endsWith('/') ? category : `${category}/`) : ''}`, rootUrl).href;
const apiUrl: string = new URL('ajax/newslist', apiRootUrl).href;
@@ -37,7 +37,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const description: string = renderDescription({
intro: item.GuideRead ?? '',
});
const guid: string = `ali213-zl-${item.ID}`;
const guid = `ali213-zl-${item.ID}`;
const image: string | undefined = item.PicPath ? `https:${item.PicPath}` : undefined;
const author: DataItem['author'] = item.xiaobian;
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { device, sort, searchParams } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://amazfitwatchfaces.com';
const baseUrl = 'https://amazfitwatchfaces.com';
const targetUrl: string = new URL(`${device}/${sort}${searchParams ? `?${searchParams}` : ''}`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://anytxt.net';
const baseUrl = 'https://anytxt.net';
const targetUrl: string = new URL('download/', baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -21,7 +21,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
});
const $: CheerioAPI = load(response);
const language = $('html').attr('lang') ?? 'en';
const selector: string = 'div.card-panel';
const selector = 'div.card-panel';
const items: DataItem[] = await fetchItems($, selector, targetUrl, country, limit);
+3 -3
View File
@@ -6,7 +6,7 @@ import { renderToString } from 'hono/jsx/dom/server';
import type { DataItem } from '@/types';
import ofetch from '@/utils/ofetch';
const baseUrl: string = 'https://www.app-sales.net';
const baseUrl = 'https://www.app-sales.net';
const renderDescription = ({
images,
appName,
@@ -20,7 +20,7 @@ const renderDescription = ({
priceDisco,
linkUrl,
}: {
images?: { alt?: string; src?: string }[];
images?: Array<{ alt?: string; src?: string }>;
appName?: string;
appDev?: string;
appNote?: string;
@@ -150,7 +150,7 @@ const processItems = ($: CheerioAPI, selector: string): DataItem[] =>
const isHot: boolean = $el.hasClass('sale-hot');
const isFree: boolean = priceNew?.toLocaleUpperCase() === 'FREE';
const title: string = `${appName} ${formatPriceChangeTag(priceOld, priceNew, priceDisco)}`;
const title = `${appName} ${formatPriceChangeTag(priceOld, priceNew, priceDisco)}`;
const image: string | undefined = $el.find('div.app-icon img').attr('src');
const linkUrl: string | undefined = $el.find('div.sale-list-action a').attr('href');
const description: string | undefined = renderDescription({
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { language = 'en-us' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://support.apple.com';
const baseUrl = 'https://support.apple.com';
const targetUrl: string = new URL(`${language}/100100`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -7,11 +7,11 @@ type DescriptionData = {
src?: string;
title?: string;
};
assets?: {
assets?: Array<{
asset_type?: string;
player_embedded?: string;
image_url?: string;
}[];
}>;
};
const ArtstationDescription = ({ description, image, assets }: DescriptionData) => (
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'all' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10);
const baseUrl: string = 'https://asiafruitchina.net';
const baseUrl = 'https://asiafruitchina.net';
const targetUrl: string = new URL(`categories?gspx=${category}`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -14,7 +14,7 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://asiafruitchina.net';
const baseUrl = 'https://asiafruitchina.net';
const targetUrl: string = new URL('category/news', baseUrl).href;
const response = await ofetch(targetUrl);
+12 -12
View File
@@ -21,54 +21,54 @@ export interface Work {
duration: number;
has_subtitle: boolean;
id: number;
language_editions: {
language_editions: Array<{
display_order: number;
edition_id: number;
edition_type: string;
label: string;
lang: string;
workno: string;
}[];
}>;
mainCoverUrl: string;
name: string;
nsfw: boolean;
original_workno: null | string;
other_language_editions_in_db: {
other_language_editions_in_db: Array<{
id: number;
is_original: boolean;
lang: string;
source_id: string;
source_type: string;
title: string;
}[];
}>;
playlistStatus: any;
price: number;
rank:
| {
| Array<{
category: string;
rank: number;
rank_date: string;
term: string;
}[]
}>
| null;
rate_average_2dp: number | number;
rate_count: number;
rate_count_detail: {
rate_count_detail: Array<{
count: number;
ratio: number;
review_point: number;
}[];
}>;
release: string;
review_count: number;
samCoverUrl: string;
source_id: string;
source_type: string;
source_url: string;
tags: {
tags: Array<{
i18n: any;
id: number;
name: string;
}[];
}>;
category: string;
thumbnailCoverUrl: string;
title: string;
@@ -87,10 +87,10 @@ export interface Work {
translation_bonus_langs: string[];
};
userRating: null;
vas: {
vas: Array<{
id: string;
name: string;
}[];
}>;
cv: string;
work_attributes: string;
}
+1 -1
View File
@@ -33,7 +33,7 @@ const renderDescription = ({ images, description }: { images?: DescriptionImage[
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10);
const baseUrl: string = 'https://augmentcode.com';
const baseUrl = 'https://augmentcode.com';
const targetUrl: string = new URL('blog', baseUrl).href;
const response = await ofetch(targetUrl);
+5 -5
View File
@@ -9,8 +9,8 @@ import ofetch from '@/utils/ofetch';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://www.azul.com';
const apiBaseUrl: string = 'https://api.azul.com';
const baseUrl = 'https://www.azul.com';
const apiBaseUrl = 'https://api.azul.com';
const targetUrl: string = new URL('downloads', baseUrl).href;
const apiUrl: string = new URL('metadata/v1/zulu/packages', apiBaseUrl).href;
@@ -30,13 +30,13 @@ export const handler = async (ctx: Context): Promise<Data> => {
});
const items: DataItem[] = response.slice(0, limit).map((item): DataItem => {
const javaVersion: string = `${item.java_version.join('.')}+${item.openjdk_build_number}`;
const javaVersion = `${item.java_version.join('.')}+${item.openjdk_build_number}`;
const distroVersion: string = item.distro_version.join('.');
const title: string = `[${javaVersion}] (${distroVersion}) ${item.name}`;
const title = `[${javaVersion}] (${distroVersion}) ${item.name}`;
const linkUrl: string | undefined = item.download_url;
const categories: string[] = [item.os, item.arch, item.java_package_type, item.archive_type, item.abi, ...(item.javafx_bundled ? ['javafx'] : []), ...(item.crac_supported ? ['crac'] : [])];
const guid: string = `azul-${item.name}`;
const guid = `azul-${item.name}`;
let processedItem: DataItem = {
title,
+1 -1
View File
@@ -40,7 +40,7 @@ const handler: Route['handler'] = async (ctx) => {
const ja: Route['handler'] = async (ctx) => {
const { type = '0' } = ctx.req.param();
const response = await ofetch<{ data: { rows: { id: number; content: string; title: string; publishTime: number }[] } }>('https://www.azurlane.jp/api/news/list', {
const response = await ofetch<{ data: { rows: Array<{ id: number; content: string; title: string; publishTime: number }> } }>('https://www.azurlane.jp/api/news/list', {
query: {
type,
index: 1,
+1 -1
View File
@@ -51,7 +51,7 @@ async function handler(ctx) {
if (tagId) {
const tagsData = await getTagsData();
const tag = (tagsData as Record<string, string>[]).find((tag) => tag.id === tagId);
const tag = (tagsData as Array<Record<string, string>>).find((tag) => tag.id === tagId);
if (tag) {
title = tag.title;
description = tag.description;
+4 -4
View File
@@ -130,19 +130,19 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { id = 'bandizip', language = 'en' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '500', 10);
const validIds: Set<string> = new Set(idOptions.map((option) => option.value));
const validIds = new Set<string>(idOptions.map((option) => option.value));
if (!validIds.has(id)) {
throw new Error(`Invalid id: ${id}. Allowed values are: ${[...validIds].join(', ')}`);
}
const validLanguages: Set<string> = new Set(languageOptions.map((option) => option.value));
const validLanguages = new Set<string>(languageOptions.map((option) => option.value));
if (!validLanguages.has(language)) {
throw new Error(`Invalid language: ${language}. Allowed values are: ${[...validLanguages].join(', ')}`);
}
const baseUrl: string = `https://${language}.bandisoft.com`;
const baseUrl = `https://${language}.bandisoft.com`;
const targetUrl: string = new URL(`${id}/history/`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -163,7 +163,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const description: string | undefined = $el.find('ul.cell3').html() ?? undefined;
const linkUrl: string = targetUrl;
const guid: string = `bandisoft-${id}-${language}-${version}`;
const guid = `bandisoft-${id}-${language}-${version}`;
const upDatedStr: string | undefined = pubDateStr;
const processedItem: DataItem = {
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10);
const baseUrl: string = 'http://banshujiang.cn';
const baseUrl = 'http://banshujiang.cn';
const targetUrl: string = new URL(`${category ? 'e_books' : `category/${category}`}/page/1`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -16,7 +16,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { id = 'jinritan' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'http://www.banyuetan.org';
const baseUrl = 'http://www.banyuetan.org';
const targetUrl: string = new URL(`byt/${id}/index.html`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -35,7 +35,7 @@ const getCookie = (disableConfig = false) => {
}
const key = 'bili-cookie';
return cache.tryGet(key, async () => {
let waitForRequest: Promise<string> = new Promise((resolve) => {
let waitForRequest = new Promise<string>((resolve) => {
resolve('');
});
const { destory } = await getPuppeteerPage('https://space.bilibili.com/1/dynamic', {
+2 -2
View File
@@ -129,11 +129,11 @@ const getIframe = (data?: Modules, embed: boolean = true) => {
};
const getImgs = (data?: Modules) => {
const imgUrls: {
const imgUrls: Array<{
url: string;
width?: number;
height?: number;
}[] = [];
}> = [];
const major = data?.module_dynamic?.major;
if (!major) {
return '';
+4 -4
View File
@@ -105,14 +105,14 @@ async function handler(ctx) {
let imgs = '';
// 动态图片
if (data.pictures) {
for (let i = 0; i < data.pictures.length; i++) {
imgs += `<img src="${data.pictures[i].img_src}">`;
for (const pic of data.pictures) {
imgs += `<img src="${pic.img_src}">`;
}
}
// 专栏封面
if (data.image_urls) {
for (let i = 0; i < data.image_urls.length; i++) {
imgs += `<img src="${data.image_urls[i]}">`;
for (const url of data.image_urls) {
imgs += `<img src="${url}">`;
}
}
// 视频封面
+1 -1
View File
@@ -41,7 +41,7 @@ const handler: Route['handler'] = async (ctx) => {
const ja: Route['handler'] = async (ctx) => {
const { type = '0' } = ctx.req.param();
const data = await ofetch<{ data: { rows: { id: number; content: string; summary: string; publishTime: number }[] } }, 'json'>('https://api-web.bluearchive.jp/api/news/list', {
const data = await ofetch<{ data: { rows: Array<{ id: number; content: string; summary: string; publishTime: number }> } }, 'json'>('https://api-web.bluearchive.jp/api/news/list', {
query: {
typeId: type,
pageNum: 16,
+2 -2
View File
@@ -12,7 +12,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { filter = 'order=sell_desc' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '24', 10);
const baseUrl: string = 'https://www.bookwalker.com.tw';
const baseUrl = 'https://www.bookwalker.com.tw';
const targetUrl: string = new URL(`search?${filter}`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -29,7 +29,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const price: string = $el.find('h5.bprice').text();
const authorStr: string = $el.find('h5.booknamesub').text().trim();
const title: string = `${name} - ${authorStr} ${price}`;
const title = `${name} - ${authorStr} ${price}`;
const image: string | undefined = $el
.find('img')
.attr('data-src')
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://bullionvault.com';
const baseUrl = 'https://bullionvault.com';
const targetUrl: string = new URL(`gold-news${category ? `/${category}` : ''}`, baseUrl).href;
const response = await ofetch(targetUrl);
+8 -8
View File
@@ -10,36 +10,36 @@ export interface UserNextData {
}
export interface PortfolioResponse {
data: {
data: Array<{
url: string;
postId: string;
imageNum: number;
}[];
}>;
}
export interface PortfolioDetailResponse {
data: {
createdAt: string;
images: {
images: Array<{
src: string;
isCoverImg: boolean;
}[];
}>;
title: string;
content: string;
};
}
export interface PostsResponse {
data: {
data: Array<{
name: string;
photo: string;
createdAt: string;
images: {
images: Array<{
src: string;
isCoverImg: boolean;
}[];
}>;
id: string;
title: string;
content: string;
}[];
}>;
}
+4 -4
View File
@@ -14,7 +14,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { id = 'all' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10);
const baseUrl: string = 'https://www.cbndata.com';
const baseUrl = 'https://www.cbndata.com';
const targetUrl: string = new URL(`information?tag_id=${id}`, baseUrl).href;
const apiUrl: string = new URL('api/v3/informations', baseUrl).href;
@@ -47,7 +47,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const pubDate: number | string = item.date;
const linkUrl: string | undefined = item.id ? `information/${item.id}` : undefined;
const categories: string[] = item.tags;
const guid: string = `cbndata-information-${item.id}`;
const guid = `cbndata-information-${item.id}`;
const updated: number | string = pubDate;
const processedItem: DataItem = {
@@ -108,7 +108,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
avatar: undefined,
},
];
const guid: string = `cbndata-information-${data.id}`;
const guid = `cbndata-information-${data.id}`;
const image: string | undefined = data.thumbnail_url;
const updated: number | string = pubDate;
@@ -140,7 +140,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
);
const tag: string = response.home_tags.find((t: { id: number; name: string }) => String(t.id) === id)?.name ?? '';
const title: string = `${tag ? `${tag}-` : ''}${$('title').text().trim()}`;
const title = `${tag ? `${tag}-` : ''}${$('title').text().trim()}`;
return {
title,
+1 -1
View File
@@ -14,7 +14,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'association-news' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10);
const baseUrl: string = 'http://www.ccagm.org.cn';
const baseUrl = 'http://www.ccagm.org.cn';
const targetUrl: string = new URL(category, baseUrl).href;
const response = await ofetch(targetUrl);
+2 -2
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'ywgg/tzgg' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '15', 10);
const baseUrl: string = 'https://www.cccmc.org.cn';
const baseUrl = 'https://www.cccmc.org.cn';
const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -22,7 +22,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
let items: DataItem[] = [];
const regex: RegExp = /\{url:'(.*)',title:'(.*)',time:'(.*)'\},/g;
const regex = /\{url:'(.*)',title:'(.*)',time:'(.*)'\},/g;
items =
response
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'news' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '7', 10);
const baseUrl: string = 'http://www.ccg.org.cn';
const baseUrl = 'http://www.ccg.org.cn';
const targetUrl: string = new URL(category, baseUrl).href;
const response = await ofetch(targetUrl);
+4 -4
View File
@@ -1,6 +1,6 @@
export interface LinkData {
'@context': string;
'@graph': {
'@graph': Array<{
'@type': string;
headline: string;
name: string;
@@ -18,13 +18,13 @@ export interface LinkData {
name: string;
url: string;
};
}[];
}>;
}
export interface VideoSetup {
techOrder: string[];
sources: {
sources: Array<{
type: string;
src: string;
}[];
}>;
}
+1 -1
View File
@@ -232,7 +232,7 @@ function parseDefault($): DataItem {
function parseLinkData($: CheerioAPI) {
try {
const data = (<LinkData>JSON.parse($('script[type="application/ld+json"]').text()))['@graph'][0];
const data = (JSON.parse($('script[type="application/ld+json"]').text()) as LinkData)['@graph'][0];
return {
title: data.name,
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'zxyw' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '11', 10);
const rootUrl: string = 'https://www.chinacdc.cn';
const rootUrl = 'https://www.chinacdc.cn';
const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, rootUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -16,7 +16,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'thelatest' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://language.chinadaily.com.cn';
const baseUrl = 'https://language.chinadaily.com.cn';
const targetUrl: string = new URL(category, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'Industry/Comment' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '15', 10);
const baseUrl: string = 'https://www.chinaratings.com.cn';
const baseUrl = 'https://www.chinaratings.com.cn';
const targetUrl: string = new URL(`CreditResearch/${category.endsWith('/') ? category : `${category}/`}`, baseUrl).href;
const response = await ofetch(targetUrl);
+2 -2
View File
@@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise<Data> => {
const { id } = ctx.req.param();
const baseUrl: string = 'https://community.chocolatey.org';
const baseUrl = 'https://community.chocolatey.org';
const targetUrl: string = new URL(`packages/${id}`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -33,7 +33,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
avatar: $authorEl.attr('src'),
};
});
const guid: string = `chocolatey-${title}`;
const guid = `chocolatey-${title}`;
const image: string | undefined = $('div.package-logo img').attr('src') ? new URL($('div.package-logo img').attr('src') as string, baseUrl).href : undefined;
const upDatedStr: string | undefined = pubDateStr;
+1 -1
View File
@@ -108,7 +108,7 @@ async function handler(ctx: Context): Promise<Data | null> {
link: $(element).attr('href'),
}));
const processedItems: Promise<DataItem>[] = articles
const processedItems: Array<Promise<DataItem>> = articles
.filter((article: RawArticle): article is ValidArticle => isValidArticle(article))
.map((article: ValidArticle) => {
if (article.link.startsWith('/')) {
+2 -2
View File
@@ -13,7 +13,7 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
const baseUrl: string = 'https://www.cloudflarestatus.com';
const baseUrl = 'https://www.cloudflarestatus.com';
const response = await ofetch(baseUrl);
const $: CheerioAPI = load(response);
@@ -32,7 +32,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const type: string = $el.find('strong').first().text();
const text: string = $el.find('span.whitespace-pre-wrap').first().text();
const title: string = `${type ? `${type} - ` : ''}${text}`;
const title = `${type ? `${type} - ` : ''}${text}`;
const description: string | undefined = renderToString(
<>
{actualTitle ? <h2>{actualTitle}</h2> : null}
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'news', id = '10' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10);
const baseUrl: string = 'https://www.cnljxh.org.cn';
const baseUrl = 'https://www.cnljxh.org.cn';
const targetUrl: string = new URL(`${category}/?classid=${id}`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -51,7 +51,7 @@ async function handler(ctx: Context) {
const $ = load(response);
const limit = ctx.req.query('limit') ? Number.parseInt(<string>ctx.req.query('limit')) : 20;
const limit = ctx.req.query('limit') ? Number.parseInt((ctx.req.query('limit') as string)) : 20;
const list =
type === 'home'
+3 -3
View File
@@ -10,8 +10,8 @@ import ofetch from '@/utils/ofetch';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10);
const baseUrl: string = 'https://coolbuy.com';
const imageBaseUrl: string = 'https://mcache.ifanr.cn';
const baseUrl = 'https://coolbuy.com';
const imageBaseUrl = 'https://mcache.ifanr.cn';
const apiUrl: string = new URL('api/v1.4/product_preview', baseUrl).href;
const response = await ofetch(apiUrl, {
@@ -77,7 +77,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
);
const linkUrl: string | undefined = item.visit_url;
const guid: string = `coolbuy-${item.id}#${item.price}`;
const guid = `coolbuy-${item.id}#${item.price}`;
const processedItem: DataItem = {
title,
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { filter } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10);
const baseUrl: string = 'https://www.costar.com';
const baseUrl = 'https://www.costar.com';
const targetUrl: string = new URL(`products/benchmark/resources/press-releases${filter ? `?${filter}` : ''}`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -71,7 +71,7 @@ async function handler(ctx) {
];
const seen = new Set<string>();
const dedupedList: { title?: string; link?: string }[] = [];
const dedupedList: Array<{ title?: string; link?: string }> = [];
for (const item of list) {
const link = item.link || '';
if (seen.has(link)) {
+3 -3
View File
@@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
const baseUrl: string = 'https://cursor.com';
const baseUrl = 'https://cursor.com';
const targetUrl: string = new URL('changelog', baseUrl).href;
const response = await ofetch(targetUrl, {
@@ -28,7 +28,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
.map((el): DataItem => {
const $el: Cheerio<Element> = $(el);
let version: string = '';
let version = '';
let pubDateStr: string | undefined;
$el.find('div').each((_, div) => {
@@ -47,7 +47,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const title: string = version ? `[${version}] ${titleText}` : titleText;
const linkUrl: string | undefined = linkEl.attr('href');
const guid: string = `cursor-changelog-${version || 'unknown'}`;
const guid = `cursor-changelog-${version || 'unknown'}`;
const upDatedStr: string | undefined = pubDateStr;
const $h2El = $el.find('h2').first();
+3 -3
View File
@@ -9,7 +9,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { lang } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '500', 10);
const baseUrl: string = 'https://t1.daumcdn.net';
const baseUrl = 'https://t1.daumcdn.net';
const targetUrl: string = new URL(`potplayer/PotPlayer/v4/Update2/Update${lang ?? ''}.html`, baseUrl).href;
const response: string = await ofetch(targetUrl);
@@ -29,7 +29,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const headerLine: string | undefined = match[2].trim();
const description: string | undefined = match[4].trim()?.replaceAll(/(\s[+-])/g, '<br>$1');
let version: string = 'N/A';
let version = 'N/A';
let pubDateStr: string | undefined = undefined;
// Regex to extract version (e.g., [1.4.20199] or [250514])
@@ -56,7 +56,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
}
}
const guid: string = `potplayer-${lang}-${version}`;
const guid = `potplayer-${lang}-${version}`;
const processedItem: DataItem = {
title: version,
+1 -1
View File
@@ -16,7 +16,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { id = '9' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://dbaplus.cn';
const baseUrl = 'https://dbaplus.cn';
const targetUrl: string = new URL(`news-${id}-1.html`, baseUrl).href;
const response = await ofetch(targetUrl);
+2 -2
View File
@@ -34,13 +34,13 @@ export const route: Route = {
};
interface ThreadIndexResult {
ThreadIndex: {
ThreadIndex: Array<{
id: number;
subject: string;
created_at: string;
user: { nickname: string };
forum: { name: string };
}[];
}>;
}
interface ThreadInfoResult {
data: {
+1 -1
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { lang = 'en' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://www.deepl.com';
const baseUrl = 'https://www.deepl.com';
const targetUrl: string = new URL(`${lang}/blog`, baseUrl).href;
const response = await ofetch(targetUrl);
+5 -5
View File
@@ -14,7 +14,7 @@ const md = MarkdownIt({
linkify: true,
});
const baseUrl: string = 'https://www.dgtle.com';
const baseUrl = 'https://www.dgtle.com';
const ProcessItems = async (limit: number, dataList: any): Promise<DataItem[]> => {
let items: DataItem[] = [];
@@ -43,7 +43,7 @@ const ProcessItems = async (limit: number, dataList: any): Promise<DataItem[]> =
avatar: item.user?.avatar_path ?? item.avatar_path,
},
];
const guid: string = `dgtle-${item.id}`;
const guid = `dgtle-${item.id}`;
const updated: number | string = pubDate;
const processedItem: DataItem = {
@@ -142,7 +142,7 @@ const ProcessFeedItems = (limit: number, dataList: any, $: CheerioAPI): DataItem
avatar: item.avatar_path,
},
];
const guid: string = `dgtle-${item.id}`;
const guid = `dgtle-${item.id}`;
const image: string | undefined = item.imgs_url?.[0];
const updated: number | string = item.updated_at ?? pubDate;
@@ -174,10 +174,10 @@ const ProcessFeedItems = (limit: number, dataList: any, $: CheerioAPI): DataItem
continue;
}
const medium: string = 'image';
const medium = 'image';
const count: number = Object.values(acc).filter((m) => m.medium === medium).length + 1;
const key: string = `${medium}${count}`;
const key = `${medium}${count}`;
acc[key] = {
url,
+2 -2
View File
@@ -15,7 +15,7 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '18', 10);
const baseUrl: string = 'https://www.dgtle.com';
const baseUrl = 'https://www.dgtle.com';
const targetUrl: string = new URL('video', baseUrl).href;
const apiUrl: string = new URL('video/list/1', baseUrl).href;
@@ -49,7 +49,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
avatar: item.author.avatar_path?.split(/\?/)?.[0],
},
];
const guid: string = `dgtle-${item.id}`;
const guid = `dgtle-${item.id}`;
const processedItem: DataItem = {
title,
+1 -1
View File
@@ -14,7 +14,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { filter } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://diariofruticola.cl';
const baseUrl = 'https://diariofruticola.cl';
const targetUrl: string = new URL(`filtro/${filter}`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -27,8 +27,8 @@ export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const params: URLSearchParams = createSearchParams(filters, limit);
const baseUrl: string = 'https://digitalpolicyalert.org';
const apiBaseUrl: string = 'https://api.globaltradealert.org';
const baseUrl = 'https://digitalpolicyalert.org';
const apiBaseUrl = 'https://api.globaltradealert.org';
const targetUrl: string = new URL(`activity-tracker?${params.toString()}`, baseUrl).href;
const apiUrl: string = new URL('dpa/intervention', apiBaseUrl).href;
+11 -11
View File
@@ -183,7 +183,7 @@ interface Music {
prevent_download: boolean;
unshelve_countries: null;
prevent_item_download_status: number;
external_song_info: false[];
external_song_info: Array<false>;
preview_start_time: number;
preview_end_time: number;
is_commerce_music: boolean;
@@ -191,7 +191,7 @@ interface Music {
audition_duration: number;
shoot_duration: number;
reason_type: number;
artists: false[];
artists: Array<false>;
lyric_short_position: null;
mute_share: boolean;
tag_list: null;
@@ -447,16 +447,16 @@ interface LogPb {
}
interface SuggestWords {
suggest_words: {
words: {
suggest_words: Array<{
words: Array<{
word: string;
word_id: string;
info: string;
}[];
}>;
scene: string;
icon_url: string;
hint_text: string;
}[];
}>;
}
interface CommentPermissionInfo {
@@ -661,7 +661,7 @@ interface Aweme {
comment_list: null;
author_user_id: number;
publish_plus_alienation: PublishPlusAlienation;
geofencing: false[];
geofencing: Array<false>;
enable_comment_sticker_rec: boolean;
xigua_base_info: XiguaBaseInfo;
region: string;
@@ -669,7 +669,7 @@ interface Aweme {
ref_voice_modify_id_list: null;
collect_stat: number;
label_top_text: null;
promotions: false[];
promotions: Array<false>;
group_id: string;
prevent_download: boolean;
nickname_position: null;
@@ -720,11 +720,11 @@ interface Aweme {
relation_labels: null;
mark_largely_following: boolean;
impression_data: {
group_id_list_a: false[];
group_id_list_b: false[];
group_id_list_a: Array<false>;
group_id_list_b: Array<false>;
similar_id_list_a: number[] | null;
similar_id_list_b: number[] | null;
group_id_list_c: false[];
group_id_list_c: Array<false>;
};
boost_status: number;
authentication_token: string;
+1 -1
View File
@@ -16,7 +16,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'http://www.duozhi.com';
const baseUrl = 'http://www.duozhi.com';
const targetUrl: string = new URL(category && category.endsWith('/') ? category : category ? `${category}/` : '', baseUrl).href;
const response = await ofetch(targetUrl);
+3 -3
View File
@@ -111,7 +111,7 @@ interface Post {
postPerm: PostPerm;
showStatus: boolean;
postUser: PostUser;
hintInfos: false[];
hintInfos: Array<false>;
isDisableRepost: boolean;
tagInfos: TagInfo[];
isVoteActivityPost: boolean;
@@ -140,7 +140,7 @@ interface SpecialAdmin {
enterpriseStatus: boolean;
identificationTitle: string;
blueVip: boolean;
talentBoard: false[];
talentBoard: Array<false>;
userTitle: UserTitle;
enterpriseName: string;
}
@@ -169,7 +169,7 @@ export interface SpecialBoardDetail {
pushStatus: boolean;
specialAdmins: SpecialAdmin[];
isContribute: boolean;
post: false[];
post: Array<false>;
isOpenPostEntrance: boolean;
}
+3 -3
View File
@@ -11,8 +11,8 @@ import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
const domain: string = 'www.dydytt.net';
const baseUrl: string = `https://${domain}`;
const domain = 'www.dydytt.net';
const baseUrl = `https://${domain}`;
export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'gndy/dyzz' } = ctx.req.param();
@@ -101,7 +101,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const enclosureUrl: string | undefined = $enclosureEl.attr('href');
if (enclosureUrl) {
const enclosureType: string = 'application/x-bittorrent';
const enclosureType = 'application/x-bittorrent';
const enclosureTitle: string = $enclosureEl.text();
processedItem = {
+2 -2
View File
@@ -14,8 +14,8 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10);
const baseUrl: string = 'https://www.eeo.com.cn';
const apiUrl: string = 'https://app.eeo.com.cn';
const baseUrl = 'https://www.eeo.com.cn';
const apiUrl = 'https://app.eeo.com.cn';
const targetUrl: string = new URL('kuaixun/', baseUrl).href;
const response = await ofetch(apiUrl, {
+2 -2
View File
@@ -126,9 +126,9 @@ interface EventbriteEvent {
url: string;
};
summary: string;
tags: {
tags: Array<{
display_name: string;
}[];
}>;
image: {
url: string;
original: {
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'daily-news' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://www.expats.cz';
const baseUrl = 'https://www.expats.cz';
const targetUrl: string = new URL(`czech-news/${category}`, baseUrl).href;
const response = await ofetch(targetUrl);
+10 -10
View File
@@ -42,11 +42,11 @@ export interface ArticleDetail {
name_ja: string;
};
description: string;
content: {
content: Array<{
page_no: number;
contents: Content[];
text: string;
}[];
}>;
mainCategories: Category;
publishedAt: string;
subCategories: Category[];
@@ -63,7 +63,7 @@ export interface ArticleDetail {
offset: number;
page: number;
limit: number;
results: {
results: Array<{
id: string;
article_type: string;
main_category_ids: string[];
@@ -91,27 +91,27 @@ export interface ArticleDetail {
tweet_id: string;
game_ids: string[];
author_ids: string[];
}[];
}>;
};
authors: {
authors: Array<{
id: number;
icon_url: string;
name_ja: string;
description: string;
relate_urls: any[];
}[];
}>;
redirectUrl: string;
copyright: string;
relatedLinks: {
relatedLinks: Array<{
title: string;
description: null;
url: string;
article: any[];
}[];
}>;
isToc: boolean;
items: {
items: Array<{
status: string;
item_id: string;
item_type: string;
}[];
}>;
}
+12 -12
View File
@@ -10,12 +10,12 @@ export interface UserInfoResponse {
hasAdultContent: boolean;
coverImageUrl: string;
profileLinks: string[];
profileItems: {
profileItems: Array<{
id: string;
type: string;
serviceProvider: string;
videoId: string;
}[];
}>;
isFollowed: boolean;
isSupported: boolean;
isStopped: boolean;
@@ -60,7 +60,7 @@ export interface PostItem {
interface BasicPost {
commentCount: number;
commentList: {
items: {
items: Array<{
body: string;
createdDatetime: string;
id: string;
@@ -68,7 +68,7 @@ interface BasicPost {
isOwn: boolean;
likeCount: number;
parentCommentId: string;
replies: {
replies: Array<{
body: string;
createdDatetime: string;
id: string;
@@ -77,14 +77,14 @@ interface BasicPost {
likeCount: number;
parentCommentId: string;
rootCommentId: string;
}[];
}>;
rootCommentId: string;
user: {
iconUrl: string;
name: string;
userId: string;
};
}[];
}>;
};
coverImageUrl: string | null;
creatorId: string;
@@ -152,13 +152,13 @@ export interface ArticlePost extends BasicPost {
export interface FilePost extends BasicPost {
type: 'file';
body: {
files: {
files: Array<{
extension: string;
id: string;
name: string;
size: number;
url: string;
}[];
}>;
text: string;
};
}
@@ -177,14 +177,14 @@ export interface VideoPost extends BasicPost {
export interface ImagePost extends BasicPost {
type: 'image';
body: {
images: {
images: Array<{
id: string;
originalUrl: string;
thumbnailUrl: string;
width: number;
height: number;
extension: string;
}[];
}>;
text: string;
};
}
@@ -199,11 +199,11 @@ export interface TextPost extends BasicPost {
interface TextBlock {
type: 'p';
text: string;
styles?: {
styles?: Array<{
length: number;
offset: number;
type: 'bold';
}[];
}>;
}
interface HeaderBlock {
+2 -3
View File
@@ -100,9 +100,8 @@ async function parseVideo(body: VideoPost['body']) {
}
async function parseArtile(body: ArticlePost['body']) {
let ret: Array<string> = [];
for (let x = 0; x < body.blocks.length; ++x) {
const b = body.blocks[x];
let ret: string[] = [];
for (const b of body.blocks) {
ret.push('<p>');
switch (b.type) {
+3 -3
View File
@@ -15,8 +15,8 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { id = 'datalist' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'http://www.fangchan.com';
const apiBaseUrl: string = 'http://news.fangchan.com';
const baseUrl = 'http://www.fangchan.com';
const apiBaseUrl = 'http://news.fangchan.com';
const targetUrl: string = new URL(id.endsWith('/') ? id : `${id}/`, baseUrl).href;
const apiUrl: string = new URL(`api/${id.endsWith('/') ? id.replace(/\/$/, '') : id}.json`, apiBaseUrl).href;
@@ -134,7 +134,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
)
).filter((_): _ is DataItem => true);
const author: string = '中房网';
const author = '中房网';
return {
title: `${author} - ${$('div.curmbs a').text()}`,
+4 -4
View File
@@ -18,9 +18,9 @@ interface Plan {
subscribersCount: number;
planPosts: {
totalCount: number;
nodes: {
nodes: Array<{
post: PlanPost;
}[];
}>;
};
}
@@ -82,9 +82,9 @@ export interface PostReelNode {
creator: CreatorFragment;
comments: Comments;
planPosts: {
nodes: {
nodes: Array<{
plan: Plan;
}[];
}>;
};
favoritesCount: number;
contentData: {
+1 -1
View File
@@ -80,7 +80,7 @@ async function handler(ctx) {
const items = firstOutbox.orderedItems;
const itemResolvers = [] as Promise<any>[];
const itemResolvers = [] as Array<Promise<any>>;
for (const item of items) {
if (!['Announce', 'Create', 'Update'].includes(item.type)) {
+1 -1
View File
@@ -52,7 +52,7 @@ async function handler(ctx: Context): Promise<Data> {
return {
title: `${profile.data.name}'s subscriptions`,
item: (<Exclude<Subscription, InboxSubscription>[]>subscriptions.data.filter((i) => !isInbox(i) && !(isFeed(i) && !!i.feeds.errorAt))).map((subscription) => {
item: (subscriptions.data.filter((i) => !isInbox(i) && !(isFeed(i) && !!i.feeds.errorAt)) as Array<Exclude<Subscription, InboxSubscription>>).map((subscription) => {
if (isList(subscription)) {
return {
title: subscription.lists.title,
+1 -1
View File
@@ -42,7 +42,7 @@ async function handler() {
? `Status: FA Server Online <br> Guests: ${data.online.guests} <br> Registered: ${data.online.registered} <br> Other: ${data.online.other} <br> Total: ${data.online.total} <br> FA Server Time: ${data.fa_server_time} <br> FA Server Time at: ${data.fa_server_time_at}`
: 'FA Server Offline';
const items: { title: string; link: string; description: string }[] = [
const items: Array<{ title: string; link: string; description: string }> = [
{
title: `Status: ${Object.keys(data)[0]}`,
link: 'https://www.furaffinity.net/',
+1 -1
View File
@@ -104,7 +104,7 @@ async function handler(ctx) {
Favorite Animal: ${favorites_animal} <br> Favorite Website: ${favorites_website} <br> Favorite Food: ${favorites_food} <br> <br> Contact Information: <br> ${contact_result}
Watchers Count: ${watchers_count} <br> Watching Count: ${watching_count} `;
const items: { title: string; link: string; description: string }[] = [
const items: Array<{ title: string; link: string; description: string }> = [
{
title: `${data.name}'s User Profile`,
link: `https://www.furaffinity.net/user/${username}`,
+3 -3
View File
@@ -43,9 +43,9 @@ export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://news.gamebase.com.tw';
const baseUrl = 'https://news.gamebase.com.tw';
const targetUrl: string = new URL(`news${category === 'all' ? '' : `/newslist?type=${category}`}`, baseUrl).href;
const apiBaseUrl: string = 'https://api.gamebase.com.tw';
const apiBaseUrl = 'https://api.gamebase.com.tw';
const apiUrl: string = new URL('api/news/getNewsList', apiBaseUrl).href;
const response = await ofetch(apiUrl, {
@@ -69,7 +69,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const linkUrl: string | undefined = item.news_no ? `news/detail/${item.news_no}` : undefined;
const categories: string[] = [item.system];
const authors: DataItem['author'] = item.nickname;
const guid: string = `gamebase-news-${item.news_no}`;
const guid = `gamebase-news-${item.news_no}`;
const image: string | undefined = item.news_img;
const updated: number | string = item.updated ?? pubDate;
+1 -1
View File
@@ -14,7 +14,7 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10);
const baseUrl: string = 'https://www.gaoyu.me';
const baseUrl = 'https://www.gaoyu.me';
const targetUrl: string = new URL('blog', baseUrl).href;
const response = await ofetch(targetUrl);
+2 -2
View File
@@ -43,7 +43,7 @@ interface Content {
entityMap: { [key: string]: Entity };
}
const imageBaseUrl: string = 'https://image.gcores.com';
const imageBaseUrl = 'https://image.gcores.com';
const STYLES: Readonly<Record<string, Style>> = {
BOLD: { fontWeight: 'bold' },
@@ -167,7 +167,7 @@ const parseBlock = (block: Block, entityMap: Readonly<Record<string, Entity>>):
// Group ranges by offset and length
const groupedRangesMap = new Map<string, { offset: number; length: number; styles: Style[]; entities: Entity[] }>();
const groupedRanges: { offset: number; length: number; styles: Style[]; entities: Entity[] }[] = [];
const groupedRanges: Array<{ offset: number; length: number; styles: Style[]; entities: Entity[] }> = [];
for (const range of combinedRanges) {
const rangeKey = `${range.offset}-${range.length}`;
+5 -5
View File
@@ -8,11 +8,11 @@ import { parseDate } from '@/utils/parse-date';
import { parseContent } from './parser';
import { renderDescription } from './templates/description';
const baseUrl: string = 'https://www.gcores.com';
const imageBaseUrl: string = 'https://image.gcores.com';
const audioBaseUrl: string = 'https://alioss.gcores.com';
const baseUrl = 'https://www.gcores.com';
const imageBaseUrl = 'https://image.gcores.com';
const audioBaseUrl = 'https://alioss.gcores.com';
const types: Set<string> = new Set(['radios', 'articles', 'news', 'videos', 'talks']);
const types = new Set<string>(['radios', 'articles', 'news', 'videos', 'talks']);
const processItems = async (limit: number, query: any, apiUrl: string, targetUrl: string): Promise<Data> => {
const response = await ofetch(apiUrl, {
@@ -61,7 +61,7 @@ const processItems = async (limit: number, query: any, apiUrl: string, targetUrl
]
: undefined;
const guid: string = `gcores-${item.id}`;
const guid = `gcores-${item.id}`;
const image: string | undefined = (attributes.cover ?? attributes.thumb) ? new URL(attributes.cover ?? attributes.thumb, imageBaseUrl).href : undefined;
const updated: number | string = pubDate;
+3 -3
View File
@@ -51,7 +51,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'repositories' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
const baseUrl: string = 'https://gitstar-ranking.com';
const baseUrl = 'https://gitstar-ranking.com';
const targetUrl: string = new URL(category, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -64,7 +64,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
.map((el): Element => {
const $el: Cheerio<Element> = $(el);
const stargazersCount: number = Number($el.find('span.stargazers_count').text()?.trim());
const stargazersCount = Number($el.find('span.stargazers_count').text()?.trim());
const title: string = $el.find('span.hidden-xs').text()?.trim();
const image: string | undefined = $el.find('img.avatar_image_big').attr('src');
const language: string | undefined = $el.find('div.repo-language').text()?.trim();
@@ -83,7 +83,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
});
const linkUrl: string | undefined = $el.attr('href');
const categories: string[] = language ? [language] : [];
const guid: string = `gitstar-ranking-${title}-${stargazersCount}`;
const guid = `gitstar-ranking-${title}-${stargazersCount}`;
const processedItem: DataItem = {
title: `${title}${stargazersCount}`,
+2 -2
View File
@@ -12,7 +12,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { year = new Date().getFullYear() } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://id-info.jihs.go.jp';
const baseUrl = 'https://id-info.jihs.go.jp';
const targetUrl: string = new URL(`surveillance/idwr/jp/idwr/${year}/`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -52,7 +52,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const enclosureUrl: string | undefined = linkUrl ? new URL(linkUrl, targetUrl).href : undefined;
if (enclosureUrl) {
const enclosureType: string = `application/${enclosureUrl.split(/\./).pop()}`;
const enclosureType = `application/${enclosureUrl.split(/\./).pop()}`;
const enclosureTitle: string = $enclosureEl.text();
processedItem = {
+2 -2
View File
@@ -177,8 +177,8 @@ const gdgov = async (info, ctx) => {
const zcjdlink = 'https://zcjd.cloud.gd.gov.cn/api/home/article' + idlink.search;
const response = await got(zcjdlink);
const data = response.data.data;
for (let index = 0; index < data.jie_du_items.length; index++) {
data.jie_du_items[index].jd_content = data.jie_du_items[index].jd_content.replaceAll(/((\n {4})|(\n))/g, '</p><p style="font-size: 16px;line-height: 32px;text-indent: 2em;">');
for (const item of data.jie_du_items) {
item.jd_content = item.jd_content.replaceAll(/((\n {4})|(\n))/g, '</p><p style="font-size: 16px;line-height: 32px;text-indent: 2em;">');
}
return {
+2 -2
View File
@@ -14,7 +14,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'ywdt/hjyw' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '15', 10);
const baseUrl: string = 'https://nnsa.mee.gov.cn';
const baseUrl = 'https://nnsa.mee.gov.cn';
const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -54,7 +54,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const title: string = $$('meta[name="ArticleTitle"]').attr('content') ?? item.title;
const description: string | undefined = $$('div.Custom_UnionStyle').html() ?? undefined;
const pubDateStr: string | undefined = $$('meta[name="PubDate"]').attr('content');
const categoryEls: Cheerio<Element>[] = [$$('meta[name="ColumnName"]'), $$('meta[name="ColumnType"]'), $$('meta[name="ContentSource"]'), $$('meta[name="source"]')];
const categoryEls: Array<Cheerio<Element>> = [$$('meta[name="ColumnName"]'), $$('meta[name="ColumnType"]'), $$('meta[name="ContentSource"]'), $$('meta[name="source"]')];
const categories: string[] = [...new Set(categoryEls.map((el) => $$(el)?.attr('content') ?? '').filter(Boolean))];
const authors: DataItem['author'] = [$$('meta[name="Author"]'), $$('meta[name="author"]'), $$('meta[name="source"]')]
.filter((authorEl) => $$(authorEl).attr('content'))
+3 -3
View File
@@ -14,7 +14,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'gzdt' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'http://www.gjs.moa.gov.cn';
const baseUrl = 'http://www.gjs.moa.gov.cn';
const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -86,7 +86,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const enclosureUrl: string | undefined = $enclosureEl.attr('href');
if (enclosureUrl) {
const enclosureType: string = `application/${enclosureUrl.split('.').pop()}`;
const enclosureType = `application/${enclosureUrl.split('.').pop()}`;
const enclosureTitle: string = $enclosureEl.text();
processedItem = {
@@ -106,7 +106,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
)
).filter((_): _ is DataItem => true);
const author: string = '中华人民共和国农业农村部国际合作司';
const author = '中华人民共和国农业农村部国际合作司';
const description: string = $('meta[name="ColumnName"]').attr('content') ?? '';
return {
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'jiaotongyaowen' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'https://www.mot.gov.cn';
const baseUrl = 'https://www.mot.gov.cn';
const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -13,7 +13,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { category, id } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
const baseUrl: string = 'http://load.grainoil.com.cn';
const baseUrl = 'http://load.grainoil.com.cn';
const targetUrl: string = new URL(`${category}/${id}.jspx`, baseUrl).href;
const response = await ofetch(targetUrl);
+1 -1
View File
@@ -56,7 +56,7 @@ async function handler(/* ctx*/): Promise<Data> {
item.description = content('.post-body').html();
return item;
})
) as Promise<DataItem>[]
) as Array<Promise<DataItem>>
);
return {
+2 -2
View File
@@ -15,7 +15,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const { id = 'tzgg' } = ctx.req.param();
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10);
const baseUrl: string = 'https://hitgs.hit.edu.cn';
const baseUrl = 'https://hitgs.hit.edu.cn';
const targetUrl: string = new URL(`${id}/list.htm`, baseUrl).href;
const response = await ofetch(targetUrl);
@@ -94,7 +94,7 @@ export const handler = async (ctx: Context): Promise<Data> => {
const enclosureUrl: string | undefined = $enclosureEl.attr('href');
if (enclosureUrl) {
const enclosureType: string = `application/${enclosureUrl.split(/\./).pop() || 'octet-stream'}`;
const enclosureType = `application/${enclosureUrl.split(/\./).pop() || 'octet-stream'}`;
const enclosureTitle: string | undefined = $enclosureEl.attr('sudyfile-attr')?.match(/'title':'(.*?)'/)?.[1];
processedItem = {
+2 -2
View File
@@ -20,7 +20,7 @@ async function handler() {
return Object.values(response);
})
)
).flat() as {
).flat() as Array<{
manifest: {
name: string;
};
@@ -32,7 +32,7 @@ async function handler() {
topics?: string[];
last_updated: string;
last_fetched: number;
}[];
}>;
return {
title: 'HACS Repositories',
+1 -1
View File
@@ -33,7 +33,7 @@ interface Paper {
id: string;
summary: string;
upvotes: number;
authors: { name: string }[];
authors: Array<{ name: string }>;
}
interface DailyPaperItem {
+1 -1
View File
@@ -75,7 +75,7 @@ export const route: Route = {
throw new Error(`Expected '${dataKey}' property not found in pageProps for category: ${category || 'home'}`);
}
const rawDataArray: (HomePostItem | NewsDataItem)[] = (() => {
const rawDataArray: Array<HomePostItem | NewsDataItem> = (() => {
const data = (pageProps as any)[dataKey];
return Array.isArray(data) ? data : [];
})();
+4 -4
View File
@@ -10,8 +10,8 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise<Data> => {
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10);
const baseUrl: string = 'https://www.ifanr.com';
const apiBaseUrl: string = 'https://sso.ifanr.com';
const baseUrl = 'https://www.ifanr.com';
const apiBaseUrl = 'https://sso.ifanr.com';
const targetUrl: string = new URL('digest', baseUrl).href;
const apiUrl: string = new URL('api/v5/wp/buzz', apiBaseUrl).href;
@@ -30,8 +30,8 @@ export const handler = async (ctx: Context): Promise<Data> => {
const title: string = item.post_title;
const description: string = item.post_content;
const pubDate: number | string = item.created_at;
const linkUrl: string = `digest/${item.post_id}`;
const guid: string = `ifanr-digest-${item.post_id}`;
const linkUrl = `digest/${item.post_id}`;
const guid = `ifanr-digest-${item.post_id}`;
const updated: number | string = item.updated_at ?? pubDate;
const processedItem: DataItem = {
+4 -4
View File
@@ -1,15 +1,15 @@
import type { DataItem } from '@/types';
import { parseDate } from '@/utils/parse-date';
const author: string = '趣集';
const language: string = 'zh-CN';
const rootUrl: string = 'https://n.ifun.cool';
const author = '趣集';
const language = 'zh-CN';
const rootUrl = 'https://n.ifun.cool';
const processItems: (items: any[], limit: number) => DataItem[] = (items: any[], limit: number) =>
items.slice(0, limit).map((item): DataItem => {
const title: string = item.title;
const description: string = item.content;
const guid: string = `ifun-n-${item.id}`;
const guid = `ifun-n-${item.id}`;
const author: DataItem['author'] = item.author;

Some files were not shown because too many files have changed in this diff Show More