UNPKG

@follow-app/client-sdk

Version:

TypeScript client SDK for Follow RSS Server API

1,830 lines (1,829 loc) 84.7 kB
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