mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-08-31 01:01:11 +08:00
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:
+12
-1
@@ -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
@@ -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) => {
|
||||
|
||||
@@ -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
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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) => (
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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', {
|
||||
|
||||
@@ -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 '';
|
||||
|
||||
@@ -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}">`;
|
||||
}
|
||||
}
|
||||
// 视频封面
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}[];
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}[];
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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('/')) {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -126,9 +126,9 @@ interface EventbriteEvent {
|
||||
url: string;
|
||||
};
|
||||
summary: string;
|
||||
tags: {
|
||||
tags: Array<{
|
||||
display_name: string;
|
||||
}[];
|
||||
}>;
|
||||
image: {
|
||||
url: string;
|
||||
original: {
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()}`,
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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/',
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}`;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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'))
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -33,7 +33,7 @@ interface Paper {
|
||||
id: string;
|
||||
summary: string;
|
||||
upvotes: number;
|
||||
authors: { name: string }[];
|
||||
authors: Array<{ name: string }>;
|
||||
}
|
||||
|
||||
interface DailyPaperItem {
|
||||
|
||||
@@ -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 : [];
|
||||
})();
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user