@follow-app/client-sdk
Version:
TypeScript client SDK for Follow RSS Server API
1,830 lines (1,829 loc) • 84.7 kB
TypeScript
import { ACHIEVEMENTS_TYPES, FEATURE_NAMES, FeatureName, FeedViewType, FeedViewType as FeedViewType$1, SETTINGS_TABS } from "@folo-services/constants";
import { ExceptionCodeMap } from "@folo-services/exceptions";
import { ActionItem, ActionsModel, SettingsModel as SettingsModel$1, achievements, collectionsOpenAPISchema, entries, entriesOpenAPISchema, featureFlags, feedAnalytics, feeds, inboxes, inboxesEntriesOpenAPISchema, invitations, languageSchema, levels, lists, listsSubscriptions, messaging, settings, subscriptions, userFeatureOverrides, users, wallets } from "@folo-services/drizzle";
import { InferInsertModel, InferSelectModel } from "drizzle-orm";
import z$1, { z } from "zod";
import { FeedOpenApiSchema, InboxOpenApiSchema, ListOpenApiSchema } from "@folo-services/shared";
//#region src/types/api.d.ts
/**
* Standard Follow API response wrapper
*/
interface FollowAPIResponse<T = any> {
code: number;
data: T;
message?: string;
}
/**
* Error response from Follow API
*/
interface FollowAPIErrorResponse {
code: number;
message: string;
data?: any;
}
/**
* Generic type for requests that only contain an id parameter
*/
interface IdRequest {
id: string;
}
/**
* Generic type for requests that only contain a feedId parameter
*/
interface FeedIdRequest {
feedId: string;
}
/**
* Generic type for requests that only contain a listId parameter
*/
interface ListIdRequest {
listId: string;
}
/**
* Generic type for requests that only contain a userId parameter
*/
interface UserIdRequest {
userId: string;
}
/**
* Generic type for requests that only contain an entryId parameter
*/
interface EntryIdRequest {
entryId: string;
}
/**
* HTTP methods supported by the client
*/
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
/**
* Request content types
*/
type RequestContentType = "json" | "formData" | "text" | "blob" | "arrayBuffer";
/**
* Response content types
*/
type ResponseContentType = "json" | "text" | "blob" | "arrayBuffer" | "stream";
/**
* Request options for API calls
*/
interface RequestOptions {
method?: HTTPMethod;
headers?: Record<string, string>;
body?: unknown;
query?: Record<string, string | number | boolean>;
timeout?: number;
signal?: AbortSignal;
requestType?: RequestContentType;
}
/**
* Client configuration options
*/
interface ClientConfig {
baseURL: string;
timeout?: number;
headers?: Record<string, string>;
credentials?: RequestCredentials;
fetch?: typeof fetch;
}
/**
* Pagination parameters
*/
interface PaginationParams {
page?: number;
limit?: number;
before?: string;
after?: string;
}
/**
* Pagination response
*/
interface PaginationResponse<T> {
data: T[];
pagination: {
page: number;
limit: number;
total: number;
hasMore: boolean;
};
}
//#endregion
//#region src/types/date-serialization.d.ts
/**
* Utility types for handling Date to ISO string serialization in HTTP JSON responses
*/
type DateISOString = string;
/**
* Recursively converts Date types to DateISOString for JSON serialization
* This handles the fact that Date objects are serialized as ISO strings in HTTP JSON responses
*/
type DateToString<T> = T extends Date ? DateISOString : T extends (infer U)[] ? DateToString<U>[] : T extends Array<infer U> ? Array<DateToString<U>> : T extends Record<string, any> ? T extends ((...args: any[]) => any) ? T : { [K in keyof T]: DateToString<T[K]> } : T;
/**
* Converts Drizzle InferSelectModel Date types to DateISOString for HTTP responses
* Use this for types that will be sent over HTTP as JSON
*/
type SerializedModel<T> = DateToString<T>;
/**
* Converts Drizzle InferInsertModel Date types to DateISOString for HTTP requests
* Use this for types that will be received from HTTP as JSON
*/
type SerializedInsertModel<T> = DateToString<T>;
/**
* Helper type for API responses that contain serialized models
*/
type ApiResponse<T> = SerializedModel<T>;
/**
* Helper type for API requests that contain serialized models
*/
type ApiRequest<T> = SerializedInsertModel<T>;
//#endregion
//#region src/types/errors.d.ts
/**
* Base error class for all Follow API errors
*/
declare class FollowAPIError extends Error {
status: number;
code?: string | undefined;
data?: any | undefined;
constructor(message: string, status: number, code?: string | undefined, data?: any | undefined);
}
declare class NetworkError extends Error {
constructor(message: string);
}
/**
* Authentication error for Follow API
*/
declare class FollowAuthError extends FollowAPIError {
constructor(message?: string, data?: any);
}
/**
* Validation error for Follow API requests
*/
declare class FollowValidationError extends FollowAPIError {
validationErrors: any[];
constructor(message: string, validationErrors: any[]);
}
/**
* Network timeout error
*/
declare class FollowTimeoutError extends FollowAPIError {
constructor(message?: string);
}
//#endregion
//#region src/types/response.d.ts
/**
* Standard API response structure for Follow Server
* All API responses follow this consistent format
*/
interface ResponseStruct<T = any> {
/**
* Response code
* 0 = success
* Non-zero = error code (matches ExceptionCodes)
*/
code: number;
/**
* Response message
* Usually contains error message when code !== 0
*/
message?: string;
/**
* Response data payload
* Contains actual response data when code === 0
*/
data?: T;
}
/**
* Successful API response with data
*/
interface SuccessResponse<T = any> extends ResponseStruct<T> {
code: 0;
data: T;
}
type ExtractResponseData<T> = T extends ResponseStruct<infer U> ? U : never;
/**
* Error API response
*/
interface ErrorResponse extends ResponseStruct<never> {
code: number;
message: string;
data?: any;
}
/**
* Paginated response structure
*/
interface PaginatedData<T = any> {
items: T[];
total: number;
page?: number;
limit?: number;
hasMore?: boolean;
}
/**
* Paginated API response
*/
type PaginatedResponse<T = any> = SuccessResponse<PaginatedData<T>>;
/**
* Empty success response (for operations that don't return data)
*/
type EmptyResponse = SuccessResponse<null>;
//#endregion
//#region src/client/interceptors.d.ts
/**
* Base context object shared by all interceptors
*/
interface BaseInterceptorContext {
url: string;
options: RequestOptions;
}
/**
* Context object passed to request interceptors
*/
interface RequestInterceptorContext extends BaseInterceptorContext {}
/**
* Context object passed to response interceptors
*/
interface ResponseInterceptorContext extends BaseInterceptorContext {
response: Response;
}
/**
* Context object passed to error interceptors
*/
interface ErrorInterceptorContext extends BaseInterceptorContext {
response: Response | null;
error: Error;
}
/**
* Request interceptor function type
*/
type RequestInterceptor = (ctx: RequestInterceptorContext) => Promise<{
url: string;
options: RequestOptions;
}> | {
url: string;
options: RequestOptions;
};
/**
* Response interceptor function type
*/
type ResponseInterceptor = (ctx: ResponseInterceptorContext) => Promise<Response> | Response;
/**
* Error interceptor function type
*/
type ErrorInterceptor = (ctx: ErrorInterceptorContext) => Promise<Error | void> | Error | void;
/**
* Interceptor manager for handling request/response middleware
*/
//#endregion
//#region src/shared/define-module.d.ts
/**
* Route definition with type annotations
*/
interface RouteDefinition<TInput = any, TResponse = any> {
method: HTTPMethod;
path: string;
params?: readonly string[];
/** Fields that should be sent as query parameters */
query?: readonly string[];
/** Fields that should be sent as request body */
body?: readonly string[];
input?: TInput;
response?: TResponse;
requestType?: RequestContentType;
responseType?: ResponseContentType;
}
/**
* Nested routes structure - supports any depth of nesting
*/
type NestedRoutes = {
[key: string]: RouteDefinition | NestedRoutes;
};
/**
* Module definition interface
*/
interface ModuleDefinition<TRoutes extends NestedRoutes> {
name: string;
prefix?: string;
routes: TRoutes;
api: ModuleAPI<TRoutes>;
}
/**
* Fetch options for route requests
*/
interface FetchOptions {
headers?: Record<string, string>;
timeout?: number;
signal?: AbortSignal;
}
/**
* Check if arguments are required
*/
type IsRequired<TInput> = [TInput] extends [never] ? false : {} extends TInput ? false : true;
/**
* Route function with proper argument requirements
*/
type RouteFunction<TInput, TResponse> = IsRequired<TInput> extends true ? (args: TInput, options?: FetchOptions) => Promise<TResponse> : (args?: TInput, options?: FetchOptions) => Promise<TResponse>;
/**
* Generate API types from route structure
*/
type ModuleAPI<TRoutes> = { [K in keyof TRoutes]: TRoutes[K] extends RouteDefinition<infer TInput, infer TResponse> ? RouteFunction<TInput, TResponse> : TRoutes[K] extends NestedRoutes ? ModuleAPI<TRoutes[K]> : never };
/**
* Legacy route args interface for backward compatibility
*/
//#endregion
//#region src/modules/achievement/types.d.ts
type Achievement = SerializedModel<InferSelectModel<typeof achievements>>;
type AchievementType = "checking" | "completed" | "incomplete" | "audit" | "received";
interface ListAchievementsRequest {
type?: AchievementType | "all";
}
interface ClaimAchievementRequest {
actionId: number;
}
interface CheckAchievementRequest {
actionId: number;
}
interface AuditAchievementRequest {
actionId: number;
payload: any;
}
interface AchievementWithPower extends Achievement {
power: string;
}
interface ListAchievementsData {
data: AchievementWithPower[];
total: number;
done: number;
}
interface AchievementActionResult {
actionId: number;
result: boolean;
}
type ListAchievementsResponse = SuccessResponse<AchievementWithPower[]> & {
total: number;
done: number;
};
type ClaimAchievementResponse = SuccessResponse<AchievementActionResult>;
type CheckAchievementResponse = SuccessResponse<AchievementActionResult>;
type AuditAchievementResponse = EmptyResponse;
//#endregion
//#region src/modules/achievement/index.d.ts
/**
* Achievement module for user achievement management
*/
declare const achievementModule: ModuleDefinition<{
list: RouteDefinition<ListAchievementsRequest, ListAchievementsResponse>;
claim: RouteDefinition<ClaimAchievementRequest, ClaimAchievementResponse>;
check: RouteDefinition<CheckAchievementRequest, CheckAchievementResponse>;
audit: RouteDefinition<AuditAchievementRequest, EmptyResponse>;
}>;
type AchievementAPI = typeof achievementModule.api;
//#endregion
//#region src/modules/admin/types.d.ts
type FeatureFlagModel = SerializedModel<InferSelectModel<typeof featureFlags>>;
type FeatureFlagInsert = SerializedInsertModel<InferInsertModel<typeof featureFlags>>;
type UserFeatureOverrideModel = SerializedModel<InferSelectModel<typeof userFeatureOverrides>>;
type UserFeatureOverrideInsert = SerializedInsertModel<InferInsertModel<typeof userFeatureOverrides>>;
declare const ROLLOUT_TYPES: readonly ["whitelist", "percentage"];
type RolloutType = (typeof ROLLOUT_TYPES)[number];
type RolloutValue = 0 | 1;
type MessageResponse = SuccessResponse<{
message: string;
}>;
type FeatureFlagResponse = SuccessResponse<FeatureFlagModel>;
type FeatureFlagListResponse = SuccessResponse<FeatureFlagModel[]>;
interface FeatureFlagUpdateRequest {
description?: string;
enabled?: boolean;
rolloutType?: RolloutType;
rolloutValue?: RolloutValue;
rolloutPercentage?: number;
rolloutSeed?: string;
}
interface UserOverrideRequest {
userId: string;
forceEnabled: boolean;
reason?: string;
expiresAt?: string;
}
type FeatureStatsResponse = SuccessResponse<{
totalUsers: number;
enabledUsers: number;
overrideUsers: number;
rolloutType: string;
rolloutPercentage: number;
enabledOverrides: number;
disabledOverrides: number;
enabled: boolean;
enabledByRollout: number;
enabledByOverride: number;
disabledUsers: number;
}>;
interface AffectedUsersQuery {
page?: number;
limit?: number;
filter?: "all" | "enabled" | "disabled" | "override";
search?: string;
}
interface AffectedUser {
id: string;
name: string | null;
email: string;
handle: string | null;
image: string | null;
createdAt: string;
status: "enabled" | "disabled";
reason: "rollout" | "override";
overrideReason: string | null;
overrideExpiresAt: string | null;
overrideCreatedBy: string | null;
}
type AffectedUsersResponse = SuccessResponse<{
users: AffectedUser[];
pagination: {
page: number;
limit: number;
total: number;
totalPages: number;
};
}>;
interface FeatureFlagUpdateInput {
name: string;
description?: string;
enabled?: boolean;
rolloutType?: RolloutType;
rolloutValue?: RolloutValue;
rolloutPercentage?: number;
rolloutSeed?: string;
}
interface UserOverrideInput {
name: string;
userId: string;
forceEnabled: boolean;
reason?: string;
expiresAt?: string;
}
interface RemoveOverrideInput {
name: string;
userId: string;
}
interface FeatureStatsInput {
name: string;
}
interface AffectedUsersInput {
name: string;
page?: number;
limit?: number;
filter?: "all" | "enabled" | "disabled" | "override";
search?: string;
}
interface CleanRequest {
type: string;
feedId?: string;
nsfw?: boolean;
}
type CleanResponse = EmptyResponse;
interface MintRequest {
userId: string;
amount: number;
key: string;
comment?: string;
}
type MintResponse = SuccessResponse<string>;
//#endregion
//#region src/modules/admin/index.d.ts
/**
* Admin module definition with nested routes
*/
declare const adminModule: ModuleDefinition<{
featureFlags: {
list: RouteDefinition<never, FeatureFlagListResponse>;
update: RouteDefinition<FeatureFlagUpdateInput, FeatureFlagResponse>;
override: RouteDefinition<UserOverrideInput, MessageResponse>;
removeOverride: RouteDefinition<RemoveOverrideInput, MessageResponse>;
stats: RouteDefinition<FeatureStatsInput, FeatureStatsResponse>;
affectedUsers: RouteDefinition<AffectedUsersInput, AffectedUsersResponse>;
};
clean: {
execute: RouteDefinition<CleanRequest, EmptyResponse>;
};
mint: {
execute: RouteDefinition<MintRequest, MintResponse>;
};
}>;
type AdminAPI = typeof adminModule.api;
//#endregion
//#region src/modules/ai/types.d.ts
type LanguageSchema = z.infer<typeof languageSchema>;
interface ChatMessage {
role: string;
content: string;
}
interface ChatContext {
mainEntryId?: string;
referEntryIds?: string[];
referFeedIds?: string[];
selectedText?: string;
}
interface ChatRequest {
messages: ChatMessage[];
context?: ChatContext;
}
type ChatResponse = Response;
interface SummaryRequest {
id: string;
language?: LanguageSchema;
target?: "content" | "readabilityContent";
}
type SummaryResponse = SuccessResponse<string | null>;
type EntryStringKey = "title" | "description" | "content" | "readabilityContent";
interface TranslationRequest {
id: string;
language: LanguageSchema;
fields: string;
part?: string;
}
interface TranslationData {
title?: string;
description?: string;
content?: string;
readabilityContent?: string;
}
type TranslationResponse = SuccessResponse<TranslationData | null>;
interface TitleRequest {
messages: ChatMessage[];
}
interface TitleResponse {
title: string;
remainingTokens?: number;
}
interface TitleErrorResponse {
error: string;
}
interface DailyRequest {
startDate: string;
view: "0" | "1";
}
type DailyResponse = SuccessResponse<string>;
interface UsageRequest {}
type UsageResponse = SuccessResponse<{
total: number;
used: number;
remaining: number;
resetAt: Date;
}>;
interface RateLimit {
maxTokens: number;
currentTokens: number;
remainingTokens: number;
windowDuration: number;
windowResetTime: number;
}
interface ConfigResponse {
currentModel: string;
availableModels: string[];
rateLimit: RateLimit;
}
//#endregion
//#region src/modules/ai/index.d.ts
/**
* AI module definition with nested AI-powered features
*/
declare const aiModule: ModuleDefinition<{
chat: RouteDefinition<ChatRequest, Response>;
summary: RouteDefinition<SummaryRequest, SummaryResponse>;
translation: RouteDefinition<TranslationRequest, TranslationResponse>;
summaryTitle: RouteDefinition<TitleRequest, TitleResponse>;
daily: RouteDefinition<DailyRequest, DailyResponse>;
usage: RouteDefinition<UsageRequest, UsageResponse>;
config: RouteDefinition<never, ConfigResponse>;
}>;
type AIAPI = typeof aiModule.api;
//#endregion
//#region src/modules/boosts/types.d.ts
type User$2 = SerializedModel<InferSelectModel<typeof users>>;
interface GetFeedBoostLevelRequest extends FeedIdRequest {}
interface BoostFeedRequest extends FeedIdRequest {
amount: string;
TOTPCode?: string;
}
interface GetFeedBoostersRequest extends FeedIdRequest {}
interface FeedBoostLevelData {
monthlyBoostCost: number;
boostCount: number;
level: number;
remainingBoostsToLevelUp: number;
lastValidBoost: {
hash: string | null;
expiresAt: string;
} | null;
}
interface BoostFeedData {
transactionHash: string;
expiresAt: string;
}
type GetFeedBoostLevelResponse = SuccessResponse<FeedBoostLevelData>;
type BoostFeedResponse = SuccessResponse<BoostFeedData>;
type GetFeedBoostersResponse = SuccessResponse<Omit<User$2, "email">[]>;
//#endregion
//#region src/modules/boosts/index.d.ts
/**
* Boosts module for content boosting with power tokens
*/
declare const boostsModule: ModuleDefinition<{
getFeedBoostLevel: RouteDefinition<GetFeedBoostLevelRequest, GetFeedBoostLevelResponse>;
boostFeed: RouteDefinition<BoostFeedRequest, BoostFeedResponse>;
getFeedBoosters: RouteDefinition<GetFeedBoostersRequest, GetFeedBoostersResponse>;
}>;
type BoostsAPI = typeof boostsModule.api;
//#endregion
//#region src/modules/categories/types.d.ts
interface CategoriesGetQuery {
view?: string;
}
type CategoriesGetResponse = SuccessResponse<string[]>;
interface CategoryPatchRequest {
feedIdList: string[];
category: string;
}
type CategoryPatchResponse = EmptyResponse;
interface CategoryDeleteRequest {
feedIdList: string[];
deleteSubscriptions: boolean;
}
type CategoryDeleteResponse = EmptyResponse;
//#endregion
//#region src/modules/categories/index.d.ts
/**
* Categories module definition - Subscription categorization
*/
declare const categoriesModule: ModuleDefinition<{
get: RouteDefinition<CategoriesGetQuery, CategoriesGetResponse>;
update: RouteDefinition<CategoryPatchRequest, EmptyResponse>;
delete: RouteDefinition<CategoryDeleteRequest, EmptyResponse>;
}>;
type CategoriesAPI = typeof categoriesModule.api;
//#endregion
//#region src/modules/collections/types.d.ts
interface CollectionCheckQuery extends EntryIdRequest {}
type CollectionCheckResponse = SuccessResponse<boolean>;
interface CollectionCreateRequest extends EntryIdRequest {
view?: number;
}
type CollectionCreateResponse = EmptyResponse;
interface CollectionDeleteRequest extends EntryIdRequest {}
type CollectionDeleteResponse = EmptyResponse;
//#endregion
//#region src/modules/collections/index.d.ts
/**
* Collections module definition - Content collections management
*/
declare const collectionsModule: ModuleDefinition<{
get: RouteDefinition<CollectionCheckQuery, CollectionCheckResponse>;
post: RouteDefinition<CollectionCreateRequest, EmptyResponse>;
delete: RouteDefinition<CollectionDeleteRequest, EmptyResponse>;
}>;
type CollectionsAPI = typeof collectionsModule.api;
//#endregion
//#region src/modules/data/types.d.ts
interface ExportDataRequest {
format?: string;
type?: string;
}
type ExportDataResponse = SuccessResponse<string>;
//#endregion
//#region src/modules/data/index.d.ts
/**
* Data module for data export operations
*/
declare const dataModule: ModuleDefinition<{
export: RouteDefinition<ExportDataRequest, ExportDataResponse>;
}>;
type DataAPI = typeof dataModule.api;
//#endregion
//#region src/modules/discover/types.d.ts
interface DiscoverRequest {
keyword: string;
target?: "feeds" | "lists";
}
interface FeedDiscoveryResult {
type: "feed";
id: string;
url: string;
title: string | null;
description: string | null;
siteUrl: string | null;
image: string | null;
ownerUserId?: string;
owner?: {
id: string;
name: string;
handle: string;
avatar: string | null;
};
}
interface ListDiscoveryResult {
type: "list";
id: string;
title: string;
description: string | null;
image: string | null;
view: number;
fee: number;
ownerUserId: string;
}
interface EntryData {
id: string;
title: string | null;
content: string | null;
description: string | null;
publishedAt: string;
url: string | null;
author: string | null;
feedId: string;
}
interface FeedAnalyticsData {
feedId: string;
subscriptionCount: number;
updatesPerWeek: number;
totalSubscriptions: number;
weeklyGrowth: number;
}
interface DiscoveryItem {
feed?: FeedDiscoveryResult;
list?: ListDiscoveryResult;
docs?: string;
entries?: EntryData[];
subscriptionCount?: number;
updatesPerWeek?: number;
analytics?: FeedAnalyticsData;
}
type DiscoverResponse = SuccessResponse<DiscoveryItem[]>;
interface RSSHubRoute {
path: string;
name: string;
description: string;
parameters?: Record<string, string>;
example?: string;
}
type RSSHubResponse = SuccessResponse<RSSHubRoute[]>;
interface RSSHubRouteQuery {
route: string;
}
interface RSSHubRouteData {
route: string;
name: string;
description: string;
parameters: Record<string, any>;
examples: string[];
documentation: string;
}
type RSSHubRouteResponse = SuccessResponse<RSSHubRouteData>;
interface RSSHubAnalyticsQuery {
period?: "day" | "week" | "month";
}
interface RSSHubAnalyticsData {
totalRoutes: number;
activeRoutes: number;
totalRequests: number;
popularRoutes: Array<{
route: string;
requests: number;
name: string;
}>;
usage: Array<{
date: string;
requests: number;
}>;
}
type RSSHubAnalyticsResponse = SuccessResponse<RSSHubAnalyticsData>;
//#endregion
//#region src/modules/discover/index.d.ts
/**
* Discover module definition - Feed and list discovery
*/
declare const discoverModule: ModuleDefinition<{
discover: RouteDefinition<DiscoverRequest, DiscoverResponse>;
rsshub: RouteDefinition<never, RSSHubResponse>;
rsshubRoute: RouteDefinition<RSSHubRouteQuery, RSSHubRouteResponse>;
rsshubAnalytics: RouteDefinition<RSSHubAnalyticsQuery, RSSHubAnalyticsResponse>;
}>;
type DiscoverAPI = typeof discoverModule.api;
//#endregion
//#region src/types/utils.d.ts
type Prettify<T> = { [K in keyof T]: T[K] } & {};
//#endregion
//#region src/modules/entries/types.d.ts
type FeedOpenApiSchema$1 = SerializedModel<FeedOpenApiSchema>;
type InboxOpenApiSchema$1 = SerializedModel<InboxOpenApiSchema>;
type EntryModel = SerializedModel<InferSelectModel<typeof entries>>;
type EntryInsert = SerializedInsertModel<InferInsertModel<typeof entries>>;
type UserModel = SerializedModel<InferSelectModel<typeof users>>;
type InboxModel$1 = SerializedModel<InferSelectModel<typeof inboxes>>;
interface EntryMedia {
url: string;
type: "photo" | "video";
preview_image_url?: string;
width?: number;
height?: number;
blurhash?: string;
}
interface EntryAttachment {
url: string;
title?: string;
duration_in_seconds?: number;
mime_type?: string;
size_in_bytes?: number;
}
interface EntryGetQuery extends IdRequest {}
type EntryOpenAPISchema = SerializedModel<z$1.infer<typeof entriesOpenAPISchema>>;
type EntryGetByIdResponse = SuccessResponse<{
feeds: FeedOpenApiSchema$1;
entries: Prettify<Omit<EntryOpenAPISchema, "feedId">>;
} | null>;
interface EntryWithFeed extends EntryExtraResponse {
read: boolean;
view: FeedViewType$1;
from: string[];
feeds: FeedOpenApiSchema$1;
entries: Prettify<Omit<EntryOpenAPISchema, "content" | "feedId">>;
}
type EntryListRequest = {
view?: FeedViewType$1;
feedId?: string;
feedIdList?: string[];
read?: boolean;
limit?: number;
publishedAfter?: DateISOString;
publishedBefore?: DateISOString;
isCollection?: boolean;
isArchived?: boolean;
withContent?: boolean;
excludePrivate?: boolean;
};
type EntryListResponse = SuccessResponse<EntryWithFeed[]>;
interface EntryPreviewRequest extends IdRequest {}
type EntryPreviewResponse = SuccessResponse<z$1.infer<typeof entriesOpenAPISchema>>;
interface EntryReadabilityRequest extends IdRequest {}
type EntryReadabilityResponse = SuccessResponse<{
content?: string;
} | null>;
interface EntryStreamRequest {
ids: string[];
}
interface EntryStreamItem {
id: string;
content: string;
}
interface CheckNewEntriesQuery {
view?: number;
feedId?: string;
feedIdList?: string[];
read?: boolean;
insertedAfter: number;
}
type CheckNewEntriesResponse = SuccessResponse<{
has_new: boolean;
lastest_at?: string;
entry_id?: string;
}>;
interface ReadHistoriesQuery {
page?: number;
size?: number;
}
type ReadHistoriesResponse = SuccessResponse<{
users: Record<string, Pick<UserModel, "id" | "handle" | "name" | "image">>;
total: number;
entryReadHistories: {
userIds: string[];
readCount: number;
} | null;
}>;
interface InboxEntryGetQuery extends IdRequest {}
interface InboxListEntryRequestInput {
inboxId: string;
read?: boolean;
limit?: number;
publishedAfter?: string;
publishedBefore?: string;
}
type EntrySettings = SettingsModel$1;
interface EntryExtraResponse {
collections?: Prettify<Pick<z$1.infer<typeof collectionsOpenAPISchema>, "createdAt">>;
settings?: EntrySettings;
}
interface InboxListEntry extends EntryExtraResponse {
read: boolean;
feeds: InboxOpenApiSchema$1;
entries: Prettify<Omit<z$1.infer<typeof inboxesEntriesOpenAPISchema>, "content">>;
}
type InboxListEntryResponse = SuccessResponse<InboxListEntry[]>;
interface InboxEntryGetResponse {
data: {
entries: EntryModel;
feed: Pick<InboxModel$1, "secret" | "title"> & {
type: "inbox";
id: string;
};
};
}
interface MarkReadInput extends IdRequest {}
interface MarkUnreadInput extends IdRequest {}
interface ReadHistoriesInput extends IdRequest {
page?: number;
size?: number;
}
interface InboxRemoveInput extends EntryIdRequest {}
//#endregion
//#region src/modules/entries/index.d.ts
/**
* Entries module definition with nested routes
*/
declare const entriesModule: ModuleDefinition<{
get: RouteDefinition<EntryGetQuery, EntryGetByIdResponse>;
list: RouteDefinition<EntryListRequest, EntryListResponse>;
preview: RouteDefinition<EntryPreviewRequest, EntryPreviewResponse>;
readability: RouteDefinition<EntryReadabilityRequest, EntryReadabilityResponse>;
stream: RouteDefinition<EntryStreamRequest, Response>;
checkNew: RouteDefinition<CheckNewEntriesQuery, CheckNewEntriesResponse>;
readHistories: RouteDefinition<ReadHistoriesInput, ReadHistoriesResponse>;
inbox: {
get: RouteDefinition<InboxEntryGetQuery, InboxEntryGetResponse>;
list: RouteDefinition<InboxListEntryRequestInput, InboxListEntryResponse>;
delete: RouteDefinition<InboxRemoveInput, SuccessResponse<any>>;
};
}>;
type EntriesAPI = typeof entriesModule.api;
//#endregion
//#region src/modules/feeds/types.d.ts
type FeedModel = SerializedModel<InferSelectModel<typeof feeds>>;
interface FeedGetQuery {
id?: string;
url?: string;
entriesLimit?: number;
}
interface FeedGetResponse {
feed: FeedModel;
entries?: any[];
subscription?: any;
readCount?: number;
subscriptionCount?: number;
}
interface FeedRefreshRequest {
url: string;
force?: boolean;
}
interface FeedRefreshResponse {
success: boolean;
message?: string;
}
interface FeedAnalyticsQuery extends FeedIdRequest {
timeRange?: "7d" | "30d" | "90d";
}
interface FeedAnalyticsResponse {
views: number;
subscribers: number;
engagement: number;
growth: number;
}
interface FeedResetRequest extends FeedIdRequest {
reason?: string;
}
interface FeedResetResponse {
success: boolean;
message?: string;
}
interface FeedClaimChallengeRequest extends FeedIdRequest {
challenge: string;
}
interface FeedClaimChallengeResponse {
success: boolean;
message?: string;
}
interface FeedClaimListQuery {
page?: number;
limit?: number;
status?: "pending" | "approved" | "rejected";
}
interface FeedClaimItem {
id: string;
feedId: string;
userId: string;
status: "pending" | "approved" | "rejected";
createdAt: string;
updatedAt: string;
}
interface FeedClaimListResponse {
claims: FeedClaimItem[];
pagination: {
page: number;
limit: number;
total: number;
hasMore: boolean;
};
}
interface FeedClaimMessageRequest extends FeedIdRequest {
message: string;
}
interface FeedClaimMessageResponse {
success: boolean;
message?: string;
}
//#endregion
//#region src/modules/inboxes/types.d.ts
type InboxModel = SerializedModel<InferSelectModel<typeof inboxes>>;
interface InboxTarget extends InboxModel {
type: "inbox";
}
interface InboxGetQuery {
handle: string;
}
type InboxGetResponse = SuccessResponse<InboxTarget>;
type InboxListResponse = PaginatedResponse<InboxTarget>;
interface InboxCreateRequest {
title: string;
handle: string;
description?: string;
image?: string;
}
type InboxCreateResponse = SuccessResponse<InboxTarget>;
interface InboxUpdateRequest {
id: string;
title?: string;
description?: string;
image?: string;
}
type InboxUpdateResponse = SuccessResponse<InboxTarget>;
interface InboxDeleteRequest {
id: string;
}
type InboxDeleteResponse = EmptyResponse;
interface InboxEmailRequest {
inboxId: string;
action: "enable" | "disable" | "regenerate";
}
interface InboxEmailData {
email: string;
enabled: boolean;
lastUsed?: string;
}
type InboxEmailResponse = SuccessResponse<InboxEmailData>;
interface InboxWebhookRequest {
inboxId: string;
url?: string;
secret?: string;
enabled?: boolean;
}
interface InboxWebhookData {
url: string;
secret: string;
enabled: boolean;
lastTriggered?: string;
}
type InboxWebhookResponse = SuccessResponse<InboxWebhookData>;
//#endregion
//#region src/modules/inboxes/index.d.ts
/**
* Inboxes module definition - Email inboxes management
*/
declare const inboxesModule: ModuleDefinition<{
get: RouteDefinition<InboxGetQuery, InboxGetResponse>;
list: RouteDefinition<never, InboxListResponse>;
post: RouteDefinition<InboxCreateRequest, InboxCreateResponse>;
put: RouteDefinition<InboxUpdateRequest, InboxUpdateResponse>;
delete: RouteDefinition<InboxDeleteRequest, EmptyResponse>;
email: RouteDefinition<InboxEmailRequest, InboxEmailResponse>;
webhook: RouteDefinition<InboxWebhookRequest, InboxWebhookResponse>;
}>;
type InboxesAPI = typeof inboxesModule.api;
//#endregion
//#region src/modules/invitations/types.d.ts
type Invitation = SerializedModel<InferSelectModel<typeof invitations>>;
type User$1 = SerializedModel<InferSelectModel<typeof users>>;
interface CreateInvitationRequest {
TOTPCode?: string;
}
interface UseInvitationRequest {
code: string;
}
interface InvitationWithUser extends Omit<Invitation, "fromUserId"> {
fromUser: Pick<User$1, "id" | "name" | "image">;
}
type GetInvitationLimitationResponse = SuccessResponse<number>;
type GetInvitationsListResponse = SuccessResponse<InvitationWithUser[]>;
type CreateInvitationResponse = SuccessResponse<string>;
type UseInvitationResponse = SuccessResponse<null>;
//#endregion
//#region src/modules/invitations/index.d.ts
/**
* Invitations module for managing invitation codes
*/
declare const invitationsModule: ModuleDefinition<{
getLimitation: RouteDefinition<never, GetInvitationLimitationResponse>;
list: RouteDefinition<never, GetInvitationsListResponse>;
create: RouteDefinition<CreateInvitationRequest, CreateInvitationResponse>;
use: RouteDefinition<UseInvitationRequest, UseInvitationResponse>;
}>;
type InvitationsAPI = typeof invitationsModule.api;
//#endregion
//#region src/modules/lists/types.d.ts
type ListModel = SerializedModel<InferSelectModel<typeof lists>>;
type ListInsert = SerializedInsertModel<InferInsertModel<typeof lists>>;
type ListSubscriptionModel = SerializedModel<InferSelectModel<typeof listsSubscriptions>>;
type ListVisibility = "public" | "private" | "unlisted";
type ListPermission = "read" | "write" | "admin";
interface List extends ListModel {
feedCount?: number;
subscriberCount?: number;
isOwner?: boolean;
isSubscribed?: boolean;
permission?: ListPermission;
owner?: {
id: string;
name: string | null;
handle: string | null;
avatar: string | null;
};
}
interface CreateListRequest {
title: string;
description?: string;
visibility?: ListVisibility;
image?: string;
feedIds?: string[];
}
interface UpdateListRequest {
title?: string;
description?: string;
visibility?: ListVisibility;
image?: string;
}
interface ListFeed {
id: string;
feedId: string;
listId: string;
order: number;
addedAt: string;
feed: {
id: string;
title: string;
description?: string;
image?: string;
url: string;
category?: string;
subscriberCount?: number;
};
}
interface AddFeedRequest {
feedId: string;
order?: number;
}
interface UpdateFeedOrderRequest {
feeds: Array<{
feedId: string;
order: number;
}>;
}
interface ListEntry {
id: string;
title: string;
description?: string;
content?: string;
url: string;
publishedAt: string;
readAt?: string;
starred?: boolean;
feed: {
id: string;
title: string;
image?: string;
};
author?: {
name: string;
email?: string;
url?: string;
};
}
interface ShareListRequest {
visibility: ListVisibility;
shareCode?: string;
permissions?: {
allowComments?: boolean;
allowSubscribe?: boolean;
allowCopy?: boolean;
};
}
interface ListPermissions {
visibility: ListVisibility;
shareCode?: string;
permissions: {
allowComments: boolean;
allowSubscribe: boolean;
allowCopy: boolean;
};
collaborators: Array<{
userId: string;
permission: ListPermission;
addedAt: string;
user: {
id: string;
name: string | null;
handle: string | null;
avatar: string | null;
};
}>;
}
interface UpdatePermissionsRequest {
visibility?: ListVisibility;
permissions?: {
allowComments?: boolean;
allowSubscribe?: boolean;
allowCopy?: boolean;
};
collaborators?: Array<{
userId: string;
permission: ListPermission;
}>;
}
interface ListSubscriber {
id: string;
userId: string;
subscribedAt: string;
user: {
id: string;
name: string | null;
handle: string | null;
avatar: string | null;
};
}
interface DiscoverList {
id: string;
title: string;
description?: string;
image?: string;
visibility: ListVisibility;
feedCount: number;
subscriberCount: number;
createdAt: string;
updatedAt: string;
owner: {
id: string;
name: string | null;
handle: string | null;
avatar: string | null;
};
tags: string[];
category?: string;
}
interface ImportListRequest {
title: string;
description?: string;
feedUrls: string[];
visibility?: ListVisibility;
}
interface ExportFormat {
format: "opml" | "json" | "csv";
includeMetadata?: boolean;
}
interface ListAnalytics {
views: {
total: number;
unique: number;
thisWeek: number;
thisMonth: number;
};
subscribers: {
total: number;
new: number;
growth: number;
};
engagement: {
avgReadTime: number;
readRate: number;
shareRate: number;
};
topFeeds: Array<{
feedId: string;
title: string;
views: number;
reads: number;
}>;
traffic: Array<{
date: string;
views: number;
uniqueViews: number;
}>;
}
interface ListsQuery {
listId: string;
noExtras?: boolean;
}
interface ListFeedsQuery {
limit?: number;
page?: number;
sort?: "order" | "added" | "title";
order?: "asc" | "desc";
}
interface ListEntriesQuery {
read?: boolean;
starred?: boolean;
feedId?: string;
since?: string;
until?: string;
limit?: number;
page?: number;
sort?: "published" | "added" | "title";
order?: "asc" | "desc";
}
interface SubscribersQuery {
limit?: number;
page?: number;
sort?: "subscribed" | "name";
order?: "asc" | "desc";
}
interface DiscoverQuery {
category?: string;
search?: string;
minFeeds?: number;
minSubscribers?: number;
limit?: number;
page?: number;
sort?: "title" | "created" | "subscribers" | "feeds" | "relevance";
order?: "asc" | "desc";
}
interface TrendingQuery {
period?: "day" | "week" | "month";
category?: string;
limit?: number;
page?: number;
}
interface AnalyticsQuery {
period?: "day" | "week" | "month" | "year";
since?: string;
until?: string;
}
type ListResponse = SuccessResponse<List>;
type ListsResponse = PaginatedResponse<List>;
type ListFeedsResponse = PaginatedResponse<ListFeed>;
type ListEntriesResponse = PaginatedResponse<ListEntry>;
type ListPermissionsResponse = SuccessResponse<ListPermissions>;
type ListSubscribersResponse = PaginatedResponse<ListSubscriber>;
type DiscoverListsResponse = PaginatedResponse<DiscoverList>;
type TrendingListsResponse = PaginatedResponse<DiscoverList>;
type ListAnalyticsResponse = SuccessResponse<ListAnalytics>;
type ExportResponse = SuccessResponse<{
url: string;
}>;
interface RemoveFeedInput {
id: string;
feedId: string;
}
interface ExportInput {
id: string;
format: "opml" | "json" | "csv";
includeMetadata?: boolean;
}
interface GetAnalyticsInput {
id: string;
period?: "day" | "week" | "month" | "year";
since?: string;
until?: string;
}
//#endregion
//#region src/modules/lists/index.d.ts
/**
* Lists module definition with nested routes
*/
declare const listsModule: ModuleDefinition<{
list: RouteDefinition<ListsQuery, ListsResponse>;
create: RouteDefinition<CreateListRequest, ListResponse>;
removeFeed: RouteDefinition<RemoveFeedInput, EmptyResponse>;
discover: RouteDefinition<DiscoverQuery, DiscoverListsResponse>;
trending: RouteDefinition<TrendingQuery, TrendingListsResponse>;
import: RouteDefinition<ImportListRequest, ListResponse>;
export: RouteDefinition<ExportInput, ExportResponse>;
getAnalytics: RouteDefinition<GetAnalyticsInput, ListAnalyticsResponse>;
}>;
type ListsAPI = typeof listsModule.api;
//#endregion
//#region src/modules/mcp/types.d.ts
type McpTransportType = "streamable-http" | "sse";
interface McpConnectionInfo {
id: string;
name: string;
transportType: McpTransportType;
url?: string;
isConnected: boolean;
lastError?: string;
toolCount: number;
resourceCount: number;
promptCount: number;
createdAt: string;
lastUsed: string | null;
}
interface McpTool {
name: string;
title?: string;
description?: string;
inputSchema: {
type: "object";
properties?: Record<string, any>;
required?: string[];
};
outputSchema?: {
type: "object";
properties?: Record<string, any>;
required?: string[];
};
annotations?: {
title?: string;
readOnlyHint?: boolean;
openWorldHint?: boolean;
};
}
interface RefreshResult {
success: boolean;
error?: string;
}
interface CreateConnectionRequest {
name: string;
transportType: McpTransportType;
url: string;
headers?: Record<string, string>;
}
interface UpdateConnectionRequest {
name?: string;
transportType?: McpTransportType;
url?: string;
headers?: Record<string, string>;
connectionId: string;
}
type UpdateConnectionResponse = {
code: 0 | 1;
/**
* If code is 1, the authorizationUrl is required
*/
authorizationUrl?: string;
};
interface ConnectionParams {
connectionId: string;
}
interface RefreshToolsRequest {
connectionIds?: string[];
}
type CreateConnectionResponse = {
/**
* 0: success, 1: need oauth
*/
code: 0 | 1;
authorizationUrl?: string;
};
type GetConnectionsResponse = SuccessResponse<McpConnectionInfo[]>;
type DeleteConnectionResponse = SuccessResponse;
type GetToolsResponse = SuccessResponse<McpTool[]>;
type RefreshToolsResponse = SuccessResponse<{
total: number;
successful: number;
failed: number;
results: RefreshResult[];
}>;
//#endregion
//#region src/modules/messaging/types.d.ts
type MessagingToken = SerializedModel<InferSelectModel<typeof messaging>>;
type MessagingChannel = "macos" | "windows" | "linux" | "ios" | "android" | "web" | "desktop";
interface CreateMessagingTokenRequest {
token: string;
channel: MessagingChannel;
}
interface DeleteMessagingTokenRequest {
channel: MessagingChannel;
}
interface TestMessagingRequest {
channel?: string;
}
type GetMessagingTokensResponse = SuccessResponse<MessagingToken[]>;
type CreateMessagingTokenResponse = EmptyResponse;
type DeleteMessagingTokenResponse = EmptyResponse;
type TestMessagingResponse = EmptyResponse;
//#endregion
//#region src/modules/messaging/index.d.ts
/**
* Messaging module for push notification management
*/
declare const messagingModule: ModuleDefinition<{
getTokens: RouteDefinition<never, GetMessagingTokensResponse>;
createToken: RouteDefinition<CreateMessagingTokenRequest, EmptyResponse>;
deleteToken: RouteDefinition<DeleteMessagingTokenRequest, EmptyResponse>;
}>;
type MessagingAPI = typeof messagingModule.api;
//#endregion
//#region src/modules/profiles/types.d.ts
type User = SerializedModel<InferSelectModel<typeof users>>;
type UserProfile = Omit<User, "email">;
interface GetProfileRequest {
id?: string;
handle?: string;
}
interface GetProfilesBatchRequest {
ids: string[];
}
type GetProfileResponse = SuccessResponse<UserProfile>;
type GetProfilesBatchResponse = SuccessResponse<Record<string, UserProfile>>;
//#endregion
//#region src/modules/profiles/index.d.ts
/**
* Profiles module for user profile management
*/
declare const profilesModule: ModuleDefinition<{
getProfile: RouteDefinition<GetProfileRequest, GetProfileResponse>;
getBatch: RouteDefinition<GetProfilesBatchRequest, GetProfilesBatchResponse>;
}>;
type ProfilesAPI = typeof profilesModule.api;
//#endregion
//#region src/modules/probes/types.d.ts
interface CheckBullMQRequest {
name: "follow-queue" | "admin-wallet-queue";
}
interface GetRSSHubAnalyticsRequest {
namespace?: string;
route?: string;
}
interface BullMQStatus {
current: {
wait: number;
completed: number;
failed: number;
};
metrics: {
completed: {
data: number[];
count: number;
};
failed: {
data: number[];
count: number;
};
};
}
interface RSSHubAnalyticsItem {
successCount: number;
errorCount: number;
timestamp: string;
successRate: number;
}
type CheckPostgreSQLResponse = SuccessResponse<number>;
type CheckRedisResponse = SuccessResponse<number>;
type CheckBullMQResponse = SuccessResponse<BullMQStatus>;
type GetRSSHubAnalyticsResponse = SuccessResponse<RSSHubAnalyticsItem[]>;
//#endregion
//#region src/modules/probes/index.d.ts
/**
* Probes module for health checks and system monitoring
*/
declare const probesModule: ModuleDefinition<{
checkPostgreSQL: RouteDefinition<never, CheckPostgreSQLResponse>;
checkRedis: RouteDefinition<never, CheckRedisResponse>;
checkBullMQ: RouteDefinition<CheckBullMQRequest, CheckBullMQResponse>;
getRSSHubAnalytics: RouteDefinition<GetRSSHubAnalyticsRequest, GetRSSHubAnalyticsResponse>;
}>;
type ProbesAPI = typeof probesModule.api;
//#endregion
//#region src/modules/reads/types.d.ts
/**
* Query parameters for getting read status
*/
interface ReadStatusQuery {
view?: FeedViewType$1;
}
type ReadStatusResponse = SuccessResponse<Record<string, number>>;
/**
* Request to mark entries as read
*/
interface MarkAsReadRequest {
entryIds: string[];
isInbox?: boolean;
readHistories?: string[];
}
/**
* Request to mark single entry as unread
*/
interface MarkAsUnreadRequest {
entryId: string;
isInbox?: boolean;
}
/**
* Request to mark all entries as read (batch operation)
*/
interface MarkAllAsReadRequest {
view?: number;
feedId?: string;
listId?: string;
inboxId?: string;
feedIdList?: string[];
startTime?: number;
endTime?: number;
excludePrivate?: boolean;
insertedBefore?: number;
}
/**
* Response for mark all as read operation
*/
type MarkAllAsReadResponse = SuccessResponse<{
read: Record<string, number>;
}>;
/**
* Response for basic read operations
*/
type ReadOperationResponse = SuccessResponse<null>;
/**
* Response for total unread count
*/
type TotalUnreadCountResponse = SuccessResponse<{
count: number;
}>;
//#endregion
//#region src/modules/reads/index.d.ts
/**
* Reads module definition with nested routes
*/
declare const readsModule: ModuleDefinition<{
get: RouteDefinition<ReadStatusQuery, ReadStatusResponse>;
markAsRead: RouteDefinition<MarkAsReadRequest, ReadOperationResponse>;
markAsUnread: RouteDefinition<MarkAsUnreadRequest, ReadOperationResponse>;
markAllAsRead: RouteDefinition<MarkAllAsReadRequest, MarkAllAsReadResponse>;
getTotalCount: RouteDefinition<never, TotalUnreadCountResponse>;
}>;
type ReadsAPI = typeof readsModule.api;
//#endregion
//#region src/modules/referrals/types.d.ts
interface GetReferralDaysRequest {
code: string;
}
interface VerifyReceiptRequest {
appReceipt: string;
}
interface ReferralUser {
id: string;
name: string | null;
image: string | null;
}
interface ReferralInvitation {
code: string;
createdAt: DateISOString | null;
usedAt: DateISOString | null;
toUserId: string | null;
user: ReferralUser | null;
}
interface ReferralsData {
referralCycleDays: number;
invitations: ReferralInvitation[];
}
interface ReferralDaysData {
referralCycleDays: number;
}
type GetReferralsResponse = SuccessResponse<ReferralsData>;
type GetReferralDaysResponse = SuccessResponse<ReferralDaysData>;
//#endregion
//#region src/modules/rsshub/types.d.ts
interface CreateRSSHubInstanceRequest {
id?: string;
baseUrl: string;
accessKey?: string;
}
interface DeleteRSSHubInstanceRequest {
id: string;
}
interface UseRSSHubInstanceRequest {
id: string | null;
durationInMonths?: number;
twoFactorCode?: string;
backupCode?: string;
}
interface GetRSSHubInstanceRequest {
id: string;
}
interface RSSHubInstanceOwner {
id: string;
handle: string | null;
name: string | null;
image: string | null;
}
interface RSSHubInstanceListItem {
id: string;
ownerUserId: string;
price: number;
userLimit: number | null;
description: string | null;
errorMessage: string | null;
errorAt: DateISOString | null;
userCount: number;
owner: RSSHubInstanceOwner | null;
}
interface RSSHubInstanceDetails {
id: string;
ownerUserId: string;
price: number;
userLimit: number | null;
description: string | null;
errorAt: DateISOString | null;
errorMessage: string | null;
baseUrl?: string | null;
accessKey?: string | null;
}
interface RSSHubPurchase {
hash: string | null;
expiresAt: string;
}
interface RSSHubInstanceData {
instance: RSSHubInstanceDetails;
purchase: RSSHubPurchase | null;
}
interface RSSHubUsage {
id: string;
rsshubId: string;
userId: string;
}
interface RSSHubStatusData {
usage?: RSSHubUsage;
purchase: RSSHubPurchase | null;
}
type CreateRSSHubInstanceResponse = EmptyResponse;
type GetRSSHubInstancesListResponse = SuccessResponse<RSSHubInstanceListItem[]>;
type DeleteRSSHubInstanceResponse = EmptyResponse;
type UseRSSHubInstanceResponse = EmptyResponse;
type GetRSSHubInstanceResponse = SuccessResponse<RSSHubInstanceData>;
type GetRSSHubStatusResponse = SuccessResponse<RSSHubStatusData>;
//#endregion
//#region src/modules/rsshub/index.d.ts
/**
* RSSHub module for RSSHub instance management
*/
declare const rsshubModule: ModuleDefinition<{
createInstance: RouteDefinition<CreateRSSHubInstanceRequest, EmptyResponse>;
listInstances: RouteDefinition<never, GetRSSHubInstancesListResponse>;
deleteInstance: RouteDefinition<DeleteRSSHubInstanceRequest, EmptyResponse>;
useInstance: RouteDefinition<UseRSSHubInstanceRequest, EmptyResponse>;
getInstance: RouteDefinition<GetRSSHubInstanceRequest, GetRSSHubInstanceResponse>;
getStatus: RouteDefinition<never, GetRSSHubStatusResponse>;
}>;
type RSSHubAPI = typeof rsshubModule.api;
//#endregion
//#region src/modules/settings/types.d.ts
type SettingsModel = SerializedModel<InferSelectModel<typeof settings>>;
type SettingsInsert = SerializedInsertModel<InferInsertModel<typeof settings>>;
type SettingsTab = "general" | "appearance" | "integration" | "ai";
type SettingsValue = Record<string, any>;
type SettingsPayload = Record<string, any>;
type SettingsGetResponse = SuccessResponse<{
settings: Record<SettingsTab, SettingsPayload>;
updated: Record<SettingsTab, string>;
}>;
interface SettingsGetQuery {
tab?: string;
}
type SettingsUpdateRequest = Record<string, any>;
type SettingsUpdateResponse = SuccessResponse<null>;
interface GeneralSettings {
language?: string;
theme?: string;
timezone?: string;
notifications?: boolean;
autoRefresh?: boolean;
refreshInterval?: number;
markAsReadOnScroll?: boolean;
showUnreadCount?: boolean;
defaultView?: number;
compactMode?: boolean;
[key: string]: any;
}
interface AppearanceSettings {
fontSize?: number;
fontFamily?: string;
lineHeight?: number;
colorScheme?: "light" | "dark" | "system";
sidebarWidth?: number;
contentWidth?: number;
showSidebar?: boolean;
showToolbar?: boolean;
customCSS?: string;
[key: string]: any;
}
interface IntegrationSettings {
webhookUrl?: string;
webhookEnabled?: boolean;
emailNotifications?: boolean;
pushNotifications?: boolean;
slackWebhook?: string;
discordWebhook?: string;
telegramBotToken?: string;
telegramChatId?: string;
[key: string]: any;
}
interface AISettings {
aiEnabled?: boolean;
aiModel?: string;
autoSummarize?: boolean;
summaryLength?: "short" | "medium" | "long";
translationEnabled?: boolean;
targetLanguage?: string;
sentimentAnalysis?: boolean;
c