mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-10-16 21:02:57 +08:00
b4ae78140d
Merge current master while retaining the completed route review and retired service removals. Keep upstream source migrations and new feed functionality, including the ACEA API, Xiaomi data helpers, Yahoo Finance topic helper, Bilibili list URLs, Douban IP locations, and Douyin live-stream handling. Resolve overlapping changes without losing existing limit validation, bounded detail requests, stable item metadata, or route configuration corrections. Keep RSS image MIME inference and explicit media precedence alongside upstream attachment extraction, emitting a single enclosure per item.
477 lines
11 KiB
TypeScript
477 lines
11 KiB
TypeScript
import type { Context } from 'hono';
|
|
|
|
// Make sure it's synchronise with scripts/workflow/data.ts
|
|
// and lib/routes/rsshub/routes.ts
|
|
export type Category =
|
|
| 'popular'
|
|
| 'social-media'
|
|
| 'new-media'
|
|
| 'traditional-media'
|
|
| 'bbs'
|
|
| 'blog'
|
|
| 'programming'
|
|
| 'design'
|
|
| 'live'
|
|
| 'multimedia'
|
|
| 'picture'
|
|
| 'anime'
|
|
| 'program-update'
|
|
| 'university'
|
|
| 'forecast'
|
|
| 'travel'
|
|
| 'shopping'
|
|
| 'game'
|
|
| 'reading'
|
|
| 'government'
|
|
| 'study'
|
|
| 'journal'
|
|
| 'finance'
|
|
| 'sport'
|
|
| 'other';
|
|
|
|
// rss
|
|
export type DataItem = {
|
|
title: string;
|
|
description?: string | null;
|
|
pubDate?: number | string | Date | null;
|
|
link?: string;
|
|
category?: string[] | string;
|
|
author?:
|
|
| string
|
|
| Array<{
|
|
name: string;
|
|
url?: string;
|
|
avatar?: string;
|
|
}>;
|
|
doi?: string;
|
|
guid?: string;
|
|
id?: string;
|
|
content?: {
|
|
html?: string | null;
|
|
text?: string | null;
|
|
};
|
|
summary?: string;
|
|
image?: string;
|
|
banner?: string;
|
|
updated?: number | string | Date;
|
|
language?: Language;
|
|
enclosure_url?: string;
|
|
enclosure_type?: string;
|
|
enclosure_title?: string;
|
|
enclosure_length?: number;
|
|
itunes_duration?: number | string;
|
|
itunes_item_image?: string;
|
|
media?: Record<string, Record<string, string>>;
|
|
upvotes?: number;
|
|
downvotes?: number;
|
|
comments?: number;
|
|
attachments?: Array<{
|
|
url: string;
|
|
mime_type: string;
|
|
title?: string;
|
|
size_in_bytes?: number;
|
|
duration_in_seconds?: number;
|
|
}>;
|
|
// oxlint-disable-next-line anti-slop/no-unsafe-dictionary-type
|
|
_extra?: Record<string, any> & {
|
|
links?: Array<{
|
|
url: string;
|
|
type: string;
|
|
content_html?: string;
|
|
}>;
|
|
};
|
|
};
|
|
|
|
export type Data = {
|
|
title: string;
|
|
description?: string | null;
|
|
link?: string;
|
|
item?: DataItem[];
|
|
allowEmpty?: boolean;
|
|
/** Default publication-date sorting preference; the common sorted parameter takes precedence. */
|
|
sortItems?: boolean;
|
|
image?: string;
|
|
author?: string;
|
|
language?: Language;
|
|
feedLink?: string;
|
|
lastBuildDate?: string;
|
|
itunes_author?: string;
|
|
itunes_category?: string;
|
|
itunes_explicit?: string | boolean;
|
|
id?: string;
|
|
icon?: string;
|
|
logo?: string;
|
|
atomlink?: string;
|
|
ttl?: number;
|
|
};
|
|
|
|
export type Language =
|
|
| 'af'
|
|
| 'ar-DZ'
|
|
| 'ar-IQ'
|
|
| 'ar-KW'
|
|
| 'ar-MA'
|
|
| 'ar-SA'
|
|
| 'ar-TN'
|
|
| 'be'
|
|
| 'bg'
|
|
| 'ca'
|
|
| 'cs'
|
|
| 'da'
|
|
| 'de'
|
|
| 'de-at'
|
|
| 'de-ch'
|
|
| 'de-de'
|
|
| 'de-li'
|
|
| 'de-lu'
|
|
| 'el'
|
|
| 'en'
|
|
| 'en-au'
|
|
| 'en-bz'
|
|
| 'en-ca'
|
|
| 'en-gb'
|
|
| 'en-ie'
|
|
| 'en-jm'
|
|
| 'en-nz'
|
|
| 'en-ph'
|
|
| 'en-tt'
|
|
| 'en-us'
|
|
| 'en-za'
|
|
| 'en-zw'
|
|
| 'es'
|
|
| 'es-ar'
|
|
| 'es-bo'
|
|
| 'es-cl'
|
|
| 'es-co'
|
|
| 'es-cr'
|
|
| 'es-do'
|
|
| 'es-ec'
|
|
| 'es-es'
|
|
| 'es-gt'
|
|
| 'es-hn'
|
|
| 'es-mx'
|
|
| 'es-ni'
|
|
| 'es-pa'
|
|
| 'es-pe'
|
|
| 'es-pr'
|
|
| 'es-py'
|
|
| 'es-sv'
|
|
| 'es-uy'
|
|
| 'es-ve'
|
|
| 'et'
|
|
| 'eu'
|
|
| 'fi'
|
|
| 'fo'
|
|
| 'fr'
|
|
| 'fr-be'
|
|
| 'fr-ca'
|
|
| 'fr-ch'
|
|
| 'fr-fr'
|
|
| 'fr-lu'
|
|
| 'fr-mc'
|
|
| 'ga'
|
|
| 'gd'
|
|
| 'gl'
|
|
| 'haw'
|
|
| 'hi'
|
|
| 'hr'
|
|
| 'hu'
|
|
| 'id'
|
|
| 'in'
|
|
| 'is'
|
|
| 'it'
|
|
| 'it-ch'
|
|
| 'it-it'
|
|
| 'ja'
|
|
| 'ko'
|
|
| 'mk'
|
|
| 'mul'
|
|
| 'ne'
|
|
| 'nl'
|
|
| 'nl-be'
|
|
| 'nl-nl'
|
|
| 'no'
|
|
| 'pl'
|
|
| 'pt'
|
|
| 'pt-br'
|
|
| 'pt-pt'
|
|
| 'ro'
|
|
| 'ro-mo'
|
|
| 'ro-ro'
|
|
| 'ru'
|
|
| 'ru-mo'
|
|
| 'ru-ru'
|
|
| 'sk'
|
|
| 'sl'
|
|
| 'sq'
|
|
| 'sr'
|
|
| 'sv'
|
|
| 'sv-fi'
|
|
| 'sv-se'
|
|
| 'th'
|
|
| 'tr'
|
|
| 'uk'
|
|
| 'vi'
|
|
| 'zh'
|
|
| 'zh-CN'
|
|
| 'zh-HK'
|
|
| 'zh-TW'
|
|
| 'other';
|
|
|
|
// namespace
|
|
interface NamespaceItem {
|
|
/**
|
|
* The human-readable name of the namespace, should be the same as the secondary domain of the main website,
|
|
* which will be used as the level 2 heading in the documentation
|
|
*/
|
|
name: string;
|
|
|
|
/**
|
|
* The website URL without protocol that corresponds
|
|
*/
|
|
url?: string;
|
|
|
|
/**
|
|
* The classification of the namespace, which will be written into the corresponding classification document
|
|
*/
|
|
categories?: Category[];
|
|
|
|
/**
|
|
* Hints and additional explanations for users using this namespace, it will be inserted into the documentation
|
|
*/
|
|
description?: string;
|
|
|
|
/**
|
|
* Main Language of the namespace
|
|
*/
|
|
lang?: Language;
|
|
}
|
|
|
|
interface Namespace extends NamespaceItem {
|
|
/** Documentation in languages other than English, it will be used to generate multilingual documents */
|
|
ja?: NamespaceItem;
|
|
/** Documentation in languages other than English, it will be used to generate multilingual documents */
|
|
zh?: NamespaceItem;
|
|
/** Documentation in languages other than English, it will be used to generate multilingual documents */
|
|
'zh-TW'?: NamespaceItem;
|
|
}
|
|
|
|
export type { Namespace };
|
|
|
|
export enum ViewType {
|
|
Articles = 0,
|
|
SocialMedia = 1,
|
|
Pictures = 2,
|
|
Videos = 3,
|
|
Audios = 4,
|
|
Notifications = 5,
|
|
}
|
|
|
|
// route
|
|
interface RouteItem {
|
|
/**
|
|
* The route path, using [Hono routing](https://hono.dev/api/routing) syntax
|
|
*/
|
|
path: string | string[];
|
|
|
|
/**
|
|
* The human-readable name of the route, which will be used as the level 3 heading in the documentation
|
|
* and radar rule title (can be overridden by `RadarRule[].title`)
|
|
*/
|
|
name: string;
|
|
|
|
/**
|
|
* The website URL without protocol that corresponds
|
|
*/
|
|
url?: string;
|
|
|
|
/**
|
|
* The GitHub handle of the people responsible for maintaining this route
|
|
*/
|
|
maintainers: string[];
|
|
|
|
/**
|
|
* The handler function of the route
|
|
*/
|
|
handler: (ctx: Context) => Promise<Data | null | Response | void> | Data | null | Response | void;
|
|
|
|
/**
|
|
* An example URL of the route
|
|
*/
|
|
example: string;
|
|
|
|
/**
|
|
* The description of the route parameters
|
|
*/
|
|
parameters?: Record<
|
|
string,
|
|
| string
|
|
| {
|
|
description: string;
|
|
default?: string;
|
|
options?: Array<{
|
|
value: string;
|
|
label: string;
|
|
}>;
|
|
}
|
|
>;
|
|
|
|
/**
|
|
* Hints and additional explanations for users using this route, it will be appended after the route component, supports markdown
|
|
*/
|
|
description?: string;
|
|
|
|
/**
|
|
* The classification of the route, which will be written into the corresponding classification documentation
|
|
*/
|
|
categories?: Category[];
|
|
|
|
/**
|
|
* Special features of the route, such as what configuration items it depends on, whether it is strict anti-crawl, whether it supports a certain function and so on
|
|
*/
|
|
features?: {
|
|
/** The extra configuration items required by the route */
|
|
requireConfig?:
|
|
| Array<{
|
|
/** The environment variable name */
|
|
name: string;
|
|
/** Whether the environment variable is optional */
|
|
optional?: boolean;
|
|
/** The description of the environment variable */
|
|
description: string;
|
|
}>
|
|
| false;
|
|
|
|
/** set to `true` if the feed uses browser automation */
|
|
requirePuppeteer?: boolean;
|
|
|
|
/** set to `true` if the target website has an anti-crawler mechanism */
|
|
antiCrawler?: boolean;
|
|
|
|
/** set to `true` if the feed has a radar rule */
|
|
supportRadar?: boolean;
|
|
|
|
/** Set to `true` if the feed supports BitTorrent */
|
|
supportBT?: boolean;
|
|
|
|
/** Set to `true` if the feed supports podcasts */
|
|
supportPodcast?: boolean;
|
|
|
|
/** Set to `true` if the feed supports Sci-Hub */
|
|
supportScihub?: boolean;
|
|
|
|
/** Set to `true` if this feed is not safe for work */
|
|
nsfw?: boolean;
|
|
};
|
|
|
|
/**
|
|
* The [RSSHub-Radar](https://github.com/DIYgod/RSSHub-Radar) rule of the route
|
|
*/
|
|
radar?: RadarItem[];
|
|
|
|
/**
|
|
* The [Follow](https://github.com/RSSNext/follow) default view of the route, default to `ViewType.Articles`
|
|
*/
|
|
view?: ViewType;
|
|
}
|
|
|
|
export interface Route extends RouteItem {
|
|
ja?: Partial<RouteItem>;
|
|
zh?: Partial<RouteItem>;
|
|
'zh-TW'?: Partial<RouteItem>;
|
|
}
|
|
|
|
// radar
|
|
export type RadarItem = {
|
|
/**
|
|
* The overwriting title of the radar rule
|
|
*/
|
|
title?: string;
|
|
|
|
/**
|
|
* The URL path to the corresponding documentation
|
|
*/
|
|
docs?: string;
|
|
|
|
/**
|
|
* The source URL path of the radar rule
|
|
* @see https://docs.rsshub.app/joinus/new-radar#source
|
|
*/
|
|
source: string[];
|
|
|
|
/**
|
|
* The target RSSHub subscription URL path of the radar rule
|
|
*
|
|
* Will use RouteItem.path if not specified
|
|
* @see https://docs.rsshub.app/joinus/new-radar#target
|
|
*
|
|
* Using `target` as a function is deprecated in RSSHub-Radar 2.0.19,
|
|
* and the generated radar rules ignore it and use RouteItem.path instead
|
|
* @see https://github.com/DIYgod/RSSHub-Radar/commit/5a97647f900bb2bca792787a322b2b1ca512e40b#diff-f84e3c1e16af314bc4ed7c706d7189844663cde9b5142463dc5c0db34c2e8d54L10
|
|
* @see https://github.com/DIYgod/RSSHub-Radar/issues/692
|
|
*/
|
|
target?:
|
|
| string
|
|
| ((
|
|
/** The parameters matched from the `source` field */
|
|
params: any,
|
|
/** The current webpage URL string */
|
|
url: string,
|
|
/** @deprecated Temporary removed @see https://github.com/DIYgod/RSSHub-Radar/commit/e6079ea1a8c96e89b1b2c2aa6d13c7967788ca3b */
|
|
document: Document
|
|
) => string);
|
|
};
|
|
|
|
export type RadarDomain = {
|
|
_name: string;
|
|
} & {
|
|
[subdomain: string]: RadarItem[];
|
|
};
|
|
|
|
export interface APIRoute {
|
|
/**
|
|
* The route path, using [Hono routing](https://hono.dev/api/routing) syntax
|
|
*/
|
|
path: string;
|
|
|
|
/**
|
|
* The GitHub handle of the people responsible for maintaining this route
|
|
*/
|
|
maintainers: string[];
|
|
|
|
/**
|
|
* The handler function of the route
|
|
*/
|
|
handler: (ctx: Context) =>
|
|
| Promise<{
|
|
code: number;
|
|
message?: string;
|
|
data?: any;
|
|
}>
|
|
| {
|
|
code: number;
|
|
message?: string;
|
|
data?: any;
|
|
};
|
|
|
|
/**
|
|
* The description of the route parameters
|
|
*/
|
|
parameters?: Record<
|
|
string,
|
|
{
|
|
description: string;
|
|
default?: string;
|
|
options?: Array<{
|
|
value: string;
|
|
label: string;
|
|
}>;
|
|
}
|
|
>;
|
|
|
|
/**
|
|
* Hints and additional explanations for users using this route, it will be appended after the route component, supports markdown
|
|
*/
|
|
description?: string;
|
|
}
|