// Global environment interface for Cloudflare Workers export interface Env { EMAIL_STORAGE: KVNamespace; ADMIN_PASSWORD: string; DOMAIN: string; ATTACHMENT_BUCKET?: R2Bucket; FEED_MAX_SIZE_BYTES?: string; PROXY_TRUSTED_IPS?: string; PROXY_AUTH_SECRET?: string; } // Stored attachment metadata (bytes live in R2, keyed by id) export interface AttachmentData { id: string; filename: string; contentType: string; size: number; } // Email interface for stored emails export interface EmailData { subject: string; from: string; content: string; receivedAt: number; headers: Record; attachments?: AttachmentData[]; } // Feed configuration interface export interface FeedConfig { title: string; description?: string; allowed_senders?: string[]; language: string; site_url: string; feed_url: string; author?: string; created_at: number; updated_at?: number; } // Feed metadata interface export interface FeedMetadata { emails: EmailMetadata[]; } // Email metadata interface (summary info for listing) export interface EmailMetadata { key: string; subject: string; receivedAt: number; size?: number; attachmentIds?: string[]; } // Feed list interface export interface FeedList { feeds: FeedListItem[]; } // Feed summary interface (for the global feed list) export interface FeedListItem { id: string; title: string; description?: string; } // WebSub (PubSubHubbub) subscription configuration export interface WebSubSubscription { callbackUrl: string; secret?: string; expiresAt: number; // Unix timestamp ms format?: "rss" | "atom"; } // Declare KVNamespace for TypeScript declare global { // This is not an ideal solution but works for our example interface KVNamespace { get(key: string, options?: { type: "text" }): Promise; get(key: string, options: { type: "json" }): Promise; get( key: string, options: { type: "arrayBuffer" }, ): Promise; get( key: string, options: { type: "stream" }, ): Promise; put( key: string, value: string | ArrayBuffer | ReadableStream | FormData, ): Promise; delete(key: string): Promise; list(options?: { prefix?: string; limit?: number; cursor?: string; }): Promise<{ keys: { name: string; expiration?: number }[]; list_complete: boolean; cursor?: string; }>; } }