scrapebadger 0.3.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -291
- package/dist/{index-Cg0sNluO.d.cts → index-CIZUd1Zr.d.cts} +319 -1
- package/dist/{index-Cg0sNluO.d.ts → index-CIZUd1Zr.d.ts} +319 -1
- package/dist/index.d.cts +1906 -104
- package/dist/index.d.ts +1906 -104
- package/dist/index.js +1044 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1020 -58
- package/dist/index.mjs.map +1 -1
- package/dist/twitter/index.d.cts +1 -1
- package/dist/twitter/index.d.ts +1 -1
- package/dist/twitter/index.js +207 -1
- package/dist/twitter/index.js.map +1 -1
- package/dist/twitter/index.mjs +207 -2
- package/dist/twitter/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/exceptions.ts","../src/internal/client.ts","../src/internal/config.ts","../src/internal/pagination.ts","../src/twitter/tweets.ts","../src/twitter/users.ts","../src/twitter/lists.ts","../src/twitter/communities.ts","../src/twitter/trends.ts","../src/twitter/geo.ts","../src/twitter/stream.ts","../src/twitter/client.ts","../src/web/client.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Custom exceptions for the ScrapeBadger SDK.\n */\n\n/**\n * Base error class for all ScrapeBadger errors.\n */\nexport class ScrapeBadgerError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ScrapeBadgerError\";\n Object.setPrototypeOf(this, ScrapeBadgerError.prototype);\n }\n}\n\n/**\n * Raised when authentication fails (invalid or missing API key).\n */\nexport class AuthenticationError extends ScrapeBadgerError {\n constructor(message = \"Authentication failed. Check your API key.\") {\n super(message);\n this.name = \"AuthenticationError\";\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Raised when rate limit is exceeded.\n */\nexport class RateLimitError extends ScrapeBadgerError {\n /** Unix timestamp when the rate limit resets */\n readonly retryAfter: number | undefined;\n /** Maximum requests per minute for this tier */\n readonly limit: number | undefined;\n /** Remaining requests in the current window */\n readonly remaining: number | undefined;\n\n constructor(\n message = \"Rate limit exceeded.\",\n options?: { retryAfter?: number; limit?: number; remaining?: number }\n ) {\n super(message);\n this.name = \"RateLimitError\";\n this.retryAfter = options?.retryAfter;\n this.limit = options?.limit;\n this.remaining = options?.remaining;\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * Raised when the requested resource is not found.\n */\nexport class NotFoundError extends ScrapeBadgerError {\n /** The resource type that was not found */\n readonly resourceType: string | undefined;\n /** The resource ID that was not found */\n readonly resourceId: string | undefined;\n\n constructor(message = \"Resource not found.\", resourceType?: string, resourceId?: string) {\n super(message);\n this.name = \"NotFoundError\";\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n\n/**\n * Raised when the request is invalid.\n */\nexport class ValidationError extends ScrapeBadgerError {\n /** Validation errors by field */\n readonly errors: Record<string, string[]> | undefined;\n\n constructor(message = \"Validation error.\", errors?: Record<string, string[]>) {\n super(message);\n this.name = \"ValidationError\";\n this.errors = errors;\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\n/**\n * Raised when an internal server error occurs.\n */\nexport class ServerError extends ScrapeBadgerError {\n /** HTTP status code */\n readonly statusCode: number;\n\n constructor(message = \"Internal server error.\", statusCode = 500) {\n super(message);\n this.name = \"ServerError\";\n this.statusCode = statusCode;\n Object.setPrototypeOf(this, ServerError.prototype);\n }\n}\n\n/**\n * Raised when the request times out.\n */\nexport class TimeoutError extends ScrapeBadgerError {\n /** Timeout duration in milliseconds */\n readonly timeout: number;\n\n constructor(message = \"Request timed out.\", timeout: number) {\n super(message);\n this.name = \"TimeoutError\";\n this.timeout = timeout;\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Raised when the account has insufficient credits.\n */\nexport class InsufficientCreditsError extends ScrapeBadgerError {\n /** Current credit balance */\n readonly creditsBalance: number | undefined;\n\n constructor(message = \"Insufficient credits.\", creditsBalance?: number) {\n super(message);\n this.name = \"InsufficientCreditsError\";\n this.creditsBalance = creditsBalance;\n Object.setPrototypeOf(this, InsufficientCreditsError.prototype);\n }\n}\n\n/**\n * Raised when the account is restricted.\n */\nexport class AccountRestrictedError extends ScrapeBadgerError {\n /** Reason for the restriction */\n readonly reason: string | undefined;\n\n constructor(message = \"Account restricted.\", reason?: string) {\n super(message);\n this.name = \"AccountRestrictedError\";\n this.reason = reason;\n Object.setPrototypeOf(this, AccountRestrictedError.prototype);\n }\n}\n\n/**\n * Raised when a resource conflict occurs (e.g. duplicate monitor name).\n *\n * Maps to HTTP 409 Conflict.\n *\n * @example\n * ```typescript\n * import { ConflictError } from \"scrapebadger\";\n *\n * try {\n * await client.twitter.stream.createMonitor({\n * name: \"Existing Monitor\",\n * usernames: [\"elonmusk\"],\n * pollIntervalSeconds: 10,\n * });\n * } catch (err) {\n * if (err instanceof ConflictError) {\n * console.error(\"Monitor name already exists:\", err.message);\n * }\n * }\n * ```\n */\nexport class ConflictError extends ScrapeBadgerError {\n constructor(message = \"Resource conflict.\") {\n super(message);\n this.name = \"ConflictError\";\n Object.setPrototypeOf(this, ConflictError.prototype);\n }\n}\n\n/**\n * Raised when the WebSocket stream connection fails or is terminated.\n *\n * Common codes:\n * - 4001 -- Invalid or missing API key (auth failure)\n * - 4003 -- Connection limit exceeded (max 5 per API key)\n * - 1001 -- Server closed due to pong timeout\n * - 0 -- Unknown/parse error\n *\n * @example\n * ```typescript\n * import { WebSocketStreamError } from \"scrapebadger\";\n *\n * try {\n * for await (const event of client.twitter.stream.connectIter()) {\n * // ...\n * }\n * } catch (err) {\n * if (err instanceof WebSocketStreamError && err.code === 4001) {\n * console.error(\"API key rejected -- check your key\");\n * }\n * }\n * ```\n */\nexport class WebSocketStreamError extends ScrapeBadgerError {\n /** WebSocket close code or server error code */\n readonly code: number | undefined;\n\n constructor(message = \"WebSocket stream error\", code?: number) {\n super(message);\n this.name = \"WebSocketStreamError\";\n this.code = code;\n Object.setPrototypeOf(this, WebSocketStreamError.prototype);\n }\n}\n","/**\n * Base HTTP client with retry logic and error handling.\n */\n\nimport type { ResolvedConfig } from \"./config.js\";\nimport {\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n ValidationError,\n ServerError,\n TimeoutError,\n InsufficientCreditsError,\n AccountRestrictedError,\n ConflictError,\n ScrapeBadgerError,\n} from \"./exceptions.js\";\n\nexport interface RateLimit {\n limit: number;\n remaining: number;\n reset: number; // unix timestamp\n}\n\nexport interface ResponseWithHeaders<T> {\n data: T;\n rateLimit?: RateLimit;\n}\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\ninterface ErrorResponse {\n detail?: string;\n message?: string;\n errors?: Record<string, string[]>;\n limit?: number;\n remaining?: number;\n reset_at?: number;\n reason?: string;\n credits_balance?: number;\n}\n\n/**\n * Base HTTP client for making API requests.\n */\nexport class BaseClient {\n readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * Make an HTTP request to the API.\n */\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { data } = await this.requestRaw<T>(path, options);\n return data;\n }\n\n /**\n * Make an HTTP request and return both data and rate limit headers.\n */\n async requestWithHeaders<T>(\n path: string,\n options: RequestOptions = {}\n ): Promise<ResponseWithHeaders<T>> {\n return this.requestRaw<T>(path, options);\n }\n\n /**\n * Internal method that builds the request and executes it, returning data and rate limit info.\n */\n private async requestRaw<T>(\n path: string,\n options: RequestOptions = {}\n ): Promise<ResponseWithHeaders<T>> {\n const { method = \"GET\", params, body, headers = {} } = options;\n\n // Build URL with query parameters\n const url = new URL(path, this.config.baseUrl);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n // Build headers\n const requestHeaders: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n \"X-API-Key\": this.config.apiKey,\n \"User-Agent\": \"scrapebadger-node/0.3.1\",\n ...headers,\n };\n\n // Build request options\n const fetchOptions: RequestInit = {\n method,\n headers: requestHeaders,\n };\n\n if (body && method !== \"GET\") {\n fetchOptions.body = JSON.stringify(body);\n }\n\n // Execute with retry logic\n return this.executeWithRetry<T>(url.toString(), fetchOptions);\n }\n\n /**\n * Execute request with exponential backoff retry logic.\n */\n private async executeWithRetry<T>(\n url: string,\n options: RequestInit\n ): Promise<ResponseWithHeaders<T>> {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {\n try {\n const httpResponse = await this.fetchWithTimeout(url, options);\n const data = await this.handleResponse<T>(httpResponse);\n const rateLimit = this.parseRateLimitHeaders(httpResponse.headers);\n return { data, rateLimit };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on client errors (4xx) except rate limits\n if (error instanceof ScrapeBadgerError && !(error instanceof RateLimitError)) {\n throw error;\n }\n\n // Don't retry after exhausting attempts\n if (attempt === this.config.maxRetries) {\n break;\n }\n\n // Calculate delay with exponential backoff\n const delay = this.config.retryDelay * Math.pow(2, attempt);\n const delaySec = Math.round(delay / 1000);\n const attemptNum = attempt + 1;\n const maxRetries = this.config.maxRetries;\n\n // Warn with ANSI yellow coloring\n if (error instanceof RateLimitError) {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: 429 Rate Limited — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n // For rate limits, use retry-after if available\n if (error.retryAfter) {\n const retryDelay = (error.retryAfter - Date.now() / 1000) * 1000;\n if (retryDelay > 0 && retryDelay < 60000) {\n await this.sleep(retryDelay);\n continue;\n }\n }\n } else if (error instanceof TimeoutError) {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: TimeoutError — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n } else if (error instanceof ServerError) {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: ${error.statusCode} ${error.message} — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n } else {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: ${(error as Error).name} — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n }\n\n await this.sleep(delay);\n }\n }\n\n throw lastError ?? new ScrapeBadgerError(\"Request failed after retries\");\n }\n\n /**\n * Parse rate limit headers from an HTTP response.\n */\n private parseRateLimitHeaders(headers: Headers): RateLimit | undefined {\n const limit = headers.get(\"X-RateLimit-Limit\");\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n const reset = headers.get(\"X-RateLimit-Reset\");\n\n if (limit === null || remaining === null || reset === null) {\n return undefined;\n }\n\n const parsedLimit = parseInt(limit, 10);\n const parsedRemaining = parseInt(remaining, 10);\n const parsedReset = parseInt(reset, 10);\n\n if (isNaN(parsedLimit) || isNaN(parsedRemaining) || isNaN(parsedReset)) {\n return undefined;\n }\n\n return { limit: parsedLimit, remaining: parsedRemaining, reset: parsedReset };\n }\n\n /**\n * Fetch with timeout support.\n */\n private async fetchWithTimeout(url: string, options: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n return response;\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new TimeoutError(\n `Request timed out after ${this.config.timeout}ms`,\n this.config.timeout\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Handle HTTP response and convert errors.\n */\n private async handleResponse<T>(response: Response): Promise<T> {\n // Parse response body\n let data: T | ErrorResponse;\n const contentType = response.headers.get(\"content-type\");\n\n if (contentType?.includes(\"application/json\")) {\n data = (await response.json()) as T | ErrorResponse;\n } else {\n const text = await response.text();\n data = { detail: text } as ErrorResponse;\n }\n\n // Handle success\n if (response.ok) {\n return data as T;\n }\n\n // Handle errors\n const errorData = data as ErrorResponse;\n const message = errorData.detail ?? errorData.message ?? \"Request failed\";\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message);\n\n case 402:\n throw new InsufficientCreditsError(message, errorData.credits_balance);\n\n case 403:\n if (message.toLowerCase().includes(\"restricted\")) {\n throw new AccountRestrictedError(message, errorData.reason);\n }\n throw new AuthenticationError(message);\n\n case 404:\n throw new NotFoundError(message);\n\n case 409:\n throw new ConflictError(message);\n\n case 422:\n throw new ValidationError(message, errorData.errors);\n\n case 429:\n throw new RateLimitError(message, {\n retryAfter: errorData.reset_at,\n limit: errorData.limit,\n remaining: errorData.remaining,\n });\n\n default:\n if (response.status >= 500) {\n throw new ServerError(message, response.status);\n }\n throw new ScrapeBadgerError(message);\n }\n }\n\n /**\n * Sleep for a given duration.\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * Configuration management for the ScrapeBadger SDK.\n */\n\nexport interface ScrapeBadgerConfig {\n /** API key for authentication */\n apiKey: string;\n /** Base URL for the API (default: https://scrapebadger.com) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Maximum number of retry attempts (default: 3) */\n maxRetries?: number;\n /** Initial retry delay in milliseconds (default: 1000) */\n retryDelay?: number;\n}\n\nexport interface ResolvedConfig {\n apiKey: string;\n baseUrl: string;\n timeout: number;\n maxRetries: number;\n retryDelay: number;\n}\n\nconst DEFAULT_BASE_URL = \"https://scrapebadger.com\";\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_MAX_RETRIES = 10;\nconst DEFAULT_RETRY_DELAY = 1000;\n\n/**\n * Resolve configuration with defaults.\n */\nexport function resolveConfig(config: ScrapeBadgerConfig): ResolvedConfig {\n if (!config.apiKey) {\n throw new Error(\"API key is required\");\n }\n\n return {\n apiKey: config.apiKey,\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n retryDelay: config.retryDelay ?? DEFAULT_RETRY_DELAY,\n };\n}\n\n/**\n * Load API key from environment variable.\n */\nexport function getApiKeyFromEnv(): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env.SCRAPEBADGER_API_KEY;\n }\n return undefined;\n}\n","/**\n * Pagination utilities for the ScrapeBadger SDK.\n */\n\nimport type { RateLimit } from \"./client.js\";\n\n/**\n * Response wrapper for paginated API responses.\n */\nexport interface PaginatedResponse<T> {\n /** Array of items in the current page */\n data: T[];\n /** Cursor for the next page, if available */\n nextCursor?: string;\n /** Whether there are more pages available */\n hasMore: boolean;\n}\n\n/**\n * Options for paginated requests.\n */\nexport interface PaginationOptions {\n /** Maximum number of items to fetch per request (default: 20) */\n count?: number;\n /** Cursor for pagination */\n cursor?: string;\n}\n\n/**\n * Options for async iteration.\n */\nexport interface IteratorOptions extends PaginationOptions {\n /** Maximum total number of items to fetch (default: unlimited) */\n maxItems?: number;\n}\n\n/**\n * Page result returned by fetchPage callbacks passed to paginate().\n */\nexport interface PageResult<T> {\n response: PaginatedResponse<T>;\n rateLimit?: RateLimit;\n}\n\n/**\n * Create a paginated response from API response data.\n */\nexport function createPaginatedResponse<T>(\n data: T[],\n cursor?: string\n): PaginatedResponse<T> {\n return {\n data,\n nextCursor: cursor,\n hasMore: !!cursor,\n };\n}\n\nconst RATE_LIMIT_WARN_THRESHOLD = 0.2;\n\n/**\n * Async generator for paginating through API results.\n *\n * Automatically throttles when fewer than 20% of rate limit requests remain,\n * spreading requests across the remaining reset window.\n *\n * @param fetchPage - Function to fetch a single page; returns response + optional rate limit info\n * @param options - Pagination options\n * @yields Individual items from each page\n *\n * @example\n * ```typescript\n * // Iterate through all results\n * for await (const tweet of client.twitter.tweets.searchAll(\"query\")) {\n * console.log(tweet.text);\n * }\n *\n * // With max items limit\n * for await (const tweet of client.twitter.tweets.searchAll(\"query\", { maxItems: 100 })) {\n * console.log(tweet.text);\n * }\n * ```\n */\nexport async function* paginate<T>(\n fetchPage: (cursor?: string) => Promise<PageResult<T>>,\n options: IteratorOptions = {}\n): AsyncGenerator<T, void, undefined> {\n const { maxItems } = options;\n let cursor: string | undefined;\n let totalYielded = 0;\n\n do {\n const { response, rateLimit } = await fetchPage(cursor);\n\n // Throttle pagination when approaching rate limit\n if (rateLimit) {\n const { limit, remaining, reset } = rateLimit;\n if (limit > 0 && remaining / limit < RATE_LIMIT_WARN_THRESHOLD) {\n const nowSec = Date.now() / 1000;\n const windowRemainingSec = Math.max(reset - nowSec, 1);\n const delayMs = remaining > 0 ? (windowRemainingSec / remaining) * 1000 : windowRemainingSec * 1000;\n const resetInSec = Math.round(windowRemainingSec);\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: Rate limit: ${remaining}/${limit} remaining (resets in ${resetInSec}s), throttling pagination\\x1b[0m`\n );\n await sleep(delayMs);\n }\n }\n\n for (const item of response.data) {\n yield item;\n totalYielded++;\n\n if (maxItems !== undefined && totalYielded >= maxItems) {\n return;\n }\n }\n\n cursor = response.nextCursor;\n } while (cursor);\n}\n\n/**\n * Collect all items from an async generator into an array.\n *\n * @param generator - Async generator to collect from\n * @returns Array of all yielded items\n *\n * @example\n * ```typescript\n * const tweets = await collectAll(client.twitter.tweets.searchAll(\"query\", { maxItems: 100 }));\n * console.log(`Fetched ${tweets.length} tweets`);\n * ```\n */\nexport async function collectAll<T>(generator: AsyncGenerator<T, void, undefined>): Promise<T[]> {\n const items: T[] = [];\n for await (const item of generator) {\n items.push(item);\n }\n return items;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Twitter Tweets API client.\n *\n * Provides methods for fetching tweets, searching, and getting tweet metadata.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { Tweet, User, QueryType } from \"./types.js\";\n\n/**\n * Client for Twitter tweets endpoints.\n *\n * Provides async methods for fetching individual tweets, searching tweets,\n * and getting tweet engagement data (retweeters, favoriters, replies).\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get single tweet\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n *\n * // Search tweets\n * const results = await client.twitter.tweets.search(\"python programming\");\n * for (const tweet of results.data) {\n * console.log(tweet.text);\n * }\n *\n * // Iterate through all results\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\")) {\n * console.log(tweet.text);\n * }\n * ```\n */\nexport class TweetsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get a single tweet by ID.\n *\n * @param tweetId - The tweet ID to fetch.\n * @returns The tweet data.\n * @throws NotFoundError - If the tweet doesn't exist.\n * @throws AuthenticationError - If the API key is invalid.\n *\n * @example\n * ```typescript\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n * console.log(`@${tweet.username}: ${tweet.text}`);\n * ```\n */\n async getById(tweetId: string): Promise<Tweet> {\n return this.client.request<Tweet>(`/v1/twitter/tweets/tweet/${tweetId}`);\n }\n\n /**\n * Get multiple tweets by their IDs.\n *\n * @param tweetIds - List of tweet IDs to fetch.\n * @returns Paginated response containing the tweets.\n *\n * @example\n * ```typescript\n * const tweets = await client.twitter.tweets.getByIds([\n * \"1234567890\",\n * \"0987654321\"\n * ]);\n * for (const tweet of tweets.data) {\n * console.log(tweet.text);\n * }\n * ```\n */\n async getByIds(tweetIds: string[]): Promise<PaginatedResponse<Tweet>> {\n const tweetsParam = tweetIds.join(\",\");\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n \"/v1/twitter/tweets/\",\n { params: { tweets: tweetsParam } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get replies to a tweet.\n *\n * @param tweetId - The tweet ID to get replies for.\n * @param options - Pagination options.\n * @returns Paginated response containing reply tweets.\n *\n * @example\n * ```typescript\n * const replies = await client.twitter.tweets.getReplies(\"1234567890\");\n * for (const reply of replies.data) {\n * console.log(`@${reply.username}: ${reply.text}`);\n * }\n *\n * // Get next page\n * if (replies.hasMore) {\n * const more = await client.twitter.tweets.getReplies(\"1234567890\", {\n * cursor: replies.nextCursor\n * });\n * }\n * ```\n */\n async getReplies(\n tweetId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/replies`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get users who retweeted a tweet.\n *\n * @param tweetId - The tweet ID to get retweeters for.\n * @param options - Pagination options.\n * @returns Paginated response containing users who retweeted.\n *\n * @example\n * ```typescript\n * const retweeters = await client.twitter.tweets.getRetweeters(\"1234567890\");\n * for (const user of retweeters.data) {\n * console.log(`@${user.username} retweeted`);\n * }\n * ```\n */\n async getRetweeters(\n tweetId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/retweeters`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get users who liked/favorited a tweet.\n *\n * @param tweetId - The tweet ID to get favoriters for.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing users who liked.\n *\n * @example\n * ```typescript\n * const likers = await client.twitter.tweets.getFavoriters(\"1234567890\");\n * console.log(`${likers.data.length} users liked this tweet`);\n * ```\n */\n async getFavoriters(\n tweetId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/favoriters`,\n { params: { count: options.count ?? 40, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get tweets similar to a given tweet.\n *\n * @param tweetId - The tweet ID to find similar tweets for.\n * @returns Paginated response containing similar tweets.\n *\n * @example\n * ```typescript\n * const similar = await client.twitter.tweets.getSimilar(\"1234567890\");\n * for (const tweet of similar.data) {\n * console.log(`Similar: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getSimilar(tweetId: string): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/similar`\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get tweets that quote a specific tweet.\n *\n * @param tweetId - The tweet ID to get quote tweets for.\n * @param options - Pagination options.\n * @returns Paginated response containing tweets that quote this tweet.\n *\n * @example\n * ```typescript\n * const quotes = await client.twitter.tweets.getQuotes(\"1234567890\");\n * for (const quote of quotes.data) {\n * console.log(`@${quote.username} quoted: ${quote.text.slice(0, 100)}...`);\n * }\n *\n * // Get next page\n * if (quotes.hasMore) {\n * const more = await client.twitter.tweets.getQuotes(\"1234567890\", {\n * cursor: quotes.nextCursor\n * });\n * }\n * ```\n */\n async getQuotes(\n tweetId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/quotes`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all quote tweets with automatic pagination.\n *\n * This is a convenience method that automatically handles pagination,\n * yielding quote tweets one at a time.\n *\n * @param tweetId - The tweet ID to get quote tweets for.\n * @param options - Iteration options.\n * @yields Tweet objects that quote the specified tweet.\n *\n * @example\n * ```typescript\n * // Get all quote tweets (up to 500)\n * for await (const quote of client.twitter.tweets.getQuotesAll(\"1234567890\", {\n * maxItems: 500\n * })) {\n * console.log(`@${quote.username}: ${quote.text}`);\n * }\n *\n * // Collect into an array\n * import { collectAll } from \"scrapebadger\";\n * const quotes = await collectAll(\n * client.twitter.tweets.getQuotesAll(\"1234567890\", { maxItems: 100 })\n * );\n * ```\n */\n async *getQuotesAll(\n tweetId: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/tweets/tweet/${tweetId}/quotes`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Search for tweets.\n *\n * @param query - Search query string. Supports Twitter advanced search operators.\n * @param options - Search options including query type and pagination.\n * @returns Paginated response containing matching tweets.\n *\n * @example\n * ```typescript\n * // Basic search\n * const results = await client.twitter.tweets.search(\"python programming\");\n *\n * // Latest tweets only\n * const latest = await client.twitter.tweets.search(\"python\", {\n * queryType: \"Latest\"\n * });\n *\n * // Advanced search operators\n * const fromUser = await client.twitter.tweets.search(\"from:elonmusk lang:en\");\n * ```\n */\n async search(\n query: string,\n options: PaginationOptions & { queryType?: QueryType; count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n \"/v1/twitter/tweets/advanced_search\",\n {\n params: {\n query,\n query_type: options.queryType ?? \"Top\",\n count: options.count,\n cursor: options.cursor,\n },\n }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all search results with automatic pagination.\n *\n * This is a convenience method that automatically handles pagination,\n * yielding tweets one at a time.\n *\n * @param query - Search query string.\n * @param options - Search and iteration options.\n * @yields Tweet objects matching the search query.\n *\n * @example\n * ```typescript\n * // Get up to 1000 tweets\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\", {\n * maxItems: 1000\n * })) {\n * console.log(tweet.text);\n * }\n *\n * // Collect into an array\n * import { collectAll } from \"scrapebadger\";\n * const tweets = await collectAll(\n * client.twitter.tweets.searchAll(\"python\", { maxItems: 100 })\n * );\n * ```\n */\n async *searchAll(\n query: string,\n options: IteratorOptions & { queryType?: QueryType; count?: number } = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(\"/v1/twitter/tweets/advanced_search\", {\n params: {\n query,\n query_type: options.queryType ?? \"Top\",\n count: options.count,\n cursor,\n },\n });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get tweets from a user's timeline.\n *\n * @param username - Twitter username (without @).\n * @param options - Pagination options.\n * @returns Paginated response containing the user's tweets.\n *\n * @example\n * ```typescript\n * const tweets = await client.twitter.tweets.getUserTweets(\"elonmusk\");\n * for (const tweet of tweets.data) {\n * console.log(`${tweet.created_at}: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getUserTweets(\n username: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/latest_tweets`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all tweets from a user with automatic pagination.\n *\n * @param username - Twitter username (without @).\n * @param options - Iteration options.\n * @yields Tweet objects from the user's timeline.\n *\n * @example\n * ```typescript\n * for await (const tweet of client.twitter.tweets.getUserTweetsAll(\"elonmusk\", {\n * maxItems: 500\n * })) {\n * console.log(tweet.text);\n * }\n * ```\n */\n async *getUserTweetsAll(\n username: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/users/${username}/latest_tweets`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n}\n","/**\n * Twitter Users API client.\n *\n * Provides methods for fetching user profiles, followers, following, and related data.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { User, UserAbout, UserIds, Tweet } from \"./types.js\";\n\n/**\n * Client for Twitter users endpoints.\n *\n * Provides async methods for fetching user profiles, followers, following,\n * and other user-related data.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get user profile\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n * console.log(`${user.name}: ${user.followers_count.toLocaleString()} followers`);\n *\n * // Get followers\n * const followers = await client.twitter.users.getFollowers(\"elonmusk\");\n *\n * // Iterate through all followers\n * for await (const follower of client.twitter.users.getFollowersAll(\"elonmusk\")) {\n * console.log(follower.username);\n * }\n * ```\n */\nexport class UsersClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get a user by their numeric ID.\n *\n * @param userId - The user's numeric ID.\n * @returns The user profile.\n * @throws NotFoundError - If the user doesn't exist.\n *\n * @example\n * ```typescript\n * const user = await client.twitter.users.getById(\"44196397\");\n * console.log(`@${user.username}`);\n * ```\n */\n async getById(userId: string): Promise<User> {\n return this.client.request<User>(`/v1/twitter/users/${userId}/by_id`);\n }\n\n /**\n * Get a user by their username.\n *\n * @param username - The user's username (without @).\n * @returns The user profile.\n * @throws NotFoundError - If the user doesn't exist.\n *\n * @example\n * ```typescript\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n * console.log(`${user.name} has ${user.followers_count.toLocaleString()} followers`);\n * ```\n */\n async getByUsername(username: string): Promise<User> {\n return this.client.request<User>(`/v1/twitter/users/${username}/by_username`);\n }\n\n /**\n * Get extended \"About\" information for a user.\n *\n * Returns additional metadata including account location,\n * username change history, and verification details.\n *\n * @param username - The user's username (without @).\n * @returns Extended user information.\n *\n * @example\n * ```typescript\n * const about = await client.twitter.users.getAbout(\"elonmusk\");\n * console.log(`Account based in: ${about.account_based_in}`);\n * console.log(`Username changes: ${about.username_changes}`);\n * ```\n */\n async getAbout(username: string): Promise<UserAbout> {\n return this.client.request<UserAbout>(`/v1/twitter/users/${username}/about`);\n }\n\n /**\n * Get a user's followers.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options.\n * @returns Paginated response containing follower users.\n *\n * @example\n * ```typescript\n * const followers = await client.twitter.users.getFollowers(\"elonmusk\");\n * for (const user of followers.data) {\n * console.log(`@${user.username}`);\n * }\n *\n * // Get next page\n * if (followers.hasMore) {\n * const more = await client.twitter.users.getFollowers(\"elonmusk\", {\n * cursor: followers.nextCursor\n * });\n * }\n * ```\n */\n async getFollowers(\n username: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/followers`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all followers with automatic pagination.\n *\n * @param username - The user's username (without @).\n * @param options - Iteration options.\n * @yields User objects for each follower.\n *\n * @example\n * ```typescript\n * for await (const follower of client.twitter.users.getFollowersAll(\"elonmusk\", {\n * maxItems: 1000\n * })) {\n * console.log(follower.username);\n * }\n * ```\n */\n async *getFollowersAll(\n username: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(`/v1/twitter/users/${username}/followers`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get users that a user is following.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options.\n * @returns Paginated response containing followed users.\n *\n * @example\n * ```typescript\n * const following = await client.twitter.users.getFollowing(\"elonmusk\");\n * for (const user of following.data) {\n * console.log(`Follows @${user.username}`);\n * }\n * ```\n */\n async getFollowing(\n username: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/followings`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all following with automatic pagination.\n *\n * @param username - The user's username (without @).\n * @param options - Iteration options.\n * @yields User objects for each followed account.\n */\n async *getFollowingAll(\n username: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(`/v1/twitter/users/${username}/followings`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get a user's most recent followers.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing recent followers.\n */\n async getLatestFollowers(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/latest_followers`,\n { params: { count: options.count ?? 200, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get accounts a user most recently followed.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing recently followed users.\n */\n async getLatestFollowing(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/latest_following`,\n { params: { count: options.count ?? 200, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get follower IDs for a user.\n *\n * More efficient than getFollowers when you only need IDs.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns UserIds containing list of follower IDs.\n *\n * @example\n * ```typescript\n * const ids = await client.twitter.users.getFollowerIds(\"elonmusk\");\n * console.log(`Found ${ids.ids.length.toLocaleString()} follower IDs`);\n * ```\n */\n async getFollowerIds(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<UserIds> {\n const response = await this.client.request<{ data?: { ids?: number[]; next_cursor?: string } }>(\n `/v1/twitter/users/${username}/follower_ids`,\n { params: { count: options.count ?? 5000, cursor: options.cursor } }\n );\n return {\n ids: response.data?.ids ?? [],\n next_cursor: response.data?.next_cursor,\n };\n }\n\n /**\n * Get following IDs for a user.\n *\n * More efficient than getFollowing when you only need IDs.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns UserIds containing list of following IDs.\n */\n async getFollowingIds(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<UserIds> {\n const response = await this.client.request<{ data?: { ids?: number[]; next_cursor?: string } }>(\n `/v1/twitter/users/${username}/following_ids`,\n { params: { count: options.count ?? 5000, cursor: options.cursor } }\n );\n return {\n ids: response.data?.ids ?? [],\n next_cursor: response.data?.next_cursor,\n };\n }\n\n /**\n * Get verified followers for a user.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing verified followers.\n */\n async getVerifiedFollowers(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/verified_followers`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get followers that the authenticated user also follows.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing mutual connections.\n */\n async getFollowersYouKnow(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/followers_you_know`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get premium accounts that a user subscribes to.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing subscribed accounts.\n */\n async getSubscriptions(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/subscriptions`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get a user's highlighted tweets.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing highlighted tweets.\n */\n async getHighlights(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/highlights`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search for users.\n *\n * @param query - Search query string.\n * @param options - Pagination options.\n * @returns Paginated response containing matching users.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.users.search(\"python developer\");\n * for (const user of results.data) {\n * console.log(`@${user.username}: ${user.description}`);\n * }\n * ```\n */\n async search(query: string, options: PaginationOptions = {}): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n \"/v1/twitter/users/search_users\",\n { params: { query, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all search results with automatic pagination.\n *\n * @param query - Search query string.\n * @param options - Iteration options.\n * @yields User objects matching the search query.\n */\n async *searchAll(\n query: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(\"/v1/twitter/users/search_users\", { params: { query, cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n}\n","/**\n * Twitter Lists API client.\n *\n * Provides methods for fetching Twitter lists, list members, and list tweets.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { List, Tweet, User } from \"./types.js\";\n\n/**\n * Client for Twitter lists endpoints.\n *\n * Provides async methods for fetching list details, members, subscribers,\n * and tweets from lists.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search for lists\n * const lists = await client.twitter.lists.search(\"tech leaders\");\n *\n * // Get list details\n * const list = await client.twitter.lists.getDetail(\"123456\");\n * console.log(`${list.name}: ${list.member_count} members`);\n *\n * // Get list tweets\n * const tweets = await client.twitter.lists.getTweets(\"123456\");\n * ```\n */\nexport class ListsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get details for a specific list.\n *\n * @param listId - The list ID.\n * @returns The list details.\n * @throws NotFoundError - If the list doesn't exist.\n *\n * @example\n * ```typescript\n * const list = await client.twitter.lists.getDetail(\"123456\");\n * console.log(`${list.name} by @${list.username}`);\n * console.log(`${list.member_count} members, ${list.subscriber_count} subscribers`);\n * ```\n */\n async getDetail(listId: string): Promise<List> {\n return this.client.request<List>(`/v1/twitter/lists/${listId}/detail`);\n }\n\n /**\n * Get tweets from a list's timeline.\n *\n * @param listId - The list ID.\n * @param options - Pagination options.\n * @returns Paginated response containing tweets from list members.\n *\n * @example\n * ```typescript\n * const tweets = await client.twitter.lists.getTweets(\"123456\");\n * for (const tweet of tweets.data) {\n * console.log(`@${tweet.username}: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getTweets(\n listId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/tweets`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all list tweets with automatic pagination.\n *\n * @param listId - The list ID.\n * @param options - Iteration options.\n * @yields Tweet objects from the list timeline.\n */\n async *getTweetsAll(\n listId: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/lists/${listId}/tweets`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get members of a list.\n *\n * @param listId - The list ID.\n * @param options - Pagination options.\n * @returns Paginated response containing list members.\n *\n * @example\n * ```typescript\n * const members = await client.twitter.lists.getMembers(\"123456\");\n * for (const user of members.data) {\n * console.log(`@${user.username}`);\n * }\n * ```\n */\n async getMembers(\n listId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/members`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all list members with automatic pagination.\n *\n * @param listId - The list ID.\n * @param options - Iteration options.\n * @yields User objects for each list member.\n */\n async *getMembersAll(\n listId: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(`/v1/twitter/lists/${listId}/members`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get subscribers of a list.\n *\n * @param listId - The list ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing list subscribers.\n */\n async getSubscribers(\n listId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/subscribers`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search for lists.\n *\n * @param query - Search query string.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing matching lists.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.lists.search(\"tech leaders\");\n * for (const list of results.data) {\n * console.log(`${list.name}: ${list.member_count} members`);\n * }\n * ```\n */\n async search(\n query: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<List>> {\n const response = await this.client.request<{ data?: List[]; next_cursor?: string }>(\n \"/v1/twitter/lists/search\",\n { params: { query, count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get lists owned by the authenticated user.\n *\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing the user's lists.\n */\n async getMyLists(\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<List>> {\n const response = await this.client.request<{ data?: List[]; next_cursor?: string }>(\n \"/v1/twitter/lists/my_lists\",\n { params: { count: options.count ?? 100, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n}\n","/**\n * Twitter Communities API client.\n *\n * Provides methods for fetching Twitter communities, members, and tweets.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { Community, CommunityMember, CommunityTweetType, Tweet } from \"./types.js\";\n\n/**\n * Client for Twitter communities endpoints.\n *\n * Provides async methods for fetching community details, members,\n * moderators, and tweets.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search communities\n * const communities = await client.twitter.communities.search(\"python\");\n *\n * // Get community details\n * const community = await client.twitter.communities.getDetail(\"123456\");\n * console.log(`${community.name}: ${community.member_count} members`);\n *\n * // Get community tweets\n * const tweets = await client.twitter.communities.getTweets(\"123456\");\n * ```\n */\nexport class CommunitiesClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Parse a community member from the API response.\n * Handles both flat format (user_id, username, role at top level)\n * and nested format (user object with id, username).\n */\n private parseCommunityMember(item: Record<string, unknown>): CommunityMember {\n if (\"user\" in item && item.user) {\n return item as unknown as CommunityMember;\n }\n // Flat format: map user_id -> id for User interface\n return {\n user: {\n id: (item.user_id as string) ?? \"\",\n username: (item.username as string) ?? \"\",\n name: (item.name as string) ?? \"\",\n profile_image_url: item.profile_image_url as string | undefined,\n verified: (item.verified as boolean) ?? false,\n is_blue_verified: item.is_blue_verified as boolean | undefined,\n },\n role: item.role as string | undefined,\n joined_at: item.joined_at as string | undefined,\n };\n }\n\n /**\n * Get details for a specific community.\n *\n * @param communityId - The community ID.\n * @returns The community details including rules and admin info.\n * @throws NotFoundError - If the community doesn't exist.\n *\n * @example\n * ```typescript\n * const community = await client.twitter.communities.getDetail(\"123456\");\n * console.log(`${community.name}`);\n * console.log(`Members: ${community.member_count?.toLocaleString()}`);\n * console.log(`Join policy: ${community.join_policy}`);\n *\n * if (community.rules) {\n * console.log(\"Rules:\");\n * for (const rule of community.rules) {\n * console.log(` - ${rule.name}`);\n * }\n * }\n * ```\n */\n async getDetail(communityId: string): Promise<Community> {\n return this.client.request<Community>(`/v1/twitter/communities/${communityId}`);\n }\n\n /**\n * Get tweets from a community.\n *\n * @param communityId - The community ID.\n * @param options - Options including tweet type, count, and pagination.\n * @returns Paginated response containing community tweets.\n *\n * @example\n * ```typescript\n * // Get top tweets\n * const tweets = await client.twitter.communities.getTweets(\"123456\");\n *\n * // Get latest tweets\n * const latest = await client.twitter.communities.getTweets(\"123456\", {\n * tweetType: \"Latest\"\n * });\n * ```\n */\n async getTweets(\n communityId: string,\n options: PaginationOptions & { tweetType?: CommunityTweetType; count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/communities/${communityId}/tweets`,\n {\n params: {\n tweet_type: options.tweetType ?? \"Top\",\n count: options.count ?? 40,\n cursor: options.cursor,\n },\n }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all community tweets with automatic pagination.\n *\n * @param communityId - The community ID.\n * @param options - Options including tweet type and iteration limits.\n * @yields Tweet objects from the community.\n */\n async *getTweetsAll(\n communityId: string,\n options: IteratorOptions & { tweetType?: CommunityTweetType } = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/communities/${communityId}/tweets`, {\n params: {\n tweet_type: options.tweetType ?? \"Top\",\n count: options.count ?? 40,\n cursor,\n },\n });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get members of a community.\n *\n * @param communityId - The community ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing community members.\n *\n * @example\n * ```typescript\n * const members = await client.twitter.communities.getMembers(\"123456\");\n * for (const member of members.data) {\n * console.log(`@${member.user.username} (${member.role})`);\n * }\n * ```\n */\n async getMembers(\n communityId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<CommunityMember>> {\n const response = await this.client.request<{\n data?: Record<string, unknown>[];\n next_cursor?: string;\n }>(`/v1/twitter/communities/${communityId}/members`, {\n params: { count: options.count ?? 20, cursor: options.cursor },\n });\n\n const data: CommunityMember[] = (response.data ?? []).map((item) =>\n this.parseCommunityMember(item)\n );\n\n return createPaginatedResponse(data, response.next_cursor);\n }\n\n /**\n * Get moderators of a community.\n *\n * @param communityId - The community ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing community moderators.\n */\n async getModerators(\n communityId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<CommunityMember>> {\n const response = await this.client.request<{\n data?: Record<string, unknown>[];\n next_cursor?: string;\n }>(`/v1/twitter/communities/${communityId}/moderators`, {\n params: { count: options.count ?? 20, cursor: options.cursor },\n });\n\n const data: CommunityMember[] = (response.data ?? []).map((item) =>\n this.parseCommunityMember(item)\n );\n\n return createPaginatedResponse(data, response.next_cursor);\n }\n\n /**\n * Search for communities.\n *\n * @param query - Search query string.\n * @param options - Pagination options.\n * @returns Paginated response containing matching communities.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.communities.search(\"python developers\");\n * for (const community of results.data) {\n * console.log(`${community.name}: ${community.member_count} members`);\n * }\n * ```\n */\n async search(\n query: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Community>> {\n const response = await this.client.request<{ data?: Community[]; next_cursor?: string }>(\n \"/v1/twitter/communities/search\",\n { params: { query, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search for tweets within a community.\n *\n * @param communityId - The community ID.\n * @param query - Search query string.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing matching tweets.\n */\n async searchTweets(\n communityId: string,\n query: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/communities/${communityId}/search_tweets`,\n { params: { query, count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get the community timeline (tweets from communities you're in).\n *\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing community timeline tweets.\n */\n async getTimeline(\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n \"/v1/twitter/communities/timeline\",\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n}\n","/**\n * Twitter Trends API client.\n *\n * Provides methods for fetching trending topics and trend locations.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { PaginatedResponse } from \"../internal/pagination.js\";\nimport { createPaginatedResponse } from \"../internal/pagination.js\";\nimport type { Trend, TrendCategory, Location, PlaceTrends } from \"./types.js\";\n\n/**\n * Client for Twitter trends endpoints.\n *\n * Provides async methods for fetching trending topics, place-specific trends,\n * and available trend locations.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get global trends\n * const trends = await client.twitter.trends.getTrends();\n * for (const trend of trends.data) {\n * console.log(`${trend.name}: ${trend.tweet_count || 'N/A'} tweets`);\n * }\n *\n * // Get trends for a specific location\n * const usTrends = await client.twitter.trends.getPlaceTrends(23424977);\n *\n * // Get available locations\n * const locations = await client.twitter.trends.getAvailableLocations();\n * ```\n */\nexport class TrendsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get trending topics.\n *\n * @param options - Options for filtering trends.\n * @returns Paginated response containing trending topics.\n *\n * @example\n * ```typescript\n * // Get general trending topics\n * const trends = await client.twitter.trends.getTrends();\n *\n * // Get news trends\n * const newsTrends = await client.twitter.trends.getTrends({\n * category: \"news\"\n * });\n *\n * for (const trend of trends.data) {\n * const count = trend.tweet_count?.toLocaleString() || \"N/A\";\n * console.log(`${trend.name}: ${count} tweets`);\n * }\n * ```\n */\n async getTrends(\n options: { category?: TrendCategory; count?: number } = {}\n ): Promise<PaginatedResponse<Trend>> {\n const response = await this.client.request<{ data?: Trend[] }>(\"/v1/twitter/trends/\", {\n params: {\n category: options.category ?? \"trending\",\n count: options.count ?? 20,\n },\n });\n return createPaginatedResponse(response.data ?? []);\n }\n\n /**\n * Get trends for a specific location.\n *\n * @param woeid - Where On Earth ID for the location.\n * Common WOEIDs:\n * - 1: Worldwide\n * - 23424977: United States\n * - 23424975: United Kingdom\n * - 23424856: Japan\n * - 23424829: Germany\n * @returns PlaceTrends containing location info and trends.\n * @throws NotFoundError - If the WOEID is invalid.\n *\n * @example\n * ```typescript\n * // Get US trends\n * const usTrends = await client.twitter.trends.getPlaceTrends(23424977);\n * console.log(`Trends in ${usTrends.name}:`);\n * for (const trend of usTrends.trends) {\n * console.log(` - ${trend.name}`);\n * }\n *\n * // Get worldwide trends\n * const globalTrends = await client.twitter.trends.getPlaceTrends(1);\n * ```\n */\n async getPlaceTrends(woeid: number): Promise<PlaceTrends> {\n return this.client.request<PlaceTrends>(`/v1/twitter/trends/place/${woeid}`);\n }\n\n /**\n * Get all locations where trends are available.\n *\n * @returns Paginated response containing available trend locations.\n *\n * @example\n * ```typescript\n * const locations = await client.twitter.trends.getAvailableLocations();\n *\n * // Filter by country\n * const usLocations = locations.data.filter(\n * loc => loc.country_code === \"US\"\n * );\n * console.log(`Found ${usLocations.length} US locations`);\n *\n * // Get countries only\n * const countries = locations.data.filter(\n * loc => loc.place_type === \"Country\"\n * );\n * ```\n */\n async getAvailableLocations(): Promise<PaginatedResponse<Location>> {\n const response = await this.client.request<{ data?: Location[] }>(\n \"/v1/twitter/trends/locations\"\n );\n return createPaginatedResponse(response.data ?? []);\n }\n}\n","/**\n * Twitter Geo API client.\n *\n * Provides methods for fetching geographic place information.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { PaginatedResponse } from \"../internal/pagination.js\";\nimport { createPaginatedResponse } from \"../internal/pagination.js\";\nimport type { Place } from \"./types.js\";\n\n/**\n * Options for searching places.\n */\nexport interface GeoSearchOptions {\n /** Latitude coordinate */\n lat?: number;\n /** Longitude coordinate */\n long?: number;\n /** Free-form text search query (e.g., \"San Francisco\") */\n query?: string;\n /** IP address for location lookup */\n ip?: string;\n /** Result granularity (\"neighborhood\", \"city\", \"admin\", \"country\") */\n granularity?: string;\n /** Maximum number of results (1-100) */\n maxResults?: number;\n}\n\n/**\n * Client for Twitter geo/places endpoints.\n *\n * Provides async methods for fetching place details and searching\n * for geographic locations.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search for places\n * const places = await client.twitter.geo.search({ query: \"San Francisco\" });\n *\n * // Search by coordinates\n * const nearby = await client.twitter.geo.search({ lat: 37.7749, long: -122.4194 });\n *\n * // Get place details\n * const place = await client.twitter.geo.getDetail(\"5a110d312052166f\");\n * ```\n */\nexport class GeoClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get details for a specific place.\n *\n * @param placeId - The Twitter place ID.\n * @returns The place details.\n * @throws NotFoundError - If the place doesn't exist.\n *\n * @example\n * ```typescript\n * const place = await client.twitter.geo.getDetail(\"5a110d312052166f\");\n * console.log(`${place.full_name}`);\n * console.log(`Type: ${place.place_type}`);\n * console.log(`Country: ${place.country}`);\n * ```\n */\n async getDetail(placeId: string): Promise<Place> {\n return this.client.request<Place>(`/v1/twitter/geo/places/${placeId}`);\n }\n\n /**\n * Search for geographic places.\n *\n * At least one of lat/long, query, or ip must be provided.\n *\n * @param options - Search options.\n * @returns Paginated response containing matching places.\n * @throws ValidationError - If no search parameters are provided.\n *\n * @example\n * ```typescript\n * // Search by name\n * const places = await client.twitter.geo.search({ query: \"San Francisco\" });\n * for (const place of places.data) {\n * console.log(`${place.full_name} (${place.place_type})`);\n * }\n *\n * // Search by coordinates\n * const nearby = await client.twitter.geo.search({\n * lat: 37.7749,\n * long: -122.4194,\n * granularity: \"city\"\n * });\n *\n * // Search by IP\n * const ipPlaces = await client.twitter.geo.search({ ip: \"8.8.8.8\" });\n * ```\n */\n async search(options: GeoSearchOptions = {}): Promise<PaginatedResponse<Place>> {\n const response = await this.client.request<{ data?: Place[] }>(\"/v1/twitter/geo/search\", {\n params: {\n lat: options.lat,\n long: options.long,\n query: options.query,\n ip: options.ip,\n granularity: options.granularity,\n max_results: options.maxResults,\n },\n });\n return createPaginatedResponse(response.data ?? []);\n }\n}\n","/**\n * StreamClient -- stream monitor management and live WebSocket streaming.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\nimport type { BaseClient } from \"../internal/client.js\";\nimport { WebSocketStreamError } from \"../internal/exceptions.js\";\nimport type {\n BillingLogList,\n ConnectOptions,\n ConnectedEvent,\n CreateMonitorParams,\n DeliveryLogList,\n ErrorEvent,\n FilterRuleCreate,\n FilterRuleDeliveryLogListResponse,\n FilterRuleListResponse,\n FilterRulePricingTiersResponse,\n FilterRuleResponse,\n FilterRuleUpdate,\n FilterRuleValidateResponse,\n PingEvent,\n StreamEvent,\n StreamMonitor,\n StreamMonitorList,\n StreamTweet,\n TweetEvent,\n UpdateMonitorParams,\n} from \"./stream-types.js\";\n\n// Minimum reconnect delay regardless of caller configuration (seconds)\nconst MIN_RECONNECT_DELAY_SECONDS = 5;\n\n/**\n * Derive WebSocket URL from HTTP base URL.\n * 'https://...' -> 'wss://...'\n * 'http://...' -> 'ws://...'\n */\nexport function wsUrlFromBase(baseUrl: string): string {\n if (baseUrl.startsWith(\"https://\")) {\n return baseUrl.replace(\"https://\", \"wss://\") + \"/v1/twitter/stream\";\n }\n if (baseUrl.startsWith(\"http://\")) {\n return baseUrl.replace(\"http://\", \"ws://\") + \"/v1/twitter/stream\";\n }\n return baseUrl + \"/v1/twitter/stream\";\n}\n\n/**\n * Map a raw server JSON object to a camelCase StreamEvent.\n * Unknown types return an ErrorEvent with code 0.\n */\nexport function parseEvent(raw: Record<string, unknown>): StreamEvent {\n const type = raw[\"type\"] as string | undefined;\n\n switch (type) {\n case \"connected\":\n return {\n type: \"connected\",\n connectionId: raw[\"connection_id\"] as string,\n apiKeyId: raw[\"api_key_id\"] as string,\n } satisfies ConnectedEvent;\n\n case \"ping\":\n return {\n type: \"ping\",\n timestamp: raw[\"timestamp\"] as string,\n } satisfies PingEvent;\n\n case \"tweet\":\n return {\n type: \"tweet\",\n monitorId: raw[\"monitor_id\"] as string,\n tweetId: raw[\"tweet_id\"] as string,\n authorUsername: raw[\"author_username\"] as string,\n tweetPublishedAt: raw[\"tweet_published_at\"] as string,\n detectedAt: raw[\"detected_at\"] as string,\n latencyMs: raw[\"latency_ms\"] as number,\n tweet: raw[\"tweet\"] as StreamTweet,\n } satisfies TweetEvent;\n\n case \"error\":\n return {\n type: \"error\",\n code: raw[\"code\"] as number,\n message: raw[\"message\"] as string,\n } satisfies ErrorEvent;\n\n default:\n return {\n type: \"error\",\n code: 0,\n message: `Unknown event type: ${String(type)}`,\n } satisfies ErrorEvent;\n }\n}\n\n/**\n * Typed EventEmitter for stream events.\n *\n * @example\n * ```typescript\n * const stream = client.twitter.stream.connect();\n * stream.on(\"tweet\", (event) => console.log(event.authorUsername));\n * stream.on(\"error\", (err) => console.error(err));\n * ```\n */\nexport interface StreamEmitter extends EventEmitter {\n on(event: \"connected\", listener: (event: ConnectedEvent) => void): this;\n on(event: \"ping\", listener: (event: PingEvent) => void): this;\n on(event: \"tweet\", listener: (event: TweetEvent) => void): this;\n on(event: \"error\", listener: (error: WebSocketStreamError) => void): this;\n on(event: \"close\", listener: () => void): this;\n\n once(event: \"connected\", listener: (event: ConnectedEvent) => void): this;\n once(event: \"tweet\", listener: (event: TweetEvent) => void): this;\n once(event: \"close\", listener: () => void): this;\n\n /** Gracefully close the WebSocket connection. */\n close(): void;\n}\n\n/**\n * Client for Twitter Streams -- monitor CRUD and live WebSocket streaming.\n *\n * Accessed as `client.twitter.stream`.\n *\n * @example Monitor CRUD\n * ```typescript\n * const monitor = await client.twitter.stream.createMonitor({\n * name: \"Tech Leaders\",\n * usernames: [\"elonmusk\", \"naval\"],\n * pollIntervalSeconds: 10,\n * });\n * console.log(`Created: ${monitor.id}, tier: ${monitor.pricing_tier}`);\n * ```\n *\n * @example EventEmitter streaming\n * ```typescript\n * const stream = client.twitter.stream.connect();\n * stream.on(\"tweet\", (event) => {\n * console.log(`@${event.authorUsername}: ${event.tweet.text}`);\n * console.log(` latency: ${event.latencyMs}ms`);\n * });\n * stream.on(\"error\", (err) => console.error(\"Stream error:\", err));\n * // Later:\n * stream.close();\n * ```\n *\n * @example AsyncIterator streaming\n * ```typescript\n * for await (const event of client.twitter.stream.connectIter()) {\n * if (event.type === \"tweet\") {\n * console.log(event.authorUsername, event.latencyMs);\n * }\n * }\n * ```\n */\nexport class StreamClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n // ===========================================================================\n // Monitor CRUD\n // ===========================================================================\n\n /**\n * Create a new stream monitor.\n *\n * @param params - Monitor configuration.\n * @returns The created StreamMonitor.\n * @throws InsufficientCreditsError - Credit balance below tier threshold (402).\n * @throws ValidationError - Invalid username or interval (422).\n * @throws ScrapeBadgerError - Name conflict (409).\n * @throws AuthenticationError - Invalid API key (401).\n *\n * @example\n * ```typescript\n * const monitor = await client.twitter.stream.createMonitor({\n * name: \"Breaking News\",\n * usernames: [\"cnnbrk\", \"bbcbreaking\"],\n * pollIntervalSeconds: 5,\n * });\n * ```\n */\n async createMonitor(params: CreateMonitorParams): Promise<StreamMonitor> {\n const body: Record<string, unknown> = {\n name: params.name,\n usernames: params.usernames,\n poll_interval_seconds: params.pollIntervalSeconds,\n };\n if (params.webhookUrl !== undefined) body[\"webhook_url\"] = params.webhookUrl;\n if (params.webhookSecret !== undefined) body[\"webhook_secret\"] = params.webhookSecret;\n\n return this.client.request<StreamMonitor>(\"/v1/twitter/stream/monitors\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * List stream monitors for the authenticated API key.\n *\n * @param options - Filter and pagination options.\n * @returns StreamMonitorList with pagination metadata.\n *\n * @example\n * ```typescript\n * const { monitors, total } = await client.twitter.stream.listMonitors({\n * status: \"active\",\n * });\n * console.log(`${total} active monitors`);\n * ```\n */\n async listMonitors(options?: {\n status?: \"active\" | \"paused\" | \"error\";\n page?: number;\n pageSize?: number;\n }): Promise<StreamMonitorList> {\n const params: Record<string, string | number | boolean | undefined> = {\n page: options?.page ?? 1,\n page_size: options?.pageSize ?? 20,\n status: options?.status,\n };\n return this.client.request<StreamMonitorList>(\"/v1/twitter/stream/monitors\", {\n params,\n });\n }\n\n /**\n * Get a single stream monitor by ID.\n *\n * @param monitorId - UUID of the monitor.\n * @returns The StreamMonitor.\n * @throws NotFoundError - No monitor with that ID for this API key.\n *\n * @example\n * ```typescript\n * const monitor = await client.twitter.stream.getMonitor(\"550e8400-...\");\n * console.log(`${monitor.name}: ${monitor.status}`);\n * ```\n */\n async getMonitor(monitorId: string): Promise<StreamMonitor> {\n return this.client.request<StreamMonitor>(`/v1/twitter/stream/monitors/${monitorId}`);\n }\n\n /**\n * Partially update a stream monitor.\n *\n * Only fields that are explicitly set in params are sent to the server.\n *\n * @param monitorId - UUID of the monitor.\n * @param params - Fields to update (all optional).\n * @returns The updated StreamMonitor.\n * @throws NotFoundError - Monitor not found for this API key.\n * @throws InsufficientCreditsError - When resuming with insufficient credits.\n *\n * @example\n * ```typescript\n * const monitor = await client.twitter.stream.updateMonitor(\"550e8400-...\", {\n * pollIntervalSeconds: 60,\n * });\n * ```\n */\n async updateMonitor(monitorId: string, params: UpdateMonitorParams): Promise<StreamMonitor> {\n const body: Record<string, unknown> = {};\n if (params.name !== undefined) body[\"name\"] = params.name;\n if (params.usernames !== undefined) body[\"usernames\"] = params.usernames;\n if (params.pollIntervalSeconds !== undefined)\n body[\"poll_interval_seconds\"] = params.pollIntervalSeconds;\n if (params.status !== undefined) body[\"status\"] = params.status;\n if (params.webhookUrl !== undefined) body[\"webhook_url\"] = params.webhookUrl;\n if (params.webhookSecret !== undefined) body[\"webhook_secret\"] = params.webhookSecret;\n\n return this.client.request<StreamMonitor>(`/v1/twitter/stream/monitors/${monitorId}`, {\n method: \"PATCH\",\n body,\n });\n }\n\n /**\n * Pause an active stream monitor.\n *\n * Convenience wrapper around updateMonitor({ status: \"paused\" }).\n *\n * @param monitorId - UUID of the monitor.\n * @returns The updated StreamMonitor with status=\"paused\".\n */\n async pauseMonitor(monitorId: string): Promise<StreamMonitor> {\n return this.updateMonitor(monitorId, { status: \"paused\" });\n }\n\n /**\n * Resume a paused stream monitor.\n *\n * Convenience wrapper around updateMonitor({ status: \"active\" }).\n *\n * @param monitorId - UUID of the monitor.\n * @returns The updated StreamMonitor with status=\"active\".\n * @throws InsufficientCreditsError - If credits are below the tier threshold.\n */\n async resumeMonitor(monitorId: string): Promise<StreamMonitor> {\n return this.updateMonitor(monitorId, { status: \"active\" });\n }\n\n /**\n * Delete a stream monitor and all its associated logs. Irreversible.\n *\n * @param monitorId - UUID of the monitor.\n * @throws NotFoundError - Monitor not found for this API key.\n *\n * @example\n * ```typescript\n * await client.twitter.stream.deleteMonitor(\"550e8400-...\");\n * ```\n */\n async deleteMonitor(monitorId: string): Promise<void> {\n await this.client.request<void>(`/v1/twitter/stream/monitors/${monitorId}`, {\n method: \"DELETE\",\n });\n }\n\n // ===========================================================================\n // Delivery and Billing Logs\n // ===========================================================================\n\n /**\n * List tweet delivery logs.\n *\n * @param options - Filter and pagination options.\n * @returns DeliveryLogList with pagination metadata.\n */\n async listDeliveryLogs(options?: {\n monitorId?: string;\n authorUsername?: string;\n deliveryStatus?: string;\n page?: number;\n pageSize?: number;\n sort?: \"asc\" | \"desc\";\n }): Promise<DeliveryLogList> {\n const params: Record<string, string | number | boolean | undefined> = {\n page: options?.page ?? 1,\n page_size: options?.pageSize ?? 20,\n sort: options?.sort ?? \"desc\",\n monitor_id: options?.monitorId,\n author_username: options?.authorUsername,\n delivery_status: options?.deliveryStatus,\n };\n return this.client.request<DeliveryLogList>(\"/v1/twitter/stream/logs\", { params });\n }\n\n /**\n * List billing activity logs.\n *\n * @param options - Filter and pagination options.\n * @returns BillingLogList with pagination metadata.\n */\n async listBillingLogs(options?: {\n monitorId?: string;\n page?: number;\n pageSize?: number;\n }): Promise<BillingLogList> {\n const params: Record<string, string | number | boolean | undefined> = {\n page: options?.page ?? 1,\n page_size: options?.pageSize ?? 20,\n monitor_id: options?.monitorId,\n };\n return this.client.request<BillingLogList>(\"/v1/twitter/stream/billing-logs\", { params });\n }\n\n // ===========================================================================\n // Filter Rules CRUD\n // ===========================================================================\n\n /**\n * Create a new tweet filter rule.\n *\n * @param params - Filter rule configuration.\n * @returns The created FilterRuleResponse.\n * @throws ValidationError - Invalid query or interval (422).\n * @throws InsufficientCreditsError - Credit balance below tier threshold (402).\n * @throws AuthenticationError - Invalid API key (401).\n *\n * @example\n * ```typescript\n * const rule = await client.twitter.stream.createFilterRule({\n * tag: \"python news\",\n * query: \"#python lang:en -is:retweet\",\n * interval_seconds: 60,\n * });\n * console.log(`Created: ${rule.id}, tier: ${rule.pricing_tier}`);\n * ```\n */\n async createFilterRule(params: FilterRuleCreate): Promise<FilterRuleResponse> {\n const body: Record<string, unknown> = {\n tag: params.tag,\n query: params.query,\n interval_seconds: params.interval_seconds,\n };\n if (params.webhook_url !== undefined) body[\"webhook_url\"] = params.webhook_url;\n if (params.webhook_secret !== undefined) body[\"webhook_secret\"] = params.webhook_secret;\n if (params.max_results_per_poll !== undefined)\n body[\"max_results_per_poll\"] = params.max_results_per_poll;\n\n return this.client.request<FilterRuleResponse>(\"/v1/twitter/stream/filter-rules\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * List filter rules for the authenticated API key.\n *\n * @param options - Filter and pagination options.\n * @returns FilterRuleListResponse with pagination metadata.\n *\n * @example\n * ```typescript\n * const { rules, total } = await client.twitter.stream.listFilterRules({\n * status: \"active\",\n * });\n * console.log(`${total} active rules`);\n * ```\n */\n async listFilterRules(options?: {\n status?: FilterRuleResponse[\"status\"];\n limit?: number;\n offset?: number;\n }): Promise<FilterRuleListResponse> {\n const params: Record<string, string | number | boolean | undefined> = {\n limit: options?.limit ?? 20,\n offset: options?.offset ?? 0,\n status: options?.status,\n };\n return this.client.request<FilterRuleListResponse>(\"/v1/twitter/stream/filter-rules\", {\n params,\n });\n }\n\n /**\n * Get a single filter rule by ID.\n *\n * @param ruleId - UUID of the filter rule.\n * @returns The FilterRuleResponse.\n * @throws NotFoundError - No rule with that ID for this API key.\n *\n * @example\n * ```typescript\n * const rule = await client.twitter.stream.getFilterRule(\"550e8400-...\");\n * console.log(`${rule.tag}: ${rule.status}`);\n * ```\n */\n async getFilterRule(ruleId: string): Promise<FilterRuleResponse> {\n return this.client.request<FilterRuleResponse>(`/v1/twitter/stream/filter-rules/${ruleId}`);\n }\n\n /**\n * Partially update a filter rule.\n *\n * Only fields that are explicitly set in params are sent to the server.\n *\n * @param ruleId - UUID of the filter rule.\n * @param params - Fields to update (all optional).\n * @returns The updated FilterRuleResponse.\n * @throws NotFoundError - Rule not found for this API key.\n * @throws ValidationError - Invalid field values (422).\n *\n * @example\n * ```typescript\n * const rule = await client.twitter.stream.updateFilterRule(\"550e8400-...\", {\n * interval_seconds: 120,\n * });\n * ```\n */\n async updateFilterRule(ruleId: string, params: FilterRuleUpdate): Promise<FilterRuleResponse> {\n const body: Record<string, unknown> = {};\n if (params.tag !== undefined) body[\"tag\"] = params.tag;\n if (params.query !== undefined) body[\"query\"] = params.query;\n if (params.interval_seconds !== undefined) body[\"interval_seconds\"] = params.interval_seconds;\n if (params.status !== undefined) body[\"status\"] = params.status;\n if (params.webhook_url !== undefined) body[\"webhook_url\"] = params.webhook_url;\n if (params.webhook_secret !== undefined) body[\"webhook_secret\"] = params.webhook_secret;\n if (params.max_results_per_poll !== undefined)\n body[\"max_results_per_poll\"] = params.max_results_per_poll;\n\n return this.client.request<FilterRuleResponse>(`/v1/twitter/stream/filter-rules/${ruleId}`, {\n method: \"PATCH\",\n body,\n });\n }\n\n /**\n * Delete a filter rule and all its associated logs. Irreversible.\n *\n * @param ruleId - UUID of the filter rule.\n * @throws NotFoundError - Rule not found for this API key.\n *\n * @example\n * ```typescript\n * await client.twitter.stream.deleteFilterRule(\"550e8400-...\");\n * ```\n */\n async deleteFilterRule(ruleId: string): Promise<void> {\n await this.client.request<void>(`/v1/twitter/stream/filter-rules/${ruleId}`, {\n method: \"DELETE\",\n });\n }\n\n // ===========================================================================\n // Filter Rules Utility\n // ===========================================================================\n\n /**\n * Validate a Twitter search query before creating a rule.\n *\n * @param query - The Twitter search query to validate.\n * @returns FilterRuleValidateResponse with validity and sample result count.\n *\n * @example\n * ```typescript\n * const result = await client.twitter.stream.validateFilterRuleQuery(\n * \"#python lang:en -is:retweet\"\n * );\n * if (!result.valid) {\n * console.error(\"Invalid query:\", result.error);\n * }\n * ```\n */\n async validateFilterRuleQuery(query: string): Promise<FilterRuleValidateResponse> {\n return this.client.request<FilterRuleValidateResponse>(\n \"/v1/twitter/stream/filter-rules/validate\",\n { method: \"POST\", body: { query } }\n );\n }\n\n /**\n * List tweet delivery logs for a specific filter rule.\n *\n * @param ruleId - UUID of the filter rule.\n * @param options - Filter and pagination options.\n * @returns FilterRuleDeliveryLogListResponse with pagination metadata.\n *\n * @example\n * ```typescript\n * const { logs, total } = await client.twitter.stream.listFilterRuleLogs(\n * \"550e8400-...\",\n * { limit: 50, deliveryStatus: \"webhook_delivered\" }\n * );\n * ```\n */\n async listFilterRuleLogs(\n ruleId: string,\n options?: {\n limit?: number;\n offset?: number;\n deliveryStatus?: string;\n sort?: \"asc\" | \"desc\";\n }\n ): Promise<FilterRuleDeliveryLogListResponse> {\n const params: Record<string, string | number | boolean | undefined> = {\n limit: options?.limit ?? 20,\n offset: options?.offset ?? 0,\n sort: options?.sort ?? \"desc\",\n delivery_status: options?.deliveryStatus,\n };\n return this.client.request<FilterRuleDeliveryLogListResponse>(\n `/v1/twitter/stream/filter-rules/${ruleId}/logs`,\n { params }\n );\n }\n\n /**\n * Get all available filter rule pricing tiers.\n *\n * @returns FilterRulePricingTiersResponse listing all tiers.\n *\n * @example\n * ```typescript\n * const { tiers } = await client.twitter.stream.getFilterRulePricingTiers();\n * tiers.forEach((t) => console.log(t.tier_label, t.credits_per_rule_per_day));\n * ```\n */\n async getFilterRulePricingTiers(): Promise<FilterRulePricingTiersResponse> {\n return this.client.request<FilterRulePricingTiersResponse>(\n \"/v1/twitter/stream/filter-rules-pricing\"\n );\n }\n\n // ===========================================================================\n // WebSocket Streaming -- EventEmitter style\n // ===========================================================================\n\n /**\n * Connect to the WebSocket stream and return an EventEmitter.\n *\n * The caller subscribes to events via `.on(\"tweet\", handler)`.\n * The SDK handles pong replies to server pings automatically.\n * Call `.close()` on the emitter to disconnect cleanly.\n *\n * If reconnect is true, the emitter automatically reconnects after\n * disconnects (other than auth failures). A new \"connected\" event is\n * emitted on each reconnect.\n *\n * @param options - Connection options (reconnect, delay, maxReconnects).\n * @returns StreamEmitter -- an EventEmitter subclass.\n *\n * @example\n * ```typescript\n * const stream = client.twitter.stream.connect();\n * stream.on(\"connected\", (e) => console.log(\"Connected:\", e.connectionId));\n * stream.on(\"tweet\", (event) => {\n * console.log(`@${event.authorUsername}: ${event.tweet.text}`);\n * console.log(` latency: ${event.latencyMs}ms`);\n * });\n * stream.on(\"error\", (err) => console.error(\"Stream error:\", err));\n * stream.on(\"close\", () => console.log(\"Stream closed\"));\n *\n * // Later:\n * stream.close();\n * ```\n */\n connect(options: ConnectOptions = {}): StreamEmitter {\n const { reconnect = false, reconnectDelaySeconds = 90, maxReconnects } = options;\n\n const delay = Math.max(MIN_RECONNECT_DELAY_SECONDS, reconnectDelaySeconds) * 1000;\n const wsUrl = wsUrlFromBase(this.client.config.baseUrl);\n const apiKey = this.client.config.apiKey;\n\n const emitter = new EventEmitter() as StreamEmitter;\n let ws: WebSocket | null = null;\n let closed = false;\n let reconnectCount = 0;\n\n const connectOnce = (): void => {\n ws = new WebSocket(wsUrl, { headers: { \"x-api-key\": apiKey } });\n\n ws.on(\"message\", (data: unknown) => {\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(String(data)) as Record<string, unknown>;\n } catch {\n return;\n }\n\n const event = parseEvent(raw);\n\n if (event.type === \"ping\") {\n ws?.send(JSON.stringify({ type: \"pong\" }));\n emitter.emit(\"ping\", event);\n return;\n }\n\n if (event.type === \"error\") {\n const code = (event as ErrorEvent).code;\n const err = new WebSocketStreamError((event as ErrorEvent).message, code);\n emitter.emit(\"error\", err);\n if (code === 4001 || code === 4003) {\n closed = true; // Do not reconnect on auth/limit errors\n ws?.close();\n }\n return;\n }\n\n emitter.emit(event.type, event);\n });\n\n ws.on(\"open\", () => {\n // Connection is open; wait for \"connected\" event from server\n });\n\n ws.on(\"close\", (code: unknown, reason: unknown) => {\n if (closed) {\n emitter.emit(\"close\");\n return;\n }\n\n if (!reconnect) {\n const reasonStr = reason instanceof Buffer ? reason.toString() : String(reason ?? \"\");\n emitter.emit(\n \"error\",\n new WebSocketStreamError(`WebSocket closed: ${reasonStr || String(code)}`)\n );\n emitter.emit(\"close\");\n return;\n }\n\n if (maxReconnects !== undefined && reconnectCount >= maxReconnects) {\n emitter.emit(\n \"error\",\n new WebSocketStreamError(`Max reconnects (${maxReconnects}) exhausted`)\n );\n emitter.emit(\"close\");\n return;\n }\n\n reconnectCount++;\n setTimeout(connectOnce, delay);\n });\n\n ws.on(\"error\", (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n emitter.emit(\"error\", new WebSocketStreamError(message));\n });\n };\n\n // Attach close() method to emitter\n (emitter as unknown as { close: () => void }).close = (): void => {\n closed = true;\n ws?.close(1000, \"Client closed\");\n };\n\n connectOnce();\n return emitter;\n }\n\n // ===========================================================================\n // WebSocket Streaming -- AsyncIterator style\n // ===========================================================================\n\n /**\n * Connect to the WebSocket stream and return an AsyncIterator.\n *\n * Iterates over StreamEvent objects. The SDK handles pong replies\n * automatically but still yields PingEvent to the caller (the caller\n * may ignore ping events).\n *\n * @param options - Connection options (reconnect, delay, maxReconnects).\n * @yields StreamEvent\n *\n * @example\n * ```typescript\n * for await (const event of client.twitter.stream.connectIter()) {\n * if (event.type === \"tweet\") {\n * console.log(`@${event.authorUsername}: ${event.latencyMs}ms`);\n * }\n * }\n * ```\n *\n * @example With auto-reconnect\n * ```typescript\n * for await (const event of client.twitter.stream.connectIter({\n * reconnect: true,\n * reconnectDelaySeconds: 90,\n * })) {\n * if (event.type === \"tweet\") {\n * // process(event);\n * }\n * }\n * ```\n */\n async *connectIter(options: ConnectOptions = {}): AsyncIterableIterator<StreamEvent> {\n const { reconnect = false, reconnectDelaySeconds = 90, maxReconnects } = options;\n\n const delay = Math.max(MIN_RECONNECT_DELAY_SECONDS, reconnectDelaySeconds) * 1000;\n const wsUrl = wsUrlFromBase(this.client.config.baseUrl);\n const apiKey = this.client.config.apiKey;\n let reconnectCount = 0;\n\n while (true) {\n const events: StreamEvent[] = [];\n let resolveWait: (() => void) | null = null;\n let rejectWait: ((err: Error) => void) | null = null;\n let done = false;\n\n const ws = new WebSocket(wsUrl, { headers: { \"x-api-key\": apiKey } });\n\n const waitForEvent = (): Promise<void> =>\n new Promise<void>((res, rej) => {\n resolveWait = res;\n rejectWait = rej;\n });\n\n ws.on(\"message\", (data: unknown) => {\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(String(data)) as Record<string, unknown>;\n } catch {\n return;\n }\n\n const event = parseEvent(raw);\n\n if (event.type === \"ping\") {\n ws.send(JSON.stringify({ type: \"pong\" }));\n }\n\n if (event.type === \"error\") {\n const code = (event as ErrorEvent).code;\n if (code === 4001 || code === 4003) {\n rejectWait?.(new WebSocketStreamError((event as ErrorEvent).message, code));\n rejectWait = null;\n resolveWait = null;\n return;\n }\n }\n\n events.push(event);\n resolveWait?.();\n resolveWait = null;\n rejectWait = null;\n });\n\n ws.on(\"close\", () => {\n done = true;\n resolveWait?.();\n resolveWait = null;\n rejectWait = null;\n });\n\n ws.on(\"error\", (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n rejectWait?.(new WebSocketStreamError(message));\n rejectWait = null;\n resolveWait = null;\n });\n\n try {\n while (!done || events.length > 0) {\n if (events.length === 0) {\n await waitForEvent();\n }\n while (events.length > 0) {\n yield events.shift()!;\n }\n }\n } catch (err) {\n ws.close();\n throw err;\n } finally {\n ws.close();\n }\n\n // Connection ended cleanly\n if (!reconnect) {\n return;\n }\n\n if (maxReconnects !== undefined && reconnectCount >= maxReconnects) {\n throw new WebSocketStreamError(`Max reconnects (${maxReconnects}) exhausted`);\n }\n\n reconnectCount++;\n await new Promise<void>((res) => setTimeout(res, delay));\n // Continue outer while loop for reconnect\n }\n }\n}\n\n/**\n * Verify the HMAC-SHA256 signature of an incoming webhook request.\n *\n * The server sets the header:\n * X-ScrapeBadger-Signature: sha256=<hex-digest>\n *\n * @param secret - The webhook secret configured on the monitor.\n * @param body - The raw request body string or Buffer.\n * @param signatureHeader - The full X-ScrapeBadger-Signature header value.\n * @returns true if the signature is valid.\n *\n * @example\n * ```typescript\n * // In an Express webhook receiver:\n * import { verifyWebhookSignature } from \"scrapebadger/twitter\";\n * import express from \"express\";\n *\n * app.post(\"/webhook\", express.raw({ type: \"application/json\" }), (req, res) => {\n * const sig = req.headers[\"x-scrapebadger-signature\"] as string;\n * if (!verifyWebhookSignature(\"my-secret\", req.body, sig)) {\n * return res.status(401).json({ error: \"Invalid signature\" });\n * }\n * const event = JSON.parse(req.body.toString());\n * // process event...\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function verifyWebhookSignature(\n secret: string,\n body: string | Buffer,\n signatureHeader: string\n): boolean {\n if (!signatureHeader.startsWith(\"sha256=\")) {\n return false;\n }\n\n const expectedHex = signatureHeader.slice(\"sha256=\".length);\n const bodyBuffer = typeof body === \"string\" ? Buffer.from(body, \"utf-8\") : body;\n const actualHex = createHmac(\"sha256\", secret).update(bodyBuffer).digest(\"hex\");\n\n // Use constant-time comparison to prevent timing attacks\n try {\n return timingSafeEqual(Buffer.from(expectedHex, \"hex\"), Buffer.from(actualHex, \"hex\"));\n } catch {\n // Buffers of different lengths throw -- treat as mismatch\n return false;\n }\n}\n","/**\n * Twitter API client.\n *\n * Provides access to all Twitter API endpoints through specialized sub-clients.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport { TweetsClient } from \"./tweets.js\";\nimport { UsersClient } from \"./users.js\";\nimport { ListsClient } from \"./lists.js\";\nimport { CommunitiesClient } from \"./communities.js\";\nimport { TrendsClient } from \"./trends.js\";\nimport { GeoClient } from \"./geo.js\";\nimport { StreamClient } from \"./stream.js\";\n\n/**\n * Twitter API client with access to all Twitter endpoints.\n *\n * Provides sub-clients for different resource types:\n * - `tweets` - Tweet operations (get, search, replies, retweeters, etc.)\n * - `users` - User operations (profiles, followers, following, search, etc.)\n * - `lists` - List operations (details, members, tweets, search, etc.)\n * - `communities` - Community operations (details, members, tweets, search, etc.)\n * - `trends` - Trending topics and locations\n * - `geo` - Geographic place information\n * - `stream` - Real-time stream monitor management and WebSocket streaming\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Access tweets\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n *\n * // Access users\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n *\n * // Access trends\n * const trends = await client.twitter.trends.getTrends();\n *\n * // Search with automatic pagination\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\")) {\n * console.log(tweet.text);\n * }\n *\n * // Stream live tweets\n * const stream = client.twitter.stream.connect();\n * stream.on(\"tweet\", (event) => console.log(event.authorUsername));\n * ```\n */\nexport class TwitterClient {\n /** Client for tweet operations */\n readonly tweets: TweetsClient;\n\n /** Client for user operations */\n readonly users: UsersClient;\n\n /** Client for list operations */\n readonly lists: ListsClient;\n\n /** Client for community operations */\n readonly communities: CommunitiesClient;\n\n /** Client for trends operations */\n readonly trends: TrendsClient;\n\n /** Client for geo/places operations */\n readonly geo: GeoClient;\n\n /** Client for real-time stream monitor management and WebSocket streaming */\n readonly stream: StreamClient;\n\n /**\n * Create a new Twitter client.\n *\n * @param client - The base HTTP client for making requests.\n */\n constructor(client: BaseClient) {\n this.tweets = new TweetsClient(client);\n this.users = new UsersClient(client);\n this.lists = new ListsClient(client);\n this.communities = new CommunitiesClient(client);\n this.trends = new TrendsClient(client);\n this.geo = new GeoClient(client);\n this.stream = new StreamClient(client);\n }\n}\n","/**\n * Web scraping API client for ScrapeBadger SDK.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n ScrapeOptions,\n ScrapeResult,\n ScreenshotOptions,\n ScreenshotResult,\n ExtractOptions,\n ExtractResult,\n BatchOptions,\n BatchResult,\n SessionInfo,\n} from \"./types.js\";\n\n/**\n * Client for web scraping operations.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Simple scrape\n * const result = await client.web.scrape(\"https://example.com\");\n * console.log(result.content);\n *\n * // Screenshot\n * const screenshot = await client.web.screenshot(\"https://example.com\");\n *\n * // Extract structured data\n * const data = await client.web.extract(\"https://example.com\", {\n * schema: { title: \"css:h1\" }\n * });\n *\n * // Batch scrape\n * const batch = await client.web.batch([\"https://a.com\", \"https://b.com\"]);\n * ```\n */\nexport class WebClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Scrape a web page.\n */\n async scrape(url: string, options: ScrapeOptions = {}): Promise<ScrapeResult> {\n const body: Record<string, unknown> = { url };\n if (options.renderJs) body.render_js = true;\n if (options.outputFormat && options.outputFormat !== \"html\")\n body.output_format = options.outputFormat;\n if (options.proxyCountry) body.proxy_country = options.proxyCountry;\n if (options.proxyType) body.proxy_type = options.proxyType;\n if (options.sessionId) body.session_id = options.sessionId;\n if (options.engine) body.engine = options.engine;\n if (options.maxCost !== undefined) body.max_cost = options.maxCost;\n if (options.headers) body.headers = options.headers;\n if (options.waitFor) body.wait_for = options.waitFor;\n if (options.timeout !== undefined) body.timeout = options.timeout;\n if (options.jsScenario) body.js_scenario = options.jsScenario;\n\n return this.client.request<ScrapeResult>(\"/v1/web/scrape\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * Take a screenshot of a web page.\n */\n async screenshot(\n url: string,\n options: ScreenshotOptions = {}\n ): Promise<ScreenshotResult> {\n const body: Record<string, unknown> = { url };\n if (options.fullPage) body.full_page = true;\n if (options.viewportWidth && options.viewportWidth !== 1280)\n body.viewport_width = options.viewportWidth;\n if (options.viewportHeight && options.viewportHeight !== 720)\n body.viewport_height = options.viewportHeight;\n if (options.imageFormat && options.imageFormat !== \"png\")\n body.image_format = options.imageFormat;\n if (options.waitFor) body.wait_for = options.waitFor;\n if (options.timeout !== undefined) body.timeout = options.timeout;\n\n return this.client.request<ScreenshotResult>(\"/v1/web/screenshot\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * Extract structured data from a web page.\n */\n async extract(\n url: string,\n options: ExtractOptions = {}\n ): Promise<ExtractResult> {\n const body: Record<string, unknown> = { url };\n if (options.schema) body.extraction_schema = options.schema;\n if (options.renderJs) body.render_js = true;\n if (options.waitFor) body.wait_for = options.waitFor;\n if (options.timeout !== undefined) body.timeout = options.timeout;\n\n return this.client.request<ExtractResult>(\"/v1/web/extract\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * Scrape multiple URLs in a batch.\n */\n async batch(\n urls: string[],\n options: BatchOptions = {}\n ): Promise<BatchResult> {\n const body: Record<string, unknown> = { urls };\n if (options.renderJs) body.render_js = true;\n if (options.outputFormat && options.outputFormat !== \"html\")\n body.output_format = options.outputFormat;\n if (options.maxConcurrency && options.maxConcurrency !== 5)\n body.max_concurrency = options.maxConcurrency;\n if (options.engine) body.engine = options.engine;\n if (options.timeout !== undefined) body.timeout = options.timeout;\n\n return this.client.request<BatchResult>(\"/v1/web/batch\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * Create a new scraping session for a domain.\n */\n async createSession(domain: string, persist = true): Promise<SessionInfo> {\n return this.client.request<SessionInfo>(\"/v1/web/sessions\", {\n method: \"POST\",\n body: {\n domain,\n new_session: true,\n persist_session: persist,\n },\n });\n }\n\n /**\n * Scrape using an existing session.\n */\n async reuseSession(\n url: string,\n sessionId: string,\n options: ScrapeOptions = {}\n ): Promise<ScrapeResult> {\n return this.scrape(url, { ...options, sessionId });\n }\n}\n","/**\n * Main ScrapeBadger client.\n *\n * This is the primary entry point for the ScrapeBadger SDK.\n */\n\nimport { BaseClient } from \"./internal/client.js\";\nimport {\n type ScrapeBadgerConfig,\n resolveConfig,\n getApiKeyFromEnv,\n} from \"./internal/config.js\";\nimport { TwitterClient } from \"./twitter/client.js\";\nimport { WebClient } from \"./web/client.js\";\n\n/**\n * ScrapeBadger API client.\n *\n * The main client for interacting with the ScrapeBadger API.\n * Provides access to all available scrapers through typed sub-clients.\n *\n * @example\n * ```typescript\n * import { ScrapeBadger } from \"scrapebadger\";\n *\n * // Create client with API key\n * const client = new ScrapeBadger({ apiKey: \"your-api-key\" });\n *\n * // Or use environment variable (SCRAPEBADGER_API_KEY)\n * const client = new ScrapeBadger();\n *\n * // Access Twitter API\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n *\n * // Search with automatic pagination\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\")) {\n * console.log(tweet.text);\n * }\n *\n * // Collect all results into an array\n * import { collectAll } from \"scrapebadger\";\n * const tweets = await collectAll(\n * client.twitter.tweets.searchAll(\"python\", { maxItems: 100 })\n * );\n * ```\n */\nexport class ScrapeBadger {\n private readonly baseClient: BaseClient;\n\n /** Twitter API client */\n readonly twitter: TwitterClient;\n\n /** Web scraping API client */\n readonly web: WebClient;\n\n /**\n * Create a new ScrapeBadger client.\n *\n * @param config - Configuration options. If apiKey is not provided,\n * it will be read from the SCRAPEBADGER_API_KEY environment variable.\n * @throws Error if no API key is provided or found in environment.\n *\n * @example\n * ```typescript\n * // With explicit API key\n * const client = new ScrapeBadger({ apiKey: \"your-api-key\" });\n *\n * // With custom options\n * const client = new ScrapeBadger({\n * apiKey: \"your-api-key\",\n * baseUrl: \"https://custom.api.com\",\n * timeout: 60000,\n * maxRetries: 5\n * });\n *\n * // Using environment variable\n * // Set SCRAPEBADGER_API_KEY=your-api-key\n * const client = new ScrapeBadger();\n * ```\n */\n constructor(config: Partial<ScrapeBadgerConfig> = {}) {\n // Use provided API key or fall back to environment variable\n const apiKey = config.apiKey ?? getApiKeyFromEnv();\n\n if (!apiKey) {\n throw new Error(\n \"API key is required. Pass it in the config or set SCRAPEBADGER_API_KEY environment variable.\"\n );\n }\n\n const resolvedConfig = resolveConfig({ ...config, apiKey });\n this.baseClient = new BaseClient(resolvedConfig);\n\n // Initialize sub-clients\n this.twitter = new TwitterClient(this.baseClient);\n this.web = new WebClient(this.baseClient);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/exceptions.ts","../src/internal/client.ts","../src/internal/config.ts","../src/internal/pagination.ts","../src/twitter/tweets.ts","../src/twitter/users.ts","../src/twitter/lists.ts","../src/twitter/communities.ts","../src/twitter/trends.ts","../src/twitter/geo.ts","../src/twitter/stream.ts","../src/twitter/spaces.ts","../src/twitter/client.ts","../src/web/client.ts","../src/vinted/search.ts","../src/vinted/items.ts","../src/vinted/users.ts","../src/vinted/reference.ts","../src/vinted/client.ts","../src/google/ai-mode.ts","../src/google/autocomplete.ts","../src/google/finance.ts","../src/google/flights.ts","../src/google/hotels.ts","../src/google/images.ts","../src/google/jobs.ts","../src/google/lens.ts","../src/google/maps.ts","../src/google/news.ts","../src/google/patents.ts","../src/google/products.ts","../src/google/scholar.ts","../src/google/search.ts","../src/google/shopping.ts","../src/google/shorts.ts","../src/google/trends.ts","../src/google/videos.ts","../src/google/client.ts","../src/client.ts"],"names":["UsersClient","SearchClient","TrendsClient"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Custom exceptions for the ScrapeBadger SDK.\n */\n\n/**\n * Base error class for all ScrapeBadger errors.\n */\nexport class ScrapeBadgerError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ScrapeBadgerError\";\n Object.setPrototypeOf(this, ScrapeBadgerError.prototype);\n }\n}\n\n/**\n * Raised when authentication fails (invalid or missing API key).\n */\nexport class AuthenticationError extends ScrapeBadgerError {\n constructor(message = \"Authentication failed. Check your API key.\") {\n super(message);\n this.name = \"AuthenticationError\";\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Raised when rate limit is exceeded.\n */\nexport class RateLimitError extends ScrapeBadgerError {\n /** Unix timestamp when the rate limit resets */\n readonly retryAfter: number | undefined;\n /** Maximum requests per minute for this tier */\n readonly limit: number | undefined;\n /** Remaining requests in the current window */\n readonly remaining: number | undefined;\n\n constructor(\n message = \"Rate limit exceeded.\",\n options?: { retryAfter?: number; limit?: number; remaining?: number }\n ) {\n super(message);\n this.name = \"RateLimitError\";\n this.retryAfter = options?.retryAfter;\n this.limit = options?.limit;\n this.remaining = options?.remaining;\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * Raised when the requested resource is not found.\n */\nexport class NotFoundError extends ScrapeBadgerError {\n /** The resource type that was not found */\n readonly resourceType: string | undefined;\n /** The resource ID that was not found */\n readonly resourceId: string | undefined;\n\n constructor(message = \"Resource not found.\", resourceType?: string, resourceId?: string) {\n super(message);\n this.name = \"NotFoundError\";\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n\n/**\n * Raised when the request is invalid.\n */\nexport class ValidationError extends ScrapeBadgerError {\n /** Validation errors by field */\n readonly errors: Record<string, string[]> | undefined;\n\n constructor(message = \"Validation error.\", errors?: Record<string, string[]>) {\n super(message);\n this.name = \"ValidationError\";\n this.errors = errors;\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\n/**\n * Raised when an internal server error occurs.\n */\nexport class ServerError extends ScrapeBadgerError {\n /** HTTP status code */\n readonly statusCode: number;\n\n constructor(message = \"Internal server error.\", statusCode = 500) {\n super(message);\n this.name = \"ServerError\";\n this.statusCode = statusCode;\n Object.setPrototypeOf(this, ServerError.prototype);\n }\n}\n\n/**\n * Raised when the request times out.\n */\nexport class TimeoutError extends ScrapeBadgerError {\n /** Timeout duration in milliseconds */\n readonly timeout: number;\n\n constructor(message = \"Request timed out.\", timeout: number) {\n super(message);\n this.name = \"TimeoutError\";\n this.timeout = timeout;\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Raised when the account has insufficient credits.\n */\nexport class InsufficientCreditsError extends ScrapeBadgerError {\n /** Current credit balance */\n readonly creditsBalance: number | undefined;\n\n constructor(message = \"Insufficient credits.\", creditsBalance?: number) {\n super(message);\n this.name = \"InsufficientCreditsError\";\n this.creditsBalance = creditsBalance;\n Object.setPrototypeOf(this, InsufficientCreditsError.prototype);\n }\n}\n\n/**\n * Raised when the account is restricted.\n */\nexport class AccountRestrictedError extends ScrapeBadgerError {\n /** Reason for the restriction */\n readonly reason: string | undefined;\n\n constructor(message = \"Account restricted.\", reason?: string) {\n super(message);\n this.name = \"AccountRestrictedError\";\n this.reason = reason;\n Object.setPrototypeOf(this, AccountRestrictedError.prototype);\n }\n}\n\n/**\n * Raised when a resource conflict occurs (e.g. duplicate monitor name).\n *\n * Maps to HTTP 409 Conflict.\n *\n * @example\n * ```typescript\n * import { ConflictError } from \"scrapebadger\";\n *\n * try {\n * await client.twitter.stream.createMonitor({\n * name: \"Existing Monitor\",\n * usernames: [\"elonmusk\"],\n * pollIntervalSeconds: 10,\n * });\n * } catch (err) {\n * if (err instanceof ConflictError) {\n * console.error(\"Monitor name already exists:\", err.message);\n * }\n * }\n * ```\n */\nexport class ConflictError extends ScrapeBadgerError {\n constructor(message = \"Resource conflict.\") {\n super(message);\n this.name = \"ConflictError\";\n Object.setPrototypeOf(this, ConflictError.prototype);\n }\n}\n\n/**\n * Raised when the WebSocket stream connection fails or is terminated.\n *\n * Common codes:\n * - 4001 -- Invalid or missing API key (auth failure)\n * - 4003 -- Connection limit exceeded (max 5 per API key)\n * - 1001 -- Server closed due to pong timeout\n * - 0 -- Unknown/parse error\n *\n * @example\n * ```typescript\n * import { WebSocketStreamError } from \"scrapebadger\";\n *\n * try {\n * for await (const event of client.twitter.stream.connectIter()) {\n * // ...\n * }\n * } catch (err) {\n * if (err instanceof WebSocketStreamError && err.code === 4001) {\n * console.error(\"API key rejected -- check your key\");\n * }\n * }\n * ```\n */\nexport class WebSocketStreamError extends ScrapeBadgerError {\n /** WebSocket close code or server error code */\n readonly code: number | undefined;\n\n constructor(message = \"WebSocket stream error\", code?: number) {\n super(message);\n this.name = \"WebSocketStreamError\";\n this.code = code;\n Object.setPrototypeOf(this, WebSocketStreamError.prototype);\n }\n}\n","/**\n * Base HTTP client with retry logic and error handling.\n */\n\nimport type { ResolvedConfig } from \"./config.js\";\nimport {\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n ValidationError,\n ServerError,\n TimeoutError,\n InsufficientCreditsError,\n AccountRestrictedError,\n ConflictError,\n ScrapeBadgerError,\n} from \"./exceptions.js\";\n\nexport interface RateLimit {\n limit: number;\n remaining: number;\n reset: number; // unix timestamp\n}\n\nexport interface ResponseWithHeaders<T> {\n data: T;\n rateLimit?: RateLimit;\n}\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\ninterface ErrorResponse {\n detail?: string;\n message?: string;\n errors?: Record<string, string[]>;\n limit?: number;\n remaining?: number;\n reset_at?: number;\n reason?: string;\n credits_balance?: number;\n}\n\n/**\n * Base HTTP client for making API requests.\n */\nexport class BaseClient {\n readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * Make an HTTP request to the API.\n */\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { data } = await this.requestRaw<T>(path, options);\n return data;\n }\n\n /**\n * Make an HTTP request and return both data and rate limit headers.\n */\n async requestWithHeaders<T>(\n path: string,\n options: RequestOptions = {}\n ): Promise<ResponseWithHeaders<T>> {\n return this.requestRaw<T>(path, options);\n }\n\n /**\n * Internal method that builds the request and executes it, returning data and rate limit info.\n */\n private async requestRaw<T>(\n path: string,\n options: RequestOptions = {}\n ): Promise<ResponseWithHeaders<T>> {\n const { method = \"GET\", params, body, headers = {} } = options;\n\n // Build URL with query parameters\n const url = new URL(path, this.config.baseUrl);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n // Build headers\n const requestHeaders: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n \"X-API-Key\": this.config.apiKey,\n \"User-Agent\": \"scrapebadger-node/0.3.1\",\n ...headers,\n };\n\n // Build request options\n const fetchOptions: RequestInit = {\n method,\n headers: requestHeaders,\n };\n\n if (body && method !== \"GET\") {\n fetchOptions.body = JSON.stringify(body);\n }\n\n // Execute with retry logic\n return this.executeWithRetry<T>(url.toString(), fetchOptions);\n }\n\n /**\n * Execute request with exponential backoff retry logic.\n */\n private async executeWithRetry<T>(\n url: string,\n options: RequestInit\n ): Promise<ResponseWithHeaders<T>> {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {\n try {\n const httpResponse = await this.fetchWithTimeout(url, options);\n const data = await this.handleResponse<T>(httpResponse);\n const rateLimit = this.parseRateLimitHeaders(httpResponse.headers);\n return { data, rateLimit };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on client errors (4xx) except rate limits\n if (error instanceof ScrapeBadgerError && !(error instanceof RateLimitError)) {\n throw error;\n }\n\n // Don't retry after exhausting attempts\n if (attempt === this.config.maxRetries) {\n break;\n }\n\n // Calculate delay with exponential backoff\n const delay = this.config.retryDelay * Math.pow(2, attempt);\n const delaySec = Math.round(delay / 1000);\n const attemptNum = attempt + 1;\n const maxRetries = this.config.maxRetries;\n\n // Warn with ANSI yellow coloring\n if (error instanceof RateLimitError) {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: 429 Rate Limited — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n // For rate limits, use retry-after if available\n if (error.retryAfter) {\n const retryDelay = (error.retryAfter - Date.now() / 1000) * 1000;\n if (retryDelay > 0 && retryDelay < 60000) {\n await this.sleep(retryDelay);\n continue;\n }\n }\n } else if (error instanceof TimeoutError) {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: TimeoutError — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n } else if (error instanceof ServerError) {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: ${error.statusCode} ${error.message} — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n } else {\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: ${(error as Error).name} — retrying in ${delaySec}s (attempt ${attemptNum}/${maxRetries})\\x1b[0m`\n );\n }\n\n await this.sleep(delay);\n }\n }\n\n throw lastError ?? new ScrapeBadgerError(\"Request failed after retries\");\n }\n\n /**\n * Parse rate limit headers from an HTTP response.\n */\n private parseRateLimitHeaders(headers: Headers): RateLimit | undefined {\n const limit = headers.get(\"X-RateLimit-Limit\");\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n const reset = headers.get(\"X-RateLimit-Reset\");\n\n if (limit === null || remaining === null || reset === null) {\n return undefined;\n }\n\n const parsedLimit = parseInt(limit, 10);\n const parsedRemaining = parseInt(remaining, 10);\n const parsedReset = parseInt(reset, 10);\n\n if (isNaN(parsedLimit) || isNaN(parsedRemaining) || isNaN(parsedReset)) {\n return undefined;\n }\n\n return { limit: parsedLimit, remaining: parsedRemaining, reset: parsedReset };\n }\n\n /**\n * Fetch with timeout support.\n */\n private async fetchWithTimeout(url: string, options: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n return response;\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new TimeoutError(\n `Request timed out after ${this.config.timeout}ms`,\n this.config.timeout\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Handle HTTP response and convert errors.\n */\n private async handleResponse<T>(response: Response): Promise<T> {\n // Parse response body\n let data: T | ErrorResponse;\n const contentType = response.headers.get(\"content-type\");\n\n if (contentType?.includes(\"application/json\")) {\n data = (await response.json()) as T | ErrorResponse;\n } else {\n const text = await response.text();\n data = { detail: text } as ErrorResponse;\n }\n\n // Handle success\n if (response.ok) {\n return data as T;\n }\n\n // Handle errors\n const errorData = data as ErrorResponse;\n const message = errorData.detail ?? errorData.message ?? \"Request failed\";\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message);\n\n case 402:\n throw new InsufficientCreditsError(message, errorData.credits_balance);\n\n case 403:\n if (message.toLowerCase().includes(\"restricted\")) {\n throw new AccountRestrictedError(message, errorData.reason);\n }\n throw new AuthenticationError(message);\n\n case 404:\n throw new NotFoundError(message);\n\n case 409:\n throw new ConflictError(message);\n\n case 422:\n throw new ValidationError(message, errorData.errors);\n\n case 429:\n throw new RateLimitError(message, {\n retryAfter: errorData.reset_at,\n limit: errorData.limit,\n remaining: errorData.remaining,\n });\n\n default:\n if (response.status >= 500) {\n throw new ServerError(message, response.status);\n }\n throw new ScrapeBadgerError(message);\n }\n }\n\n /**\n * Sleep for a given duration.\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * Configuration management for the ScrapeBadger SDK.\n */\n\nexport interface ScrapeBadgerConfig {\n /** API key for authentication */\n apiKey: string;\n /** Base URL for the API (default: https://scrapebadger.com) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Maximum number of retry attempts (default: 3) */\n maxRetries?: number;\n /** Initial retry delay in milliseconds (default: 1000) */\n retryDelay?: number;\n}\n\nexport interface ResolvedConfig {\n apiKey: string;\n baseUrl: string;\n timeout: number;\n maxRetries: number;\n retryDelay: number;\n}\n\nconst DEFAULT_BASE_URL = \"https://scrapebadger.com\";\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_MAX_RETRIES = 10;\nconst DEFAULT_RETRY_DELAY = 1000;\n\n/**\n * Resolve configuration with defaults.\n */\nexport function resolveConfig(config: ScrapeBadgerConfig): ResolvedConfig {\n if (!config.apiKey) {\n throw new Error(\"API key is required\");\n }\n\n return {\n apiKey: config.apiKey,\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n retryDelay: config.retryDelay ?? DEFAULT_RETRY_DELAY,\n };\n}\n\n/**\n * Load API key from environment variable.\n */\nexport function getApiKeyFromEnv(): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env.SCRAPEBADGER_API_KEY;\n }\n return undefined;\n}\n","/**\n * Pagination utilities for the ScrapeBadger SDK.\n */\n\nimport type { RateLimit } from \"./client.js\";\n\n/**\n * Response wrapper for paginated API responses.\n */\nexport interface PaginatedResponse<T> {\n /** Array of items in the current page */\n data: T[];\n /** Cursor for the next page, if available */\n nextCursor?: string;\n /** Whether there are more pages available */\n hasMore: boolean;\n}\n\n/**\n * Options for paginated requests.\n */\nexport interface PaginationOptions {\n /** Maximum number of items to fetch per request (default: 20) */\n count?: number;\n /** Cursor for pagination */\n cursor?: string;\n}\n\n/**\n * Options for async iteration.\n */\nexport interface IteratorOptions extends PaginationOptions {\n /** Maximum total number of items to fetch (default: unlimited) */\n maxItems?: number;\n}\n\n/**\n * Page result returned by fetchPage callbacks passed to paginate().\n */\nexport interface PageResult<T> {\n response: PaginatedResponse<T>;\n rateLimit?: RateLimit;\n}\n\n/**\n * Create a paginated response from API response data.\n */\nexport function createPaginatedResponse<T>(\n data: T[],\n cursor?: string\n): PaginatedResponse<T> {\n return {\n data,\n nextCursor: cursor,\n hasMore: !!cursor,\n };\n}\n\nconst RATE_LIMIT_WARN_THRESHOLD = 0.2;\n\n/**\n * Async generator for paginating through API results.\n *\n * Automatically throttles when fewer than 20% of rate limit requests remain,\n * spreading requests across the remaining reset window.\n *\n * @param fetchPage - Function to fetch a single page; returns response + optional rate limit info\n * @param options - Pagination options\n * @yields Individual items from each page\n *\n * @example\n * ```typescript\n * // Iterate through all results\n * for await (const tweet of client.twitter.tweets.searchAll(\"query\")) {\n * console.log(tweet.text);\n * }\n *\n * // With max items limit\n * for await (const tweet of client.twitter.tweets.searchAll(\"query\", { maxItems: 100 })) {\n * console.log(tweet.text);\n * }\n * ```\n */\nexport async function* paginate<T>(\n fetchPage: (cursor?: string) => Promise<PageResult<T>>,\n options: IteratorOptions = {}\n): AsyncGenerator<T, void, undefined> {\n const { maxItems } = options;\n let cursor: string | undefined;\n let totalYielded = 0;\n\n do {\n const { response, rateLimit } = await fetchPage(cursor);\n\n // Throttle pagination when approaching rate limit\n if (rateLimit) {\n const { limit, remaining, reset } = rateLimit;\n if (limit > 0 && remaining / limit < RATE_LIMIT_WARN_THRESHOLD) {\n const nowSec = Date.now() / 1000;\n const windowRemainingSec = Math.max(reset - nowSec, 1);\n const delayMs = remaining > 0 ? (windowRemainingSec / remaining) * 1000 : windowRemainingSec * 1000;\n const resetInSec = Math.round(windowRemainingSec);\n console.warn(\n `\\x1b[33m⚠ ScrapeBadger: Rate limit: ${remaining}/${limit} remaining (resets in ${resetInSec}s), throttling pagination\\x1b[0m`\n );\n await sleep(delayMs);\n }\n }\n\n for (const item of response.data) {\n yield item;\n totalYielded++;\n\n if (maxItems !== undefined && totalYielded >= maxItems) {\n return;\n }\n }\n\n cursor = response.nextCursor;\n } while (cursor);\n}\n\n/**\n * Collect all items from an async generator into an array.\n *\n * @param generator - Async generator to collect from\n * @returns Array of all yielded items\n *\n * @example\n * ```typescript\n * const tweets = await collectAll(client.twitter.tweets.searchAll(\"query\", { maxItems: 100 }));\n * console.log(`Fetched ${tweets.length} tweets`);\n * ```\n */\nexport async function collectAll<T>(generator: AsyncGenerator<T, void, undefined>): Promise<T[]> {\n const items: T[] = [];\n for await (const item of generator) {\n items.push(item);\n }\n return items;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Twitter Tweets API client.\n *\n * Provides methods for fetching tweets, searching, and getting tweet metadata.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { Tweet, User, QueryType, Article, CommunityNote } from \"./types.js\";\n\n/**\n * Client for Twitter tweets endpoints.\n *\n * Provides async methods for fetching individual tweets, searching tweets,\n * and getting tweet engagement data (retweeters, favoriters, replies).\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get single tweet\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n *\n * // Search tweets\n * const results = await client.twitter.tweets.search(\"python programming\");\n * for (const tweet of results.data) {\n * console.log(tweet.text);\n * }\n *\n * // Iterate through all results\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\")) {\n * console.log(tweet.text);\n * }\n * ```\n */\nexport class TweetsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get a single tweet by ID.\n *\n * @param tweetId - The tweet ID to fetch.\n * @returns The tweet data.\n * @throws NotFoundError - If the tweet doesn't exist.\n * @throws AuthenticationError - If the API key is invalid.\n *\n * @example\n * ```typescript\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n * console.log(`@${tweet.username}: ${tweet.text}`);\n * ```\n */\n async getById(tweetId: string): Promise<Tweet> {\n return this.client.request<Tweet>(`/v1/twitter/tweets/tweet/${tweetId}`);\n }\n\n /**\n * Get multiple tweets by their IDs.\n *\n * @param tweetIds - List of tweet IDs to fetch.\n * @returns Paginated response containing the tweets.\n *\n * @example\n * ```typescript\n * const tweets = await client.twitter.tweets.getByIds([\n * \"1234567890\",\n * \"0987654321\"\n * ]);\n * for (const tweet of tweets.data) {\n * console.log(tweet.text);\n * }\n * ```\n */\n async getByIds(tweetIds: string[]): Promise<PaginatedResponse<Tweet>> {\n const tweetsParam = tweetIds.join(\",\");\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n \"/v1/twitter/tweets/\",\n { params: { tweets: tweetsParam } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get replies to a tweet.\n *\n * @param tweetId - The tweet ID to get replies for.\n * @param options - Pagination options.\n * @returns Paginated response containing reply tweets.\n *\n * @example\n * ```typescript\n * const replies = await client.twitter.tweets.getReplies(\"1234567890\");\n * for (const reply of replies.data) {\n * console.log(`@${reply.username}: ${reply.text}`);\n * }\n *\n * // Get next page\n * if (replies.hasMore) {\n * const more = await client.twitter.tweets.getReplies(\"1234567890\", {\n * cursor: replies.nextCursor\n * });\n * }\n * ```\n */\n async getReplies(\n tweetId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/replies`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get users who retweeted a tweet.\n *\n * @param tweetId - The tweet ID to get retweeters for.\n * @param options - Pagination options.\n * @returns Paginated response containing users who retweeted.\n *\n * @example\n * ```typescript\n * const retweeters = await client.twitter.tweets.getRetweeters(\"1234567890\");\n * for (const user of retweeters.data) {\n * console.log(`@${user.username} retweeted`);\n * }\n * ```\n */\n async getRetweeters(\n tweetId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/retweeters`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get users who liked/favorited a tweet.\n *\n * @param tweetId - The tweet ID to get favoriters for.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing users who liked.\n *\n * @example\n * ```typescript\n * const likers = await client.twitter.tweets.getFavoriters(\"1234567890\");\n * console.log(`${likers.data.length} users liked this tweet`);\n * ```\n */\n async getFavoriters(\n tweetId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/favoriters`,\n { params: { count: options.count ?? 40, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get tweets similar to a given tweet.\n *\n * @param tweetId - The tweet ID to find similar tweets for.\n * @returns Paginated response containing similar tweets.\n *\n * @example\n * ```typescript\n * const similar = await client.twitter.tweets.getSimilar(\"1234567890\");\n * for (const tweet of similar.data) {\n * console.log(`Similar: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getSimilar(tweetId: string): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/similar`\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get tweets that quote a specific tweet.\n *\n * @param tweetId - The tweet ID to get quote tweets for.\n * @param options - Pagination options.\n * @returns Paginated response containing tweets that quote this tweet.\n *\n * @example\n * ```typescript\n * const quotes = await client.twitter.tweets.getQuotes(\"1234567890\");\n * for (const quote of quotes.data) {\n * console.log(`@${quote.username} quoted: ${quote.text.slice(0, 100)}...`);\n * }\n *\n * // Get next page\n * if (quotes.hasMore) {\n * const more = await client.twitter.tweets.getQuotes(\"1234567890\", {\n * cursor: quotes.nextCursor\n * });\n * }\n * ```\n */\n async getQuotes(\n tweetId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/tweets/tweet/${tweetId}/quotes`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all quote tweets with automatic pagination.\n *\n * This is a convenience method that automatically handles pagination,\n * yielding quote tweets one at a time.\n *\n * @param tweetId - The tweet ID to get quote tweets for.\n * @param options - Iteration options.\n * @yields Tweet objects that quote the specified tweet.\n *\n * @example\n * ```typescript\n * // Get all quote tweets (up to 500)\n * for await (const quote of client.twitter.tweets.getQuotesAll(\"1234567890\", {\n * maxItems: 500\n * })) {\n * console.log(`@${quote.username}: ${quote.text}`);\n * }\n *\n * // Collect into an array\n * import { collectAll } from \"scrapebadger\";\n * const quotes = await collectAll(\n * client.twitter.tweets.getQuotesAll(\"1234567890\", { maxItems: 100 })\n * );\n * ```\n */\n async *getQuotesAll(\n tweetId: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/tweets/tweet/${tweetId}/quotes`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Search for tweets.\n *\n * @param query - Search query string. Supports Twitter advanced search operators.\n * @param options - Search options including query type and pagination.\n * @returns Paginated response containing matching tweets.\n *\n * @example\n * ```typescript\n * // Basic search\n * const results = await client.twitter.tweets.search(\"python programming\");\n *\n * // Latest tweets only\n * const latest = await client.twitter.tweets.search(\"python\", {\n * queryType: \"Latest\"\n * });\n *\n * // Advanced search operators\n * const fromUser = await client.twitter.tweets.search(\"from:elonmusk lang:en\");\n * ```\n */\n async search(\n query: string,\n options: PaginationOptions & { queryType?: QueryType; count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n \"/v1/twitter/tweets/advanced_search\",\n {\n params: {\n query,\n query_type: options.queryType ?? \"Top\",\n count: options.count,\n cursor: options.cursor,\n },\n }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all search results with automatic pagination.\n *\n * This is a convenience method that automatically handles pagination,\n * yielding tweets one at a time.\n *\n * @param query - Search query string.\n * @param options - Search and iteration options.\n * @yields Tweet objects matching the search query.\n *\n * @example\n * ```typescript\n * // Get up to 1000 tweets\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\", {\n * maxItems: 1000\n * })) {\n * console.log(tweet.text);\n * }\n *\n * // Collect into an array\n * import { collectAll } from \"scrapebadger\";\n * const tweets = await collectAll(\n * client.twitter.tweets.searchAll(\"python\", { maxItems: 100 })\n * );\n * ```\n */\n async *searchAll(\n query: string,\n options: IteratorOptions & { queryType?: QueryType; count?: number } = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(\"/v1/twitter/tweets/advanced_search\", {\n params: {\n query,\n query_type: options.queryType ?? \"Top\",\n count: options.count,\n cursor,\n },\n });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get tweets from a user's timeline.\n *\n * @param username - Twitter username (without @).\n * @param options - Pagination options.\n * @returns Paginated response containing the user's tweets.\n *\n * @example\n * ```typescript\n * const tweets = await client.twitter.tweets.getUserTweets(\"elonmusk\");\n * for (const tweet of tweets.data) {\n * console.log(`${tweet.created_at}: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getUserTweets(\n username: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/latest_tweets`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all tweets from a user with automatic pagination.\n *\n * @param username - Twitter username (without @).\n * @param options - Iteration options.\n * @yields Tweet objects from the user's timeline.\n *\n * @example\n * ```typescript\n * for await (const tweet of client.twitter.tweets.getUserTweetsAll(\"elonmusk\", {\n * maxItems: 500\n * })) {\n * console.log(tweet.text);\n * }\n * ```\n */\n async *getUserTweetsAll(\n username: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/users/${username}/latest_tweets`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get the edit history of a tweet.\n *\n * @param tweetId - The tweet ID to get edit history for.\n * @returns Paginated response containing tweet versions.\n *\n * @example\n * ```typescript\n * const history = await client.twitter.tweets.getEditHistory(\"1234567890\");\n * console.log(`${history.data.length} version(s) of this tweet`);\n * ```\n */\n async getEditHistory(tweetId: string): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[] }>(\n `/v1/twitter/tweets/tweet/${tweetId}/edit_history`\n );\n return createPaginatedResponse(response.data ?? [], undefined);\n }\n\n /**\n * Get community notes (Birdwatch) attached to a tweet.\n *\n * @param tweetId - The tweet ID to get community notes for.\n * @returns Paginated response containing community notes.\n *\n * @example\n * ```typescript\n * const notes = await client.twitter.tweets.getCommunityNotes(\"1234567890\");\n * for (const note of notes.data) {\n * console.log(note.text);\n * }\n * ```\n */\n async getCommunityNotes(tweetId: string): Promise<PaginatedResponse<CommunityNote>> {\n const response = await this.client.request<{ data?: CommunityNote[] }>(\n `/v1/twitter/tweets/tweet/${tweetId}/community_notes`\n );\n return createPaginatedResponse(response.data ?? [], undefined);\n }\n\n /**\n * Get a long-form article by its ID.\n *\n * @param articleId - The article ID to fetch.\n * @returns The article data.\n *\n * @example\n * ```typescript\n * const article = await client.twitter.tweets.getArticle(\"abc123\");\n * console.log(`${article.title}: ${article.text?.slice(0, 100)}...`);\n * ```\n */\n async getArticle(articleId: string): Promise<Article> {\n return this.client.request<Article>(`/v1/twitter/tweets/article/${articleId}`);\n }\n}\n","/**\n * Twitter Users API client.\n *\n * Provides methods for fetching user profiles, followers, following, and related data.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { User, UserAbout, UserIds, Tweet } from \"./types.js\";\n\n/**\n * Client for Twitter users endpoints.\n *\n * Provides async methods for fetching user profiles, followers, following,\n * and other user-related data.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get user profile\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n * console.log(`${user.name}: ${user.followers_count.toLocaleString()} followers`);\n *\n * // Get followers\n * const followers = await client.twitter.users.getFollowers(\"elonmusk\");\n *\n * // Iterate through all followers\n * for await (const follower of client.twitter.users.getFollowersAll(\"elonmusk\")) {\n * console.log(follower.username);\n * }\n * ```\n */\nexport class UsersClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get a user by their numeric ID.\n *\n * @param userId - The user's numeric ID.\n * @returns The user profile.\n * @throws NotFoundError - If the user doesn't exist.\n *\n * @example\n * ```typescript\n * const user = await client.twitter.users.getById(\"44196397\");\n * console.log(`@${user.username}`);\n * ```\n */\n async getById(userId: string): Promise<User> {\n return this.client.request<User>(`/v1/twitter/users/${userId}/by_id`);\n }\n\n /**\n * Get a user by their username.\n *\n * @param username - The user's username (without @).\n * @returns The user profile.\n * @throws NotFoundError - If the user doesn't exist.\n *\n * @example\n * ```typescript\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n * console.log(`${user.name} has ${user.followers_count.toLocaleString()} followers`);\n * ```\n */\n async getByUsername(username: string): Promise<User> {\n return this.client.request<User>(`/v1/twitter/users/${username}/by_username`);\n }\n\n /**\n * Get extended \"About\" information for a user.\n *\n * Returns additional metadata including account location,\n * username change history, and verification details.\n *\n * @param username - The user's username (without @).\n * @returns Extended user information.\n *\n * @example\n * ```typescript\n * const about = await client.twitter.users.getAbout(\"elonmusk\");\n * console.log(`Account based in: ${about.account_based_in}`);\n * console.log(`Username changes: ${about.username_changes}`);\n * ```\n */\n async getAbout(username: string): Promise<UserAbout> {\n return this.client.request<UserAbout>(`/v1/twitter/users/${username}/about`);\n }\n\n /**\n * Get a user's followers.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options.\n * @returns Paginated response containing follower users.\n *\n * @example\n * ```typescript\n * const followers = await client.twitter.users.getFollowers(\"elonmusk\");\n * for (const user of followers.data) {\n * console.log(`@${user.username}`);\n * }\n *\n * // Get next page\n * if (followers.hasMore) {\n * const more = await client.twitter.users.getFollowers(\"elonmusk\", {\n * cursor: followers.nextCursor\n * });\n * }\n * ```\n */\n async getFollowers(\n username: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/followers`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all followers with automatic pagination.\n *\n * @param username - The user's username (without @).\n * @param options - Iteration options.\n * @yields User objects for each follower.\n *\n * @example\n * ```typescript\n * for await (const follower of client.twitter.users.getFollowersAll(\"elonmusk\", {\n * maxItems: 1000\n * })) {\n * console.log(follower.username);\n * }\n * ```\n */\n async *getFollowersAll(\n username: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(`/v1/twitter/users/${username}/followers`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get users that a user is following.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options.\n * @returns Paginated response containing followed users.\n *\n * @example\n * ```typescript\n * const following = await client.twitter.users.getFollowing(\"elonmusk\");\n * for (const user of following.data) {\n * console.log(`Follows @${user.username}`);\n * }\n * ```\n */\n async getFollowing(\n username: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/followings`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all following with automatic pagination.\n *\n * @param username - The user's username (without @).\n * @param options - Iteration options.\n * @yields User objects for each followed account.\n */\n async *getFollowingAll(\n username: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(`/v1/twitter/users/${username}/followings`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get a user's most recent followers.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing recent followers.\n */\n async getLatestFollowers(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/latest_followers`,\n { params: { count: options.count ?? 200, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get accounts a user most recently followed.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing recently followed users.\n */\n async getLatestFollowing(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/latest_following`,\n { params: { count: options.count ?? 200, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get follower IDs for a user.\n *\n * More efficient than getFollowers when you only need IDs.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns UserIds containing list of follower IDs.\n *\n * @example\n * ```typescript\n * const ids = await client.twitter.users.getFollowerIds(\"elonmusk\");\n * console.log(`Found ${ids.ids.length.toLocaleString()} follower IDs`);\n * ```\n */\n async getFollowerIds(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<UserIds> {\n const response = await this.client.request<{ data?: { ids?: number[]; next_cursor?: string } }>(\n `/v1/twitter/users/${username}/follower_ids`,\n { params: { count: options.count ?? 5000, cursor: options.cursor } }\n );\n return {\n ids: response.data?.ids ?? [],\n next_cursor: response.data?.next_cursor,\n };\n }\n\n /**\n * Get following IDs for a user.\n *\n * More efficient than getFollowing when you only need IDs.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns UserIds containing list of following IDs.\n */\n async getFollowingIds(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<UserIds> {\n const response = await this.client.request<{ data?: { ids?: number[]; next_cursor?: string } }>(\n `/v1/twitter/users/${username}/following_ids`,\n { params: { count: options.count ?? 5000, cursor: options.cursor } }\n );\n return {\n ids: response.data?.ids ?? [],\n next_cursor: response.data?.next_cursor,\n };\n }\n\n /**\n * Get verified followers for a user.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing verified followers.\n */\n async getVerifiedFollowers(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/verified_followers`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get followers that the authenticated user also follows.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing mutual connections.\n */\n async getFollowersYouKnow(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/followers_you_know`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get premium accounts that a user subscribes to.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing subscribed accounts.\n */\n async getSubscriptions(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/subscriptions`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get a user's highlighted tweets.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing highlighted tweets.\n */\n async getHighlights(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/highlights`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search for users.\n *\n * @param query - Search query string.\n * @param options - Pagination options.\n * @returns Paginated response containing matching users.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.users.search(\"python developer\");\n * for (const user of results.data) {\n * console.log(`@${user.username}: ${user.description}`);\n * }\n * ```\n */\n async search(query: string, options: PaginationOptions = {}): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n \"/v1/twitter/users/search_users\",\n { params: { query, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all search results with automatic pagination.\n *\n * @param query - Search query string.\n * @param options - Iteration options.\n * @yields User objects matching the search query.\n */\n async *searchAll(\n query: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(\"/v1/twitter/users/search_users\", { params: { query, cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get multiple users by their numeric IDs in a single request.\n *\n * @param userIds - List of user IDs to fetch.\n * @returns Paginated response containing the matching users.\n *\n * @example\n * ```typescript\n * const users = await client.twitter.users.getByIds([\"44196397\", \"783214\"]);\n * for (const user of users.data) {\n * console.log(`@${user.username}`);\n * }\n * ```\n */\n async getByIds(userIds: string[]): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[] }>(\n \"/v1/twitter/users/batch_by_ids\",\n { params: { user_ids: userIds.join(\",\") } }\n );\n return createPaginatedResponse(response.data ?? [], undefined);\n }\n\n /**\n * Get multiple users by their usernames in a single request.\n *\n * @param usernames - List of usernames (without @) to fetch.\n * @returns Paginated response containing the matching users.\n *\n * @example\n * ```typescript\n * const users = await client.twitter.users.getByUsernames([\"elonmusk\", \"twitter\"]);\n * for (const user of users.data) {\n * console.log(`${user.name}: ${user.followers_count?.toLocaleString()} followers`);\n * }\n * ```\n */\n async getByUsernames(usernames: string[]): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[] }>(\n \"/v1/twitter/users/batch_by_usernames\",\n { params: { usernames: usernames.join(\",\") } }\n );\n return createPaginatedResponse(response.data ?? [], undefined);\n }\n\n /**\n * Get tweets that mention a user.\n *\n * @param username - The user's username (without @).\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing tweets mentioning the user.\n *\n * @example\n * ```typescript\n * const mentions = await client.twitter.users.getMentions(\"elonmusk\");\n * for (const tweet of mentions.data) {\n * console.log(`@${tweet.username}: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getMentions(\n username: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/users/${username}/mentions`,\n { params: { count: options.count, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get long-form articles authored by a user.\n *\n * @param userId - The user's numeric ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing the user's articles as tweets.\n *\n * @example\n * ```typescript\n * const articles = await client.twitter.users.getArticles(\"44196397\");\n * for (const article of articles.data) {\n * console.log(article.text?.slice(0, 100));\n * }\n * ```\n */\n async getArticles(\n userId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/users/${userId}/articles`,\n { params: { count: options.count, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n}\n","/**\n * Twitter Lists API client.\n *\n * Provides methods for fetching Twitter lists, list members, and list tweets.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { List, Tweet, User } from \"./types.js\";\n\n/**\n * Client for Twitter lists endpoints.\n *\n * Provides async methods for fetching list details, members, subscribers,\n * and tweets from lists.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search for lists\n * const lists = await client.twitter.lists.search(\"tech leaders\");\n *\n * // Get list details\n * const list = await client.twitter.lists.getDetail(\"123456\");\n * console.log(`${list.name}: ${list.member_count} members`);\n *\n * // Get list tweets\n * const tweets = await client.twitter.lists.getTweets(\"123456\");\n * ```\n */\nexport class ListsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get details for a specific list.\n *\n * @param listId - The list ID.\n * @returns The list details.\n * @throws NotFoundError - If the list doesn't exist.\n *\n * @example\n * ```typescript\n * const list = await client.twitter.lists.getDetail(\"123456\");\n * console.log(`${list.name} by @${list.username}`);\n * console.log(`${list.member_count} members, ${list.subscriber_count} subscribers`);\n * ```\n */\n async getDetail(listId: string): Promise<List> {\n return this.client.request<List>(`/v1/twitter/lists/${listId}/detail`);\n }\n\n /**\n * Get tweets from a list's timeline.\n *\n * @param listId - The list ID.\n * @param options - Pagination options.\n * @returns Paginated response containing tweets from list members.\n *\n * @example\n * ```typescript\n * const tweets = await client.twitter.lists.getTweets(\"123456\");\n * for (const tweet of tweets.data) {\n * console.log(`@${tweet.username}: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async getTweets(\n listId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/tweets`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all list tweets with automatic pagination.\n *\n * @param listId - The list ID.\n * @param options - Iteration options.\n * @yields Tweet objects from the list timeline.\n */\n async *getTweetsAll(\n listId: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/lists/${listId}/tweets`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get members of a list.\n *\n * @param listId - The list ID.\n * @param options - Pagination options.\n * @returns Paginated response containing list members.\n *\n * @example\n * ```typescript\n * const members = await client.twitter.lists.getMembers(\"123456\");\n * for (const user of members.data) {\n * console.log(`@${user.username}`);\n * }\n * ```\n */\n async getMembers(\n listId: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/members`,\n { params: { cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all list members with automatic pagination.\n *\n * @param listId - The list ID.\n * @param options - Iteration options.\n * @yields User objects for each list member.\n */\n async *getMembersAll(\n listId: string,\n options: IteratorOptions = {}\n ): AsyncGenerator<User, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<User>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: User[];\n next_cursor?: string;\n }>(`/v1/twitter/lists/${listId}/members`, { params: { cursor } });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get subscribers of a list.\n *\n * @param listId - The list ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing list subscribers.\n */\n async getSubscribers(\n listId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<User>> {\n const response = await this.client.request<{ data?: User[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/subscribers`,\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search for lists.\n *\n * @param query - Search query string.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing matching lists.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.lists.search(\"tech leaders\");\n * for (const list of results.data) {\n * console.log(`${list.name}: ${list.member_count} members`);\n * }\n * ```\n */\n async search(\n query: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<List>> {\n const response = await this.client.request<{ data?: List[]; next_cursor?: string }>(\n \"/v1/twitter/lists/search\",\n { params: { query, count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get lists owned by the authenticated user.\n *\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing the user's lists.\n */\n async getMyLists(\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<List>> {\n const response = await this.client.request<{ data?: List[]; next_cursor?: string }>(\n \"/v1/twitter/lists/my_lists\",\n { params: { count: options.count ?? 100, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search tweets within a specific list.\n *\n * @param listId - The list ID to search within.\n * @param query - Search query string.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing matching tweets from the list.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.lists.searchTweets(\"123456\", \"python\");\n * for (const tweet of results.data) {\n * console.log(`@${tweet.username}: ${tweet.text.slice(0, 100)}...`);\n * }\n * ```\n */\n async searchTweets(\n listId: string,\n query: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/lists/${listId}/search_tweets`,\n { params: { query, count: options.count, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n}\n","/**\n * Twitter Communities API client.\n *\n * Provides methods for fetching Twitter communities, members, and tweets.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n PaginatedResponse,\n PaginationOptions,\n IteratorOptions,\n} from \"../internal/pagination.js\";\nimport { createPaginatedResponse, paginate } from \"../internal/pagination.js\";\nimport type { PageResult } from \"../internal/pagination.js\";\nimport type { Community, CommunityMember, CommunityTweetType, Tweet } from \"./types.js\";\n\n/**\n * Client for Twitter communities endpoints.\n *\n * Provides async methods for fetching community details, members,\n * moderators, and tweets.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search communities\n * const communities = await client.twitter.communities.search(\"python\");\n *\n * // Get community details\n * const community = await client.twitter.communities.getDetail(\"123456\");\n * console.log(`${community.name}: ${community.member_count} members`);\n *\n * // Get community tweets\n * const tweets = await client.twitter.communities.getTweets(\"123456\");\n * ```\n */\nexport class CommunitiesClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Parse a community member from the API response.\n * Handles both flat format (user_id, username, role at top level)\n * and nested format (user object with id, username).\n */\n private parseCommunityMember(item: Record<string, unknown>): CommunityMember {\n if (\"user\" in item && item.user) {\n return item as unknown as CommunityMember;\n }\n // Flat format: map user_id -> id for User interface\n return {\n user: {\n id: (item.user_id as string) ?? \"\",\n username: (item.username as string) ?? \"\",\n name: (item.name as string) ?? \"\",\n profile_image_url: item.profile_image_url as string | undefined,\n verified: (item.verified as boolean) ?? false,\n is_blue_verified: item.is_blue_verified as boolean | undefined,\n },\n role: item.role as string | undefined,\n joined_at: item.joined_at as string | undefined,\n };\n }\n\n /**\n * Get details for a specific community.\n *\n * @param communityId - The community ID.\n * @returns The community details including rules and admin info.\n * @throws NotFoundError - If the community doesn't exist.\n *\n * @example\n * ```typescript\n * const community = await client.twitter.communities.getDetail(\"123456\");\n * console.log(`${community.name}`);\n * console.log(`Members: ${community.member_count?.toLocaleString()}`);\n * console.log(`Join policy: ${community.join_policy}`);\n *\n * if (community.rules) {\n * console.log(\"Rules:\");\n * for (const rule of community.rules) {\n * console.log(` - ${rule.name}`);\n * }\n * }\n * ```\n */\n async getDetail(communityId: string): Promise<Community> {\n return this.client.request<Community>(`/v1/twitter/communities/${communityId}`);\n }\n\n /**\n * Get tweets from a community.\n *\n * @param communityId - The community ID.\n * @param options - Options including tweet type, count, and pagination.\n * @returns Paginated response containing community tweets.\n *\n * @example\n * ```typescript\n * // Get top tweets\n * const tweets = await client.twitter.communities.getTweets(\"123456\");\n *\n * // Get latest tweets\n * const latest = await client.twitter.communities.getTweets(\"123456\", {\n * tweetType: \"Latest\"\n * });\n * ```\n */\n async getTweets(\n communityId: string,\n options: PaginationOptions & { tweetType?: CommunityTweetType; count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/communities/${communityId}/tweets`,\n {\n params: {\n tweet_type: options.tweetType ?? \"Top\",\n count: options.count ?? 40,\n cursor: options.cursor,\n },\n }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Iterate through all community tweets with automatic pagination.\n *\n * @param communityId - The community ID.\n * @param options - Options including tweet type and iteration limits.\n * @yields Tweet objects from the community.\n */\n async *getTweetsAll(\n communityId: string,\n options: IteratorOptions & { tweetType?: CommunityTweetType } = {}\n ): AsyncGenerator<Tweet, void, undefined> {\n const fetchPage = async (cursor?: string): Promise<PageResult<Tweet>> => {\n const { data, rateLimit } = await this.client.requestWithHeaders<{\n data?: Tweet[];\n next_cursor?: string;\n }>(`/v1/twitter/communities/${communityId}/tweets`, {\n params: {\n tweet_type: options.tweetType ?? \"Top\",\n count: options.count ?? 40,\n cursor,\n },\n });\n return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };\n };\n yield* paginate(fetchPage, options);\n }\n\n /**\n * Get members of a community.\n *\n * @param communityId - The community ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing community members.\n *\n * @example\n * ```typescript\n * const members = await client.twitter.communities.getMembers(\"123456\");\n * for (const member of members.data) {\n * console.log(`@${member.user.username} (${member.role})`);\n * }\n * ```\n */\n async getMembers(\n communityId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<CommunityMember>> {\n const response = await this.client.request<{\n data?: Record<string, unknown>[];\n next_cursor?: string;\n }>(`/v1/twitter/communities/${communityId}/members`, {\n params: { count: options.count ?? 20, cursor: options.cursor },\n });\n\n const data: CommunityMember[] = (response.data ?? []).map((item) =>\n this.parseCommunityMember(item)\n );\n\n return createPaginatedResponse(data, response.next_cursor);\n }\n\n /**\n * Get moderators of a community.\n *\n * @param communityId - The community ID.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing community moderators.\n */\n async getModerators(\n communityId: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<CommunityMember>> {\n const response = await this.client.request<{\n data?: Record<string, unknown>[];\n next_cursor?: string;\n }>(`/v1/twitter/communities/${communityId}/moderators`, {\n params: { count: options.count ?? 20, cursor: options.cursor },\n });\n\n const data: CommunityMember[] = (response.data ?? []).map((item) =>\n this.parseCommunityMember(item)\n );\n\n return createPaginatedResponse(data, response.next_cursor);\n }\n\n /**\n * Search for communities.\n *\n * @param query - Search query string.\n * @param options - Pagination options.\n * @returns Paginated response containing matching communities.\n *\n * @example\n * ```typescript\n * const results = await client.twitter.communities.search(\"python developers\");\n * for (const community of results.data) {\n * console.log(`${community.name}: ${community.member_count} members`);\n * }\n * ```\n */\n async search(\n query: string,\n options: PaginationOptions = {}\n ): Promise<PaginatedResponse<Community>> {\n const response = await this.client.request<{ data?: Community[]; next_cursor?: string }>(\n \"/v1/twitter/communities/search\",\n { params: { query, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Search for tweets within a community.\n *\n * @param communityId - The community ID.\n * @param query - Search query string.\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing matching tweets.\n */\n async searchTweets(\n communityId: string,\n query: string,\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n `/v1/twitter/communities/${communityId}/search_tweets`,\n { params: { query, count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n\n /**\n * Get the community timeline (tweets from communities you're in).\n *\n * @param options - Pagination options with optional count.\n * @returns Paginated response containing community timeline tweets.\n */\n async getTimeline(\n options: PaginationOptions & { count?: number } = {}\n ): Promise<PaginatedResponse<Tweet>> {\n const response = await this.client.request<{ data?: Tweet[]; next_cursor?: string }>(\n \"/v1/twitter/communities/timeline\",\n { params: { count: options.count ?? 20, cursor: options.cursor } }\n );\n return createPaginatedResponse(response.data ?? [], response.next_cursor);\n }\n}\n","/**\n * Twitter Trends API client.\n *\n * Provides methods for fetching trending topics and trend locations.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { PaginatedResponse } from \"../internal/pagination.js\";\nimport { createPaginatedResponse } from \"../internal/pagination.js\";\nimport type { Trend, TrendCategory, Location, PlaceTrends } from \"./types.js\";\n\n/**\n * Client for Twitter trends endpoints.\n *\n * Provides async methods for fetching trending topics, place-specific trends,\n * and available trend locations.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get global trends\n * const trends = await client.twitter.trends.getTrends();\n * for (const trend of trends.data) {\n * console.log(`${trend.name}: ${trend.tweet_count || 'N/A'} tweets`);\n * }\n *\n * // Get trends for a specific location\n * const usTrends = await client.twitter.trends.getPlaceTrends(23424977);\n *\n * // Get available locations\n * const locations = await client.twitter.trends.getAvailableLocations();\n * ```\n */\nexport class TrendsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get trending topics.\n *\n * @param options - Options for filtering trends.\n * @returns Paginated response containing trending topics.\n *\n * @example\n * ```typescript\n * // Get general trending topics\n * const trends = await client.twitter.trends.getTrends();\n *\n * // Get news trends\n * const newsTrends = await client.twitter.trends.getTrends({\n * category: \"news\"\n * });\n *\n * for (const trend of trends.data) {\n * const count = trend.tweet_count?.toLocaleString() || \"N/A\";\n * console.log(`${trend.name}: ${count} tweets`);\n * }\n * ```\n */\n async getTrends(\n options: { category?: TrendCategory; count?: number } = {}\n ): Promise<PaginatedResponse<Trend>> {\n const response = await this.client.request<{ data?: Trend[] }>(\"/v1/twitter/trends/\", {\n params: {\n category: options.category ?? \"trending\",\n count: options.count ?? 20,\n },\n });\n return createPaginatedResponse(response.data ?? []);\n }\n\n /**\n * Get trends for a specific location.\n *\n * @param woeid - Where On Earth ID for the location.\n * Common WOEIDs:\n * - 1: Worldwide\n * - 23424977: United States\n * - 23424975: United Kingdom\n * - 23424856: Japan\n * - 23424829: Germany\n * @returns PlaceTrends containing location info and trends.\n * @throws NotFoundError - If the WOEID is invalid.\n *\n * @example\n * ```typescript\n * // Get US trends\n * const usTrends = await client.twitter.trends.getPlaceTrends(23424977);\n * console.log(`Trends in ${usTrends.name}:`);\n * for (const trend of usTrends.trends) {\n * console.log(` - ${trend.name}`);\n * }\n *\n * // Get worldwide trends\n * const globalTrends = await client.twitter.trends.getPlaceTrends(1);\n * ```\n */\n async getPlaceTrends(woeid: number): Promise<PlaceTrends> {\n return this.client.request<PlaceTrends>(`/v1/twitter/trends/place/${woeid}`);\n }\n\n /**\n * Get all locations where trends are available.\n *\n * @returns Paginated response containing available trend locations.\n *\n * @example\n * ```typescript\n * const locations = await client.twitter.trends.getAvailableLocations();\n *\n * // Filter by country\n * const usLocations = locations.data.filter(\n * loc => loc.country_code === \"US\"\n * );\n * console.log(`Found ${usLocations.length} US locations`);\n *\n * // Get countries only\n * const countries = locations.data.filter(\n * loc => loc.place_type === \"Country\"\n * );\n * ```\n */\n async getAvailableLocations(): Promise<PaginatedResponse<Location>> {\n const response = await this.client.request<{ data?: Location[] }>(\n \"/v1/twitter/trends/locations\"\n );\n return createPaginatedResponse(response.data ?? []);\n }\n}\n","/**\n * Twitter Geo API client.\n *\n * Provides methods for fetching geographic place information.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { PaginatedResponse } from \"../internal/pagination.js\";\nimport { createPaginatedResponse } from \"../internal/pagination.js\";\nimport type { Place } from \"./types.js\";\n\n/**\n * Options for searching places.\n */\nexport interface GeoSearchOptions {\n /** Latitude coordinate */\n lat?: number;\n /** Longitude coordinate */\n long?: number;\n /** Free-form text search query (e.g., \"San Francisco\") */\n query?: string;\n /** IP address for location lookup */\n ip?: string;\n /** Result granularity (\"neighborhood\", \"city\", \"admin\", \"country\") */\n granularity?: string;\n /** Maximum number of results (1-100) */\n maxResults?: number;\n}\n\n/**\n * Client for Twitter geo/places endpoints.\n *\n * Provides async methods for fetching place details and searching\n * for geographic locations.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search for places\n * const places = await client.twitter.geo.search({ query: \"San Francisco\" });\n *\n * // Search by coordinates\n * const nearby = await client.twitter.geo.search({ lat: 37.7749, long: -122.4194 });\n *\n * // Get place details\n * const place = await client.twitter.geo.getDetail(\"5a110d312052166f\");\n * ```\n */\nexport class GeoClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get details for a specific place.\n *\n * @param placeId - The Twitter place ID.\n * @returns The place details.\n * @throws NotFoundError - If the place doesn't exist.\n *\n * @example\n * ```typescript\n * const place = await client.twitter.geo.getDetail(\"5a110d312052166f\");\n * console.log(`${place.full_name}`);\n * console.log(`Type: ${place.place_type}`);\n * console.log(`Country: ${place.country}`);\n * ```\n */\n async getDetail(placeId: string): Promise<Place> {\n return this.client.request<Place>(`/v1/twitter/geo/places/${placeId}`);\n }\n\n /**\n * Search for geographic places.\n *\n * At least one of lat/long, query, or ip must be provided.\n *\n * @param options - Search options.\n * @returns Paginated response containing matching places.\n * @throws ValidationError - If no search parameters are provided.\n *\n * @example\n * ```typescript\n * // Search by name\n * const places = await client.twitter.geo.search({ query: \"San Francisco\" });\n * for (const place of places.data) {\n * console.log(`${place.full_name} (${place.place_type})`);\n * }\n *\n * // Search by coordinates\n * const nearby = await client.twitter.geo.search({\n * lat: 37.7749,\n * long: -122.4194,\n * granularity: \"city\"\n * });\n *\n * // Search by IP\n * const ipPlaces = await client.twitter.geo.search({ ip: \"8.8.8.8\" });\n * ```\n */\n async search(options: GeoSearchOptions = {}): Promise<PaginatedResponse<Place>> {\n const response = await this.client.request<{ data?: Place[] }>(\"/v1/twitter/geo/search\", {\n params: {\n lat: options.lat,\n long: options.long,\n query: options.query,\n ip: options.ip,\n granularity: options.granularity,\n max_results: options.maxResults,\n },\n });\n return createPaginatedResponse(response.data ?? []);\n }\n}\n","/**\n * StreamClient -- stream monitor management and live WebSocket streaming.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\nimport type { BaseClient } from \"../internal/client.js\";\nimport { WebSocketStreamError } from \"../internal/exceptions.js\";\nimport type {\n BillingLogList,\n ConnectOptions,\n ConnectedEvent,\n CreateMonitorParams,\n DeliveryLogList,\n ErrorEvent,\n FilterRuleCreate,\n FilterRuleDeliveryLogListResponse,\n FilterRuleListResponse,\n FilterRulePricingTiersResponse,\n FilterRuleResponse,\n FilterRuleUpdate,\n FilterRuleValidateResponse,\n PingEvent,\n StreamEvent,\n StreamMonitor,\n StreamMonitorList,\n StreamTweet,\n TweetEvent,\n UpdateMonitorParams,\n} from \"./stream-types.js\";\n\n// Minimum reconnect delay regardless of caller configuration (seconds)\nconst MIN_RECONNECT_DELAY_SECONDS = 5;\n\n/**\n * Derive WebSocket URL from HTTP base URL.\n * 'https://...' -> 'wss://...'\n * 'http://...' -> 'ws://...'\n */\nexport function wsUrlFromBase(baseUrl: string): string {\n if (baseUrl.startsWith(\"https://\")) {\n return baseUrl.replace(\"https://\", \"wss://\") + \"/v1/twitter/stream\";\n }\n if (baseUrl.startsWith(\"http://\")) {\n return baseUrl.replace(\"http://\", \"ws://\") + \"/v1/twitter/stream\";\n }\n return baseUrl + \"/v1/twitter/stream\";\n}\n\n/**\n * Map a raw server JSON object to a camelCase StreamEvent.\n * Unknown types return an ErrorEvent with code 0.\n */\nexport function parseEvent(raw: Record<string, unknown>): StreamEvent {\n const type = raw[\"type\"] as string | undefined;\n\n switch (type) {\n case \"connected\":\n return {\n type: \"connected\",\n connectionId: raw[\"connection_id\"] as string,\n apiKeyId: raw[\"api_key_id\"] as string,\n } satisfies ConnectedEvent;\n\n case \"ping\":\n return {\n type: \"ping\",\n timestamp: raw[\"timestamp\"] as string,\n } satisfies PingEvent;\n\n case \"tweet\":\n return {\n type: \"tweet\",\n monitorId: raw[\"monitor_id\"] as string,\n tweetId: raw[\"tweet_id\"] as string,\n authorUsername: raw[\"author_username\"] as string,\n tweetPublishedAt: raw[\"tweet_published_at\"] as string,\n detectedAt: raw[\"detected_at\"] as string,\n latencyMs: raw[\"latency_ms\"] as number,\n tweet: raw[\"tweet\"] as StreamTweet,\n } satisfies TweetEvent;\n\n case \"error\":\n return {\n type: \"error\",\n code: raw[\"code\"] as number,\n message: raw[\"message\"] as string,\n } satisfies ErrorEvent;\n\n default:\n return {\n type: \"error\",\n code: 0,\n message: `Unknown event type: ${String(type)}`,\n } satisfies ErrorEvent;\n }\n}\n\n/**\n * Typed EventEmitter for stream events.\n *\n * @example\n * ```typescript\n * const stream = client.twitter.stream.connect();\n * stream.on(\"tweet\", (event) => console.log(event.authorUsername));\n * stream.on(\"error\", (err) => console.error(err));\n * ```\n */\nexport interface StreamEmitter extends EventEmitter {\n on(event: \"connected\", listener: (event: ConnectedEvent) => void): this;\n on(event: \"ping\", listener: (event: PingEvent) => void): this;\n on(event: \"tweet\", listener: (event: TweetEvent) => void): this;\n on(event: \"error\", listener: (error: WebSocketStreamError) => void): this;\n on(event: \"close\", listener: () => void): this;\n\n once(event: \"connected\", listener: (event: ConnectedEvent) => void): this;\n once(event: \"tweet\", listener: (event: TweetEvent) => void): this;\n once(event: \"close\", listener: () => void): this;\n\n /** Gracefully close the WebSocket connection. */\n close(): void;\n}\n\n/**\n * Client for Twitter Streams -- monitor CRUD and live WebSocket streaming.\n *\n * Accessed as `client.twitter.stream`.\n *\n * @example Monitor CRUD\n * ```typescript\n * const monitor = await client.twitter.stream.createMonitor({\n * name: \"Tech Leaders\",\n * usernames: [\"elonmusk\", \"naval\"],\n * pollIntervalSeconds: 10,\n * });\n * console.log(`Created: ${monitor.id}, tier: ${monitor.pricing_tier}`);\n * ```\n *\n * @example EventEmitter streaming\n * ```typescript\n * const stream = client.twitter.stream.connect();\n * stream.on(\"tweet\", (event) => {\n * console.log(`@${event.authorUsername}: ${event.tweet.text}`);\n * console.log(` latency: ${event.latencyMs}ms`);\n * });\n * stream.on(\"error\", (err) => console.error(\"Stream error:\", err));\n * // Later:\n * stream.close();\n * ```\n *\n * @example AsyncIterator streaming\n * ```typescript\n * for await (const event of client.twitter.stream.connectIter()) {\n * if (event.type === \"tweet\") {\n * console.log(event.authorUsername, event.latencyMs);\n * }\n * }\n * ```\n */\nexport class StreamClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n // ===========================================================================\n // Monitor CRUD\n // ===========================================================================\n\n /**\n * Create a new stream monitor.\n *\n * @param params - Monitor configuration.\n * @returns The created StreamMonitor.\n * @throws InsufficientCreditsError - Credit balance below tier threshold (402).\n * @throws ValidationError - Invalid username or interval (422).\n * @throws ScrapeBadgerError - Name conflict (409).\n * @throws AuthenticationError - Invalid API key (401).\n *\n * @example\n * ```typescript\n * const monitor = await client.twitter.stream.createMonitor({\n * name: \"Breaking News\",\n * usernames: [\"cnnbrk\", \"bbcbreaking\"],\n * pollIntervalSeconds: 5,\n * });\n * ```\n */\n async createMonitor(params: CreateMonitorParams): Promise<StreamMonitor> {\n const body: Record<string, unknown> = {\n name: params.name,\n usernames: params.usernames,\n poll_interval_seconds: params.pollIntervalSeconds,\n };\n if (params.webhookUrl !== undefined) body[\"webhook_url\"] = params.webhookUrl;\n if (params.webhookSecret !== undefined) body[\"webhook_secret\"] = params.webhookSecret;\n\n return this.client.request<StreamMonitor>(\"/v1/twitter/stream/monitors\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * List stream monitors for the authenticated API key.\n *\n * @param options - Filter and pagination options.\n * @returns StreamMonitorList with pagination metadata.\n *\n * @example\n * ```typescript\n * const { monitors, total } = await client.twitter.stream.listMonitors({\n * status: \"active\",\n * });\n * console.log(`${total} active monitors`);\n * ```\n */\n async listMonitors(options?: {\n status?: \"active\" | \"paused\" | \"error\";\n page?: number;\n pageSize?: number;\n }): Promise<StreamMonitorList> {\n const params: Record<string, string | number | boolean | undefined> = {\n page: options?.page ?? 1,\n page_size: options?.pageSize ?? 20,\n status: options?.status,\n };\n return this.client.request<StreamMonitorList>(\"/v1/twitter/stream/monitors\", {\n params,\n });\n }\n\n /**\n * Get a single stream monitor by ID.\n *\n * @param monitorId - UUID of the monitor.\n * @returns The StreamMonitor.\n * @throws NotFoundError - No monitor with that ID for this API key.\n *\n * @example\n * ```typescript\n * const monitor = await client.twitter.stream.getMonitor(\"550e8400-...\");\n * console.log(`${monitor.name}: ${monitor.status}`);\n * ```\n */\n async getMonitor(monitorId: string): Promise<StreamMonitor> {\n return this.client.request<StreamMonitor>(`/v1/twitter/stream/monitors/${monitorId}`);\n }\n\n /**\n * Partially update a stream monitor.\n *\n * Only fields that are explicitly set in params are sent to the server.\n *\n * @param monitorId - UUID of the monitor.\n * @param params - Fields to update (all optional).\n * @returns The updated StreamMonitor.\n * @throws NotFoundError - Monitor not found for this API key.\n * @throws InsufficientCreditsError - When resuming with insufficient credits.\n *\n * @example\n * ```typescript\n * const monitor = await client.twitter.stream.updateMonitor(\"550e8400-...\", {\n * pollIntervalSeconds: 60,\n * });\n * ```\n */\n async updateMonitor(monitorId: string, params: UpdateMonitorParams): Promise<StreamMonitor> {\n const body: Record<string, unknown> = {};\n if (params.name !== undefined) body[\"name\"] = params.name;\n if (params.usernames !== undefined) body[\"usernames\"] = params.usernames;\n if (params.pollIntervalSeconds !== undefined)\n body[\"poll_interval_seconds\"] = params.pollIntervalSeconds;\n if (params.status !== undefined) body[\"status\"] = params.status;\n if (params.webhookUrl !== undefined) body[\"webhook_url\"] = params.webhookUrl;\n if (params.webhookSecret !== undefined) body[\"webhook_secret\"] = params.webhookSecret;\n\n return this.client.request<StreamMonitor>(`/v1/twitter/stream/monitors/${monitorId}`, {\n method: \"PATCH\",\n body,\n });\n }\n\n /**\n * Pause an active stream monitor.\n *\n * Convenience wrapper around updateMonitor({ status: \"paused\" }).\n *\n * @param monitorId - UUID of the monitor.\n * @returns The updated StreamMonitor with status=\"paused\".\n */\n async pauseMonitor(monitorId: string): Promise<StreamMonitor> {\n return this.updateMonitor(monitorId, { status: \"paused\" });\n }\n\n /**\n * Resume a paused stream monitor.\n *\n * Convenience wrapper around updateMonitor({ status: \"active\" }).\n *\n * @param monitorId - UUID of the monitor.\n * @returns The updated StreamMonitor with status=\"active\".\n * @throws InsufficientCreditsError - If credits are below the tier threshold.\n */\n async resumeMonitor(monitorId: string): Promise<StreamMonitor> {\n return this.updateMonitor(monitorId, { status: \"active\" });\n }\n\n /**\n * Delete a stream monitor and all its associated logs. Irreversible.\n *\n * @param monitorId - UUID of the monitor.\n * @throws NotFoundError - Monitor not found for this API key.\n *\n * @example\n * ```typescript\n * await client.twitter.stream.deleteMonitor(\"550e8400-...\");\n * ```\n */\n async deleteMonitor(monitorId: string): Promise<void> {\n await this.client.request<void>(`/v1/twitter/stream/monitors/${monitorId}`, {\n method: \"DELETE\",\n });\n }\n\n // ===========================================================================\n // Delivery and Billing Logs\n // ===========================================================================\n\n /**\n * List tweet delivery logs.\n *\n * @param options - Filter and pagination options.\n * @returns DeliveryLogList with pagination metadata.\n */\n async listDeliveryLogs(options?: {\n monitorId?: string;\n authorUsername?: string;\n deliveryStatus?: string;\n page?: number;\n pageSize?: number;\n sort?: \"asc\" | \"desc\";\n }): Promise<DeliveryLogList> {\n const params: Record<string, string | number | boolean | undefined> = {\n page: options?.page ?? 1,\n page_size: options?.pageSize ?? 20,\n sort: options?.sort ?? \"desc\",\n monitor_id: options?.monitorId,\n author_username: options?.authorUsername,\n delivery_status: options?.deliveryStatus,\n };\n return this.client.request<DeliveryLogList>(\"/v1/twitter/stream/logs\", { params });\n }\n\n /**\n * List billing activity logs.\n *\n * @param options - Filter and pagination options.\n * @returns BillingLogList with pagination metadata.\n */\n async listBillingLogs(options?: {\n monitorId?: string;\n page?: number;\n pageSize?: number;\n }): Promise<BillingLogList> {\n const params: Record<string, string | number | boolean | undefined> = {\n page: options?.page ?? 1,\n page_size: options?.pageSize ?? 20,\n monitor_id: options?.monitorId,\n };\n return this.client.request<BillingLogList>(\"/v1/twitter/stream/billing-logs\", { params });\n }\n\n // ===========================================================================\n // Filter Rules CRUD\n // ===========================================================================\n\n /**\n * Create a new tweet filter rule.\n *\n * @param params - Filter rule configuration.\n * @returns The created FilterRuleResponse.\n * @throws ValidationError - Invalid query or interval (422).\n * @throws InsufficientCreditsError - Credit balance below tier threshold (402).\n * @throws AuthenticationError - Invalid API key (401).\n *\n * @example\n * ```typescript\n * const rule = await client.twitter.stream.createFilterRule({\n * tag: \"python news\",\n * query: \"#python lang:en -is:retweet\",\n * interval_seconds: 60,\n * });\n * console.log(`Created: ${rule.id}, tier: ${rule.pricing_tier}`);\n * ```\n */\n async createFilterRule(params: FilterRuleCreate): Promise<FilterRuleResponse> {\n const body: Record<string, unknown> = {\n tag: params.tag,\n query: params.query,\n interval_seconds: params.interval_seconds,\n };\n if (params.webhook_url !== undefined) body[\"webhook_url\"] = params.webhook_url;\n if (params.webhook_secret !== undefined) body[\"webhook_secret\"] = params.webhook_secret;\n if (params.max_results_per_poll !== undefined)\n body[\"max_results_per_poll\"] = params.max_results_per_poll;\n\n return this.client.request<FilterRuleResponse>(\"/v1/twitter/stream/filter-rules\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * List filter rules for the authenticated API key.\n *\n * @param options - Filter and pagination options.\n * @returns FilterRuleListResponse with pagination metadata.\n *\n * @example\n * ```typescript\n * const { rules, total } = await client.twitter.stream.listFilterRules({\n * status: \"active\",\n * });\n * console.log(`${total} active rules`);\n * ```\n */\n async listFilterRules(options?: {\n status?: FilterRuleResponse[\"status\"];\n limit?: number;\n offset?: number;\n }): Promise<FilterRuleListResponse> {\n const params: Record<string, string | number | boolean | undefined> = {\n limit: options?.limit ?? 20,\n offset: options?.offset ?? 0,\n status: options?.status,\n };\n return this.client.request<FilterRuleListResponse>(\"/v1/twitter/stream/filter-rules\", {\n params,\n });\n }\n\n /**\n * Get a single filter rule by ID.\n *\n * @param ruleId - UUID of the filter rule.\n * @returns The FilterRuleResponse.\n * @throws NotFoundError - No rule with that ID for this API key.\n *\n * @example\n * ```typescript\n * const rule = await client.twitter.stream.getFilterRule(\"550e8400-...\");\n * console.log(`${rule.tag}: ${rule.status}`);\n * ```\n */\n async getFilterRule(ruleId: string): Promise<FilterRuleResponse> {\n return this.client.request<FilterRuleResponse>(`/v1/twitter/stream/filter-rules/${ruleId}`);\n }\n\n /**\n * Partially update a filter rule.\n *\n * Only fields that are explicitly set in params are sent to the server.\n *\n * @param ruleId - UUID of the filter rule.\n * @param params - Fields to update (all optional).\n * @returns The updated FilterRuleResponse.\n * @throws NotFoundError - Rule not found for this API key.\n * @throws ValidationError - Invalid field values (422).\n *\n * @example\n * ```typescript\n * const rule = await client.twitter.stream.updateFilterRule(\"550e8400-...\", {\n * interval_seconds: 120,\n * });\n * ```\n */\n async updateFilterRule(ruleId: string, params: FilterRuleUpdate): Promise<FilterRuleResponse> {\n const body: Record<string, unknown> = {};\n if (params.tag !== undefined) body[\"tag\"] = params.tag;\n if (params.query !== undefined) body[\"query\"] = params.query;\n if (params.interval_seconds !== undefined) body[\"interval_seconds\"] = params.interval_seconds;\n if (params.status !== undefined) body[\"status\"] = params.status;\n if (params.webhook_url !== undefined) body[\"webhook_url\"] = params.webhook_url;\n if (params.webhook_secret !== undefined) body[\"webhook_secret\"] = params.webhook_secret;\n if (params.max_results_per_poll !== undefined)\n body[\"max_results_per_poll\"] = params.max_results_per_poll;\n\n return this.client.request<FilterRuleResponse>(`/v1/twitter/stream/filter-rules/${ruleId}`, {\n method: \"PATCH\",\n body,\n });\n }\n\n /**\n * Delete a filter rule and all its associated logs. Irreversible.\n *\n * @param ruleId - UUID of the filter rule.\n * @throws NotFoundError - Rule not found for this API key.\n *\n * @example\n * ```typescript\n * await client.twitter.stream.deleteFilterRule(\"550e8400-...\");\n * ```\n */\n async deleteFilterRule(ruleId: string): Promise<void> {\n await this.client.request<void>(`/v1/twitter/stream/filter-rules/${ruleId}`, {\n method: \"DELETE\",\n });\n }\n\n // ===========================================================================\n // Filter Rules Utility\n // ===========================================================================\n\n /**\n * Validate a Twitter search query before creating a rule.\n *\n * @param query - The Twitter search query to validate.\n * @returns FilterRuleValidateResponse with validity and sample result count.\n *\n * @example\n * ```typescript\n * const result = await client.twitter.stream.validateFilterRuleQuery(\n * \"#python lang:en -is:retweet\"\n * );\n * if (!result.valid) {\n * console.error(\"Invalid query:\", result.error);\n * }\n * ```\n */\n async validateFilterRuleQuery(query: string): Promise<FilterRuleValidateResponse> {\n return this.client.request<FilterRuleValidateResponse>(\n \"/v1/twitter/stream/filter-rules/validate\",\n { method: \"POST\", body: { query } }\n );\n }\n\n /**\n * List tweet delivery logs for a specific filter rule.\n *\n * @param ruleId - UUID of the filter rule.\n * @param options - Filter and pagination options.\n * @returns FilterRuleDeliveryLogListResponse with pagination metadata.\n *\n * @example\n * ```typescript\n * const { logs, total } = await client.twitter.stream.listFilterRuleLogs(\n * \"550e8400-...\",\n * { limit: 50, deliveryStatus: \"webhook_delivered\" }\n * );\n * ```\n */\n async listFilterRuleLogs(\n ruleId: string,\n options?: {\n limit?: number;\n offset?: number;\n deliveryStatus?: string;\n sort?: \"asc\" | \"desc\";\n }\n ): Promise<FilterRuleDeliveryLogListResponse> {\n const params: Record<string, string | number | boolean | undefined> = {\n limit: options?.limit ?? 20,\n offset: options?.offset ?? 0,\n sort: options?.sort ?? \"desc\",\n delivery_status: options?.deliveryStatus,\n };\n return this.client.request<FilterRuleDeliveryLogListResponse>(\n `/v1/twitter/stream/filter-rules/${ruleId}/logs`,\n { params }\n );\n }\n\n /**\n * Get all available filter rule pricing tiers.\n *\n * @returns FilterRulePricingTiersResponse listing all tiers.\n *\n * @example\n * ```typescript\n * const { tiers } = await client.twitter.stream.getFilterRulePricingTiers();\n * tiers.forEach((t) => console.log(t.tier_label, t.credits_per_rule_per_day));\n * ```\n */\n async getFilterRulePricingTiers(): Promise<FilterRulePricingTiersResponse> {\n return this.client.request<FilterRulePricingTiersResponse>(\n \"/v1/twitter/stream/filter-rules-pricing\"\n );\n }\n\n // ===========================================================================\n // WebSocket Streaming -- EventEmitter style\n // ===========================================================================\n\n /**\n * Connect to the WebSocket stream and return an EventEmitter.\n *\n * The caller subscribes to events via `.on(\"tweet\", handler)`.\n * The SDK handles pong replies to server pings automatically.\n * Call `.close()` on the emitter to disconnect cleanly.\n *\n * If reconnect is true, the emitter automatically reconnects after\n * disconnects (other than auth failures). A new \"connected\" event is\n * emitted on each reconnect.\n *\n * @param options - Connection options (reconnect, delay, maxReconnects).\n * @returns StreamEmitter -- an EventEmitter subclass.\n *\n * @example\n * ```typescript\n * const stream = client.twitter.stream.connect();\n * stream.on(\"connected\", (e) => console.log(\"Connected:\", e.connectionId));\n * stream.on(\"tweet\", (event) => {\n * console.log(`@${event.authorUsername}: ${event.tweet.text}`);\n * console.log(` latency: ${event.latencyMs}ms`);\n * });\n * stream.on(\"error\", (err) => console.error(\"Stream error:\", err));\n * stream.on(\"close\", () => console.log(\"Stream closed\"));\n *\n * // Later:\n * stream.close();\n * ```\n */\n connect(options: ConnectOptions = {}): StreamEmitter {\n const { reconnect = false, reconnectDelaySeconds = 90, maxReconnects } = options;\n\n const delay = Math.max(MIN_RECONNECT_DELAY_SECONDS, reconnectDelaySeconds) * 1000;\n const wsUrl = wsUrlFromBase(this.client.config.baseUrl);\n const apiKey = this.client.config.apiKey;\n\n const emitter = new EventEmitter() as StreamEmitter;\n let ws: WebSocket | null = null;\n let closed = false;\n let reconnectCount = 0;\n\n const connectOnce = (): void => {\n ws = new WebSocket(wsUrl, { headers: { \"x-api-key\": apiKey } });\n\n ws.on(\"message\", (data: unknown) => {\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(String(data)) as Record<string, unknown>;\n } catch {\n return;\n }\n\n const event = parseEvent(raw);\n\n if (event.type === \"ping\") {\n ws?.send(JSON.stringify({ type: \"pong\" }));\n emitter.emit(\"ping\", event);\n return;\n }\n\n if (event.type === \"error\") {\n const code = (event as ErrorEvent).code;\n const err = new WebSocketStreamError((event as ErrorEvent).message, code);\n emitter.emit(\"error\", err);\n if (code === 4001 || code === 4003) {\n closed = true; // Do not reconnect on auth/limit errors\n ws?.close();\n }\n return;\n }\n\n emitter.emit(event.type, event);\n });\n\n ws.on(\"open\", () => {\n // Connection is open; wait for \"connected\" event from server\n });\n\n ws.on(\"close\", (code: unknown, reason: unknown) => {\n if (closed) {\n emitter.emit(\"close\");\n return;\n }\n\n if (!reconnect) {\n const reasonStr =\n reason instanceof Buffer ? reason.toString() : typeof reason === \"string\" ? reason : \"\";\n emitter.emit(\n \"error\",\n new WebSocketStreamError(`WebSocket closed: ${reasonStr || String(code)}`)\n );\n emitter.emit(\"close\");\n return;\n }\n\n if (maxReconnects !== undefined && reconnectCount >= maxReconnects) {\n emitter.emit(\n \"error\",\n new WebSocketStreamError(`Max reconnects (${maxReconnects}) exhausted`)\n );\n emitter.emit(\"close\");\n return;\n }\n\n reconnectCount++;\n setTimeout(connectOnce, delay);\n });\n\n ws.on(\"error\", (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n emitter.emit(\"error\", new WebSocketStreamError(message));\n });\n };\n\n // Attach close() method to emitter\n (emitter as unknown as { close: () => void }).close = (): void => {\n closed = true;\n ws?.close(1000, \"Client closed\");\n };\n\n connectOnce();\n return emitter;\n }\n\n // ===========================================================================\n // WebSocket Streaming -- AsyncIterator style\n // ===========================================================================\n\n /**\n * Connect to the WebSocket stream and return an AsyncIterator.\n *\n * Iterates over StreamEvent objects. The SDK handles pong replies\n * automatically but still yields PingEvent to the caller (the caller\n * may ignore ping events).\n *\n * @param options - Connection options (reconnect, delay, maxReconnects).\n * @yields StreamEvent\n *\n * @example\n * ```typescript\n * for await (const event of client.twitter.stream.connectIter()) {\n * if (event.type === \"tweet\") {\n * console.log(`@${event.authorUsername}: ${event.latencyMs}ms`);\n * }\n * }\n * ```\n *\n * @example With auto-reconnect\n * ```typescript\n * for await (const event of client.twitter.stream.connectIter({\n * reconnect: true,\n * reconnectDelaySeconds: 90,\n * })) {\n * if (event.type === \"tweet\") {\n * // process(event);\n * }\n * }\n * ```\n */\n async *connectIter(options: ConnectOptions = {}): AsyncIterableIterator<StreamEvent> {\n const { reconnect = false, reconnectDelaySeconds = 90, maxReconnects } = options;\n\n const delay = Math.max(MIN_RECONNECT_DELAY_SECONDS, reconnectDelaySeconds) * 1000;\n const wsUrl = wsUrlFromBase(this.client.config.baseUrl);\n const apiKey = this.client.config.apiKey;\n let reconnectCount = 0;\n\n while (true) {\n const events: StreamEvent[] = [];\n let resolveWait: (() => void) | null = null;\n let rejectWait: ((err: Error) => void) | null = null;\n let done = false;\n\n const ws = new WebSocket(wsUrl, { headers: { \"x-api-key\": apiKey } });\n\n const waitForEvent = (): Promise<void> =>\n new Promise<void>((res, rej) => {\n resolveWait = res;\n rejectWait = rej;\n });\n\n ws.on(\"message\", (data: unknown) => {\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(String(data)) as Record<string, unknown>;\n } catch {\n return;\n }\n\n const event = parseEvent(raw);\n\n if (event.type === \"ping\") {\n ws.send(JSON.stringify({ type: \"pong\" }));\n }\n\n if (event.type === \"error\") {\n const code = (event as ErrorEvent).code;\n if (code === 4001 || code === 4003) {\n rejectWait?.(new WebSocketStreamError((event as ErrorEvent).message, code));\n rejectWait = null;\n resolveWait = null;\n return;\n }\n }\n\n events.push(event);\n resolveWait?.();\n resolveWait = null;\n rejectWait = null;\n });\n\n ws.on(\"close\", () => {\n done = true;\n resolveWait?.();\n resolveWait = null;\n rejectWait = null;\n });\n\n ws.on(\"error\", (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n rejectWait?.(new WebSocketStreamError(message));\n rejectWait = null;\n resolveWait = null;\n });\n\n try {\n while (!done || events.length > 0) {\n if (events.length === 0) {\n await waitForEvent();\n }\n while (events.length > 0) {\n yield events.shift()!;\n }\n }\n } catch (err) {\n ws.close();\n throw err;\n } finally {\n ws.close();\n }\n\n // Connection ended cleanly\n if (!reconnect) {\n return;\n }\n\n if (maxReconnects !== undefined && reconnectCount >= maxReconnects) {\n throw new WebSocketStreamError(`Max reconnects (${maxReconnects}) exhausted`);\n }\n\n reconnectCount++;\n await new Promise<void>((res) => setTimeout(res, delay));\n // Continue outer while loop for reconnect\n }\n }\n}\n\n/**\n * Verify the HMAC-SHA256 signature of an incoming webhook request.\n *\n * The server sets the header:\n * X-ScrapeBadger-Signature: sha256=<hex-digest>\n *\n * @param secret - The webhook secret configured on the monitor.\n * @param body - The raw request body string or Buffer.\n * @param signatureHeader - The full X-ScrapeBadger-Signature header value.\n * @returns true if the signature is valid.\n *\n * @example\n * ```typescript\n * // In an Express webhook receiver:\n * import { verifyWebhookSignature } from \"scrapebadger/twitter\";\n * import express from \"express\";\n *\n * app.post(\"/webhook\", express.raw({ type: \"application/json\" }), (req, res) => {\n * const sig = req.headers[\"x-scrapebadger-signature\"] as string;\n * if (!verifyWebhookSignature(\"my-secret\", req.body, sig)) {\n * return res.status(401).json({ error: \"Invalid signature\" });\n * }\n * const event = JSON.parse(req.body.toString());\n * // process event...\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function verifyWebhookSignature(\n secret: string,\n body: string | Buffer,\n signatureHeader: string\n): boolean {\n if (!signatureHeader.startsWith(\"sha256=\")) {\n return false;\n }\n\n const expectedHex = signatureHeader.slice(\"sha256=\".length);\n const bodyBuffer = typeof body === \"string\" ? Buffer.from(body, \"utf-8\") : body;\n const actualHex = createHmac(\"sha256\", secret).update(bodyBuffer).digest(\"hex\");\n\n // Use constant-time comparison to prevent timing attacks\n try {\n return timingSafeEqual(Buffer.from(expectedHex, \"hex\"), Buffer.from(actualHex, \"hex\"));\n } catch {\n // Buffers of different lengths throw -- treat as mismatch\n return false;\n }\n}\n","/**\n * Twitter Spaces API client.\n *\n * Provides methods for fetching Twitter Spaces and live broadcasts.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { Space, Broadcast } from \"./types.js\";\n\n/**\n * Client for Twitter Spaces endpoints.\n *\n * Provides async methods for fetching Space details and live broadcast data.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get Space details\n * const space = await client.twitter.spaces.getDetail(\"1eaKbrPPbPwKX\");\n * console.log(`${space.title} — state: ${space.state}`);\n *\n * // Get broadcast details\n * const broadcast = await client.twitter.spaces.getBroadcast(\"broadcast123\");\n * console.log(`${broadcast.title}: ${broadcast.total_viewers} viewers`);\n * ```\n */\nexport class SpacesClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get details for a specific Twitter Space.\n *\n * @param spaceId - The Space ID to fetch.\n * @returns The Space data.\n * @throws NotFoundError - If the Space doesn't exist.\n *\n * @example\n * ```typescript\n * const space = await client.twitter.spaces.getDetail(\"1eaKbrPPbPwKX\");\n * console.log(`${space.title} — ${space.participant_count} participants`);\n * ```\n */\n async getDetail(spaceId: string): Promise<Space> {\n return this.client.request<Space>(`/v1/twitter/spaces/${spaceId}`);\n }\n\n /**\n * Get details for a live video broadcast.\n *\n * @param broadcastId - The broadcast ID to fetch.\n * @returns The broadcast data.\n * @throws NotFoundError - If the broadcast doesn't exist.\n *\n * @example\n * ```typescript\n * const broadcast = await client.twitter.spaces.getBroadcast(\"broadcast123\");\n * console.log(`${broadcast.title}: ${broadcast.total_viewers} viewers`);\n * ```\n */\n async getBroadcast(broadcastId: string): Promise<Broadcast> {\n return this.client.request<Broadcast>(`/v1/twitter/spaces/broadcast/${broadcastId}`);\n }\n}\n","/**\n * Twitter API client.\n *\n * Provides access to all Twitter API endpoints through specialized sub-clients.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport { TweetsClient } from \"./tweets.js\";\nimport { UsersClient } from \"./users.js\";\nimport { ListsClient } from \"./lists.js\";\nimport { CommunitiesClient } from \"./communities.js\";\nimport { TrendsClient } from \"./trends.js\";\nimport { GeoClient } from \"./geo.js\";\nimport { StreamClient } from \"./stream.js\";\nimport { SpacesClient } from \"./spaces.js\";\n\n/**\n * Twitter API client with access to all Twitter endpoints.\n *\n * Provides sub-clients for different resource types:\n * - `tweets` - Tweet operations (get, search, replies, retweeters, etc.)\n * - `users` - User operations (profiles, followers, following, search, etc.)\n * - `lists` - List operations (details, members, tweets, search, etc.)\n * - `communities` - Community operations (details, members, tweets, search, etc.)\n * - `trends` - Trending topics and locations\n * - `geo` - Geographic place information\n * - `stream` - Real-time stream monitor management and WebSocket streaming\n * - `spaces` - Twitter Spaces and live broadcast details\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Access tweets\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n *\n * // Access users\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n *\n * // Access trends\n * const trends = await client.twitter.trends.getTrends();\n *\n * // Search with automatic pagination\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\")) {\n * console.log(tweet.text);\n * }\n *\n * // Stream live tweets\n * const stream = client.twitter.stream.connect();\n * stream.on(\"tweet\", (event) => console.log(event.authorUsername));\n * ```\n */\nexport class TwitterClient {\n /** Client for tweet operations */\n readonly tweets: TweetsClient;\n\n /** Client for user operations */\n readonly users: UsersClient;\n\n /** Client for list operations */\n readonly lists: ListsClient;\n\n /** Client for community operations */\n readonly communities: CommunitiesClient;\n\n /** Client for trends operations */\n readonly trends: TrendsClient;\n\n /** Client for geo/places operations */\n readonly geo: GeoClient;\n\n /** Client for real-time stream monitor management and WebSocket streaming */\n readonly stream: StreamClient;\n\n /** Client for Twitter Spaces and live broadcast operations */\n readonly spaces: SpacesClient;\n\n /**\n * Create a new Twitter client.\n *\n * @param client - The base HTTP client for making requests.\n */\n constructor(client: BaseClient) {\n this.tweets = new TweetsClient(client);\n this.users = new UsersClient(client);\n this.lists = new ListsClient(client);\n this.communities = new CommunitiesClient(client);\n this.trends = new TrendsClient(client);\n this.geo = new GeoClient(client);\n this.stream = new StreamClient(client);\n this.spaces = new SpacesClient(client);\n }\n}\n","/**\n * Web scraping API client for ScrapeBadger SDK.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { ScrapeOptions, ScrapeResult, DetectOptions, DetectResult } from \"./types.js\";\n\n/**\n * Client for web scraping operations.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Simple scrape\n * const result = await client.web.scrape(\"https://scrapebadger.com\");\n * console.log(result.content);\n *\n * // Scrape with JavaScript rendering\n * const rendered = await client.web.scrape(\"https://scrapebadger.com\", {\n * renderJs: true,\n * format: \"markdown\",\n * });\n *\n * // AI extraction\n * const extracted = await client.web.extract(\n * \"https://scrapebadger.com/pricing\",\n * \"Extract all pricing plans with their features\"\n * );\n *\n * // Detect anti-bot systems\n * const detection = await client.web.detect(\"https://scrapebadger.com\");\n * console.log(detection.antibot_systems);\n * ```\n */\nexport class WebClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Scrape a web page.\n *\n * @param url - The URL to scrape\n * @param options - Scrape configuration options\n * @returns The scrape result including content, metadata, and credit usage\n */\n async scrape(url: string, options: ScrapeOptions = {}): Promise<ScrapeResult> {\n const body: Record<string, unknown> = { url };\n\n if (options.format !== undefined) body.format = options.format;\n if (options.renderJs !== undefined) body.render_js = options.renderJs;\n if (options.engine !== undefined) body.engine = options.engine;\n if (options.waitFor !== undefined) body.wait_for = options.waitFor;\n if (options.waitTimeout !== undefined) body.wait_timeout = options.waitTimeout;\n if (options.waitAfterLoad !== undefined) body.wait_after_load = options.waitAfterLoad;\n if (options.jsScenario !== undefined) body.js_scenario = options.jsScenario;\n if (options.sessionId !== undefined) body.session_id = options.sessionId;\n if (options.retryCount !== undefined) body.retry_count = options.retryCount;\n if (options.retryOnBlock !== undefined) body.retry_on_block = options.retryOnBlock;\n if (options.country !== undefined) body.country = options.country;\n if (options.customHeaders !== undefined) body.custom_headers = options.customHeaders;\n if (options.screenshot !== undefined) body.screenshot = options.screenshot;\n if (options.video !== undefined) body.video = options.video;\n if (options.antiBot !== undefined) body.anti_bot = options.antiBot;\n if (options.escalate !== undefined) body.escalate = options.escalate;\n if (options.maxCost !== undefined) body.max_cost = options.maxCost;\n if (options.aiExtract !== undefined) body.ai_extract = options.aiExtract;\n if (options.aiPrompt !== undefined) body.ai_prompt = options.aiPrompt;\n if (options.rawContent !== undefined) body.raw_content = options.rawContent;\n if (options.skipBotDetection !== undefined) body.skip_bot_detection = options.skipBotDetection;\n\n return this.client.request<ScrapeResult>(\"/v1/web/scrape\", {\n method: \"POST\",\n body,\n });\n }\n\n /**\n * Extract structured data from a web page using AI.\n *\n * Convenience wrapper around {@link scrape} that enables AI extraction\n * with the given prompt and defaults to markdown format.\n *\n * @param url - The URL to extract data from\n * @param prompt - Natural language prompt describing what to extract (max 2000 chars)\n * @param options - Additional scrape options (aiExtract and aiPrompt are set automatically)\n * @returns The scrape result with ai_extraction populated\n */\n async extract(url: string, prompt: string, options: ScrapeOptions = {}): Promise<ScrapeResult> {\n return this.scrape(url, {\n format: \"markdown\",\n ...options,\n aiExtract: true,\n aiPrompt: prompt,\n });\n }\n\n /**\n * Detect anti-bot systems on a URL.\n *\n * @param url - The URL to analyze\n * @param options - Detection options\n * @returns Detection results including identified anti-bot and captcha systems\n */\n async detect(url: string, options: DetectOptions = {}): Promise<DetectResult> {\n const body: Record<string, unknown> = { url };\n\n if (options.timeout !== undefined) body.timeout = options.timeout;\n if (options.country !== undefined) body.country = options.country;\n\n return this.client.request<DetectResult>(\"/v1/web/detect\", {\n method: \"POST\",\n body,\n });\n }\n}\n","/**\n * Vinted Search API client.\n *\n * Provides methods for searching Vinted item listings.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { VintedSearchParams, SearchResponse } from \"./types.js\";\n\n/**\n * Client for Vinted search endpoints.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Basic search\n * const results = await client.vinted.search.search({ query: \"nike air max\" });\n * for (const item of results.items) {\n * console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);\n * }\n *\n * // Search with filters\n * const filtered = await client.vinted.search.search({\n * query: \"adidas\",\n * market: \"de\",\n * price_from: 10,\n * price_to: 50,\n * order: \"price_low_to_high\",\n * });\n * ```\n */\nexport class SearchClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Search for Vinted items.\n *\n * @param params - Search parameters including query, filters, and pagination.\n * @returns Search results with items and pagination metadata.\n * @throws AuthenticationError - If the API key is invalid.\n * @throws ValidationError - If the search parameters are invalid.\n *\n * @example\n * ```typescript\n * const results = await client.vinted.search.search({\n * query: \"vintage jacket\",\n * market: \"fr\",\n * page: 1,\n * per_page: 20,\n * order: \"newest_first\",\n * });\n * console.log(`Found ${results.pagination.total_entries} items`);\n * ```\n */\n async search(params: VintedSearchParams): Promise<SearchResponse> {\n return this.client.request<SearchResponse>(\"/v1/vinted/search\", {\n params: {\n query: params.query,\n market: params.market,\n page: params.page,\n per_page: params.per_page,\n price_from: params.price_from,\n price_to: params.price_to,\n brand_ids: params.brand_ids,\n color_ids: params.color_ids,\n status_ids: params.status_ids,\n order: params.order,\n },\n });\n }\n}\n","/**\n * Vinted Items API client.\n *\n * Provides methods for fetching individual Vinted item details.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { ItemDetailResponse } from \"./types.js\";\n\n/**\n * Client for Vinted item endpoints.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * const item = await client.vinted.items.get(123456789, { market: \"fr\" });\n * console.log(`${item.item.title} — ${item.item.price.amount} ${item.item.price.currency_code}`);\n * console.log(`Seller: ${item.item.seller.login}`);\n * ```\n */\nexport class ItemsClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get a single item by ID.\n *\n * @param itemId - The Vinted item ID to fetch.\n * @param options - Optional parameters.\n * @param options.market - Market code (default: \"fr\").\n * @returns The item detail response including full item data.\n * @throws NotFoundError - If the item doesn't exist.\n * @throws AuthenticationError - If the API key is invalid.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.items.get(123456789);\n * const { item } = response;\n * console.log(`${item.title}: ${item.description}`);\n * console.log(`Brand: ${item.brand_title}, Size: ${item.size_title}`);\n * console.log(`Photos: ${item.photos.length}`);\n * ```\n */\n async get(\n itemId: number,\n options: { market?: string } = {}\n ): Promise<ItemDetailResponse> {\n return this.client.request<ItemDetailResponse>(\n `/v1/vinted/items/${itemId}`,\n { params: { market: options.market } }\n );\n }\n}\n","/**\n * Vinted Users API client.\n *\n * Provides methods for fetching Vinted user profiles and their item listings.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { UserProfileResponse, UserItemsResponse } from \"./types.js\";\n\n/**\n * Client for Vinted user endpoints.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get user profile\n * const profile = await client.vinted.users.getProfile(12345);\n * console.log(`${profile.user.login} — ${profile.user.item_count} items`);\n *\n * // Get user's items\n * const items = await client.vinted.users.getItems(12345);\n * for (const item of items.items) {\n * console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);\n * }\n * ```\n */\nexport class UsersClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Get a user's profile.\n *\n * @param userId - The Vinted user ID.\n * @param options - Optional parameters.\n * @param options.market - Market code (default: \"fr\").\n * @returns The user profile response.\n * @throws NotFoundError - If the user doesn't exist.\n * @throws AuthenticationError - If the API key is invalid.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.users.getProfile(12345);\n * const { user } = response;\n * console.log(`${user.login} from ${user.city}, ${user.country_code}`);\n * console.log(`Reputation: ${user.feedback_reputation}`);\n * console.log(`Items: ${user.item_count}, Followers: ${user.followers_count}`);\n * ```\n */\n async getProfile(\n userId: number,\n options: { market?: string } = {}\n ): Promise<UserProfileResponse> {\n return this.client.request<UserProfileResponse>(\n `/v1/vinted/users/${userId}`,\n { params: { market: options.market } }\n );\n }\n\n /**\n * Get items listed by a user.\n *\n * @param userId - The Vinted user ID.\n * @param options - Optional parameters for pagination and market.\n * @param options.market - Market code (default: \"fr\").\n * @param options.page - Page number.\n * @param options.per_page - Items per page.\n * @returns The user's items with pagination metadata.\n * @throws NotFoundError - If the user doesn't exist.\n * @throws AuthenticationError - If the API key is invalid.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.users.getItems(12345, {\n * market: \"de\",\n * page: 1,\n * per_page: 20,\n * });\n * console.log(`Page ${response.pagination.current_page} of ${response.pagination.total_pages}`);\n * for (const item of response.items) {\n * console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);\n * }\n * ```\n */\n async getItems(\n userId: number,\n options: { market?: string; page?: number; per_page?: number } = {}\n ): Promise<UserItemsResponse> {\n return this.client.request<UserItemsResponse>(\n `/v1/vinted/users/${userId}/items`,\n {\n params: {\n market: options.market,\n page: options.page,\n per_page: options.per_page,\n },\n }\n );\n }\n}\n","/**\n * Vinted Reference Data API client.\n *\n * Provides methods for fetching brands, colors, statuses, and markets.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n BrandsResponse,\n ColorsResponse,\n StatusesResponse,\n MarketsResponse,\n} from \"./types.js\";\n\n/**\n * Client for Vinted reference data endpoints.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Get available markets\n * const markets = await client.vinted.reference.markets();\n * for (const market of markets.markets) {\n * console.log(`${market.name} (${market.code}) — ${market.currency}`);\n * }\n *\n * // Search brands\n * const brands = await client.vinted.reference.brands({ keyword: \"nike\" });\n * for (const brand of brands.brands) {\n * console.log(`${brand.title}: ${brand.item_count} items`);\n * }\n * ```\n */\nexport class ReferenceClient {\n private readonly client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n }\n\n /**\n * Search for brands by keyword.\n *\n * @param options - Optional parameters.\n * @param options.keyword - Brand name to search for.\n * @param options.market - Market code (default: \"fr\").\n * @param options.per_page - Number of results per page.\n * @returns Brands matching the keyword.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.reference.brands({\n * keyword: \"adidas\",\n * market: \"de\",\n * per_page: 10,\n * });\n * for (const brand of response.brands) {\n * console.log(`${brand.title} (${brand.slug}): ${brand.item_count} items`);\n * }\n * ```\n */\n async brands(\n options: { keyword?: string; market?: string; per_page?: number } = {}\n ): Promise<BrandsResponse> {\n return this.client.request<BrandsResponse>(\"/v1/vinted/brands\", {\n params: {\n keyword: options.keyword,\n market: options.market,\n per_page: options.per_page,\n },\n });\n }\n\n /**\n * Get available colors for a market.\n *\n * @param options - Optional parameters.\n * @param options.market - Market code (default: \"fr\").\n * @returns List of available colors.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.reference.colors({ market: \"fr\" });\n * for (const color of response.colors) {\n * console.log(`${color.title} (#${color.hex})`);\n * }\n * ```\n */\n async colors(\n options: { market?: string } = {}\n ): Promise<ColorsResponse> {\n return this.client.request<ColorsResponse>(\"/v1/vinted/colors\", {\n params: { market: options.market },\n });\n }\n\n /**\n * Get available item condition statuses for a market.\n *\n * @param options - Optional parameters.\n * @param options.market - Market code (default: \"fr\").\n * @returns List of item condition statuses.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.reference.statuses({ market: \"fr\" });\n * for (const status of response.statuses) {\n * console.log(`${status.id}: ${status.title}`);\n * }\n * ```\n */\n async statuses(\n options: { market?: string } = {}\n ): Promise<StatusesResponse> {\n return this.client.request<StatusesResponse>(\"/v1/vinted/statuses\", {\n params: { market: options.market },\n });\n }\n\n /**\n * Get all available Vinted markets.\n *\n * @returns List of all supported Vinted markets/countries.\n *\n * @example\n * ```typescript\n * const response = await client.vinted.reference.markets();\n * for (const market of response.markets) {\n * console.log(`${market.name}: ${market.domain} (${market.currency})`);\n * }\n * ```\n */\n async markets(): Promise<MarketsResponse> {\n return this.client.request<MarketsResponse>(\"/v1/vinted/markets\");\n }\n}\n","/**\n * Vinted API client.\n *\n * Provides access to all Vinted API endpoints through specialized sub-clients.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport { SearchClient } from \"./search.js\";\nimport { ItemsClient } from \"./items.js\";\nimport { UsersClient } from \"./users.js\";\nimport { ReferenceClient } from \"./reference.js\";\n\n/**\n * Vinted API client with access to all Vinted endpoints.\n *\n * Provides sub-clients for different resource types:\n * - `search` - Search for items across Vinted marketplaces\n * - `items` - Get individual item details\n * - `users` - User profiles and their item listings\n * - `reference` - Reference data (brands, colors, statuses, markets)\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * // Search items\n * const results = await client.vinted.search.search({ query: \"nike air max\" });\n *\n * // Get item details\n * const item = await client.vinted.items.get(123456789);\n *\n * // Get user profile\n * const user = await client.vinted.users.getProfile(12345);\n *\n * // Get reference data\n * const markets = await client.vinted.reference.markets();\n * ```\n */\nexport class VintedClient {\n /** Client for item search operations */\n readonly search: SearchClient;\n\n /** Client for individual item operations */\n readonly items: ItemsClient;\n\n /** Client for user operations */\n readonly users: UsersClient;\n\n /** Client for reference data (brands, colors, statuses, markets) */\n readonly reference: ReferenceClient;\n\n /**\n * Create a new Vinted client.\n *\n * @param client - The base HTTP client for making requests.\n */\n constructor(client: BaseClient) {\n this.search = new SearchClient(client);\n this.items = new ItemsClient(client);\n this.users = new UsersClient(client);\n this.reference = new ReferenceClient(client);\n }\n}\n","/**\n * Google AI Mode API client (udm=50 generative answers).\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { AiModeSearchParams, GoogleResponse } from \"./types.js\";\n\n/**\n * Client for Google AI Mode.\n */\nexport class AiModeClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: AiModeSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/ai-mode/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Autocomplete API client.\n *\n * Returns up to 10 search suggestions. Suggestions that resolve to\n * Knowledge-Graph entities (companies, people, movies, stocks, local\n * businesses, …) additionally carry `entity_name` and `thumbnail` —\n * the same enrichment Google's own search-box surfaces.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { AutocompleteParams, GoogleResponse } from \"./types.js\";\n\n/**\n * Client for Google Autocomplete (search suggestions).\n */\nexport class AutocompleteClient {\n constructor(private readonly client: BaseClient) {}\n\n /**\n * Get Google autocomplete suggestions for a query.\n *\n * @example\n * ```typescript\n * const res = await client.google.autocomplete.get({ q: \"apple\" });\n * for (const s of res.suggestions) {\n * console.log(s.value, s.entity_name, s.thumbnail);\n * }\n * ```\n */\n async get(params: AutocompleteParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/autocomplete\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Finance API client.\n *\n * Powered by the same `mKsvE` batchexecute RPC the Google Finance SPA\n * uses internally. Returns price / change / change% / previous_close /\n * after-hours / market hours / timezone / currency / country /\n * alternate exchange listings in ~1 s.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { FinanceQuoteParams, GoogleResponse } from \"./types.js\";\n\n/**\n * Client for Google Finance quotes.\n *\n * @example\n * ```typescript\n * const quote = await client.google.finance.quote({ q: \"AAPL:NASDAQ\" });\n * console.log(quote.price, quote.currency, quote.after_hours);\n * ```\n */\nexport class FinanceClient {\n constructor(private readonly client: BaseClient) {}\n\n async quote(params: FinanceQuoteParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/finance/quote\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Flights API client — one-way, round-trip, multi-city.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { FlightsSearchParams, GoogleResponse } from \"./types.js\";\n\n/**\n * Client for Google Flights search.\n *\n * Supports one-way, round-trip, and multi-city itineraries with\n * passenger configuration, cabin class, stops filter, and max-price.\n * Returns Google's Best flights recommendations plus the full Other\n * flights result set, with per-offer pricing, duration, stops,\n * layovers, carbon emissions, and price insights (low / typical /\n * high + typical price range) when Google shows them.\n *\n * @example\n * ```typescript\n * const flights = await client.google.flights.search({\n * departure_id: \"JFK\",\n * arrival_id: \"LHR\",\n * outbound_date: \"2026-06-15\",\n * return_date: \"2026-06-22\",\n * adults: 2,\n * });\n * for (const offer of flights.best_flights) {\n * console.log(offer.price, offer.currency, offer.total_duration_minutes);\n * }\n * if (flights.price_insights) {\n * console.log(\"Price level:\", flights.price_insights.price_level);\n * }\n * ```\n */\nexport class FlightsClient {\n constructor(private readonly client: BaseClient) {}\n\n /** Search Google Flights for available itineraries. */\n async search(params: FlightsSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/flights/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Hotels API client — search, property details.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n GoogleResponse,\n HotelsDetailsParams,\n HotelsSearchParams,\n} from \"./types.js\";\n\n/**\n * Client for Google Hotels endpoints.\n *\n * @example\n * ```typescript\n * const hotels = await client.google.hotels.search({\n * q: \"Paris\",\n * check_in: \"2026-05-01\",\n * check_out: \"2026-05-05\",\n * adults: 2,\n * });\n * ```\n */\nexport class HotelsClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: HotelsSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/hotels/search\", {\n params: { ...params },\n });\n }\n\n async details(params: HotelsDetailsParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/hotels/details\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Images API client.\n *\n * Returns up to 100 tiles per page with `title`, `source`, `link`\n * (referrer page), `thumbnail`, `image` (inline preview), `original`\n * (full-res URL), `original_width` / `original_height`,\n * `original_size` (e.g. `\"635KB\"`), plus licensability flags.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, ImagesSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Images search.\n *\n * @example\n * ```typescript\n * const res = await client.google.images.search({\n * q: \"golden retriever\",\n * imgsz: \"l\",\n * imgcolor: \"color\",\n * });\n * for (const img of res.results) {\n * console.log(img.rank, img.title, img.original);\n * }\n * ```\n */\nexport class ImagesClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: ImagesSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/images/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Jobs API client.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, JobsSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Jobs search.\n *\n * @example\n * ```typescript\n * const jobs = await client.google.jobs.search({\n * q: \"software engineer\",\n * location: \"San Francisco, CA\",\n * job_type: \"FULLTIME\",\n * });\n * ```\n */\nexport class JobsClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: JobsSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/jobs/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Lens API client (visual image search).\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, LensSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Lens visual search by image URL.\n *\n * Response carries `lens_results` (Scrapingdog-parity alias) with\n * `title`, `source`, `source_favicon`, `thumbnail`, optional `tag`\n * price chip and `in_stock`, plus `related_searches` chips. Legacy\n * `results` alias retained for backwards compat.\n *\n * @example\n * ```typescript\n * const out = await client.google.lens.search({\n * url: \"https://example.com/photo.jpg\",\n * product: true, // bias towards shoppable matches\n * });\n * for (const match of out.lens_results) {\n * console.log(match.title, match.tag);\n * }\n * ```\n */\nexport class LensClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: LensSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/lens/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Maps API client — search, place details, reviews, photos, posts.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n GoogleResponse,\n MapsPhotosParams,\n MapsPlaceParams,\n MapsPostsParams,\n MapsReviewsParams,\n MapsSearchParams,\n} from \"./types.js\";\n\n/**\n * Client for Google Maps endpoints.\n *\n * @example\n * ```typescript\n * const places = await client.google.maps.search({ q: \"coffee shops sf\" });\n * const detail = await client.google.maps.place({ data_id: \"0x...:0x...\" });\n * const reviews = await client.google.maps.reviews({\n * data_id: \"0x...:0x...\",\n * sort_by: \"newestFirst\",\n * });\n * ```\n */\nexport class MapsClient {\n constructor(private readonly client: BaseClient) {}\n\n /**\n * Search Maps for places by text query, place_id, or ludocid.\n *\n * Returns up to 20 results per page with full details (place_id,\n * data_id, GPS, rating, reviews, address, phone, website, extensions,\n * weekly hours, thumbnail) in a single call.\n */\n async search(params: MapsSearchParams): Promise<GoogleResponse> {\n if (!params.q && !params.place_id && !params.ludocid) {\n throw new Error(\"q, place_id, or ludocid is required\");\n }\n return this.client.request<GoogleResponse>(\"/v1/google/maps/search\", {\n params: { ...params },\n });\n }\n\n /**\n * Get full place detail by `place_id` or `data_id`.\n *\n * Returns title, address, phone, website, GPS, rating, reviews_count,\n * rating_summary (per-star distribution), categories, extensions\n * (service_options, accessibility, offerings, payments), weekly\n * operating hours, popular_times graph, provider_id,\n * permanently_closed, thumbnail, and photo list.\n */\n async place(params: MapsPlaceParams): Promise<GoogleResponse> {\n if (!params.place_id && !params.data_id) {\n throw new Error(\"place_id or data_id is required\");\n }\n return this.client.request<GoogleResponse>(\"/v1/google/maps/place\", {\n params: { ...params },\n });\n }\n\n /**\n * Get reviews for a place (paginated, optional topic filter).\n *\n * Pass the `next_page_token` from `response.pagination.next` for\n * subsequent pages, or use `topic_id` from `response.topics[].id`\n * to scope to a specific review topic.\n */\n async reviews(params: MapsReviewsParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/maps/reviews\", {\n params: { ...params },\n });\n }\n\n /**\n * Get photos for a place with place-specific categories.\n *\n * Returns place-specific categories (Menu, Vibe, Comfort food, dish\n * names) and photo URLs from all CDN families. Use `category_id` to\n * scope to a category, or `page_size: 200` to fetch all photos in\n * one call (Google caps at ~120 photos per response).\n */\n async photos(params: MapsPhotosParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/maps/photos\", {\n params: { ...params },\n });\n }\n\n /** Get business posts (promotional updates, announcements) for a place. */\n async posts(params: MapsPostsParams): Promise<GoogleResponse> {\n if (!params.data_id && !params.place_id) {\n throw new Error(\"data_id or place_id is required\");\n }\n return this.client.request<GoogleResponse>(\"/v1/google/maps/posts\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google News API client — search, topics, trending.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n GoogleResponse,\n NewsSearchParams,\n NewsTopicsParams,\n NewsTrendingParams,\n} from \"./types.js\";\n\n/**\n * Client for Google News endpoints.\n *\n * @example\n * ```typescript\n * const articles = await client.google.news.search({ q: \"openai\" });\n * const tech = await client.google.news.topics({ topic: \"TECHNOLOGY\" });\n * const trending = await client.google.news.trending();\n * ```\n */\nexport class NewsClient {\n constructor(private readonly client: BaseClient) {}\n\n /**\n * Search Google News. One of `q`, `topic_token`, `publication_token`,\n * or `story_token` is required (or pass no params for the trending\n * home feed). Returns `menu_links`, `news_results`, `related_topics`.\n */\n async search(params: NewsSearchParams = {}): Promise<GoogleResponse> {\n if (!params.q && !params.topic_token && !params.publication_token && !params.story_token) {\n throw new Error(\"Provide q, topic_token, publication_token, or story_token\");\n }\n return this.client.request<GoogleResponse>(\"/v1/google/news/search\", {\n params: { ...params },\n });\n }\n\n async topics(params: NewsTopicsParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/news/topics\", {\n params: { ...params },\n });\n }\n\n async trending(params: NewsTrendingParams = {}): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/news/trending\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Patents API client — search, detail.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, PatentsDetailParams, PatentsSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Patents endpoints.\n *\n * @example\n * ```typescript\n * const results = await client.google.patents.search({\n * q: \"distributed lock\",\n * assignee: \"Google\",\n * });\n * ```\n */\nexport class PatentsClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: PatentsSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/patents/search\", {\n params: { ...params },\n });\n }\n\n /**\n * Get rich patent document details by patent number.\n *\n * Response includes full abstract + every claim + complete description,\n * plus structured `cpc_classifications` (code + description), split\n * `backward_citations` / `forward_citations` (with `primary_examiner`\n * flag), `non_patent_citations`, `concepts` (research fields),\n * `legal_events` (prosecution history), `figures` (full-res URLs),\n * every `inventor`, and the full `assignees_original` history.\n */\n async detail(params: PatentsDetailParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/patents/detail\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Products API client (immersive product detail).\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, ProductsDetailParams } from \"./types.js\";\n\n/**\n * Client for Google's immersive product detail endpoint.\n */\nexport class ProductsClient {\n constructor(private readonly client: BaseClient) {}\n\n async detail(params: ProductsDetailParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/products/detail\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Scholar API client.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n GoogleResponse,\n ScholarAuthorCitationParams,\n ScholarAuthorParams,\n ScholarCiteParams,\n ScholarProfilesParams,\n ScholarSearchParams,\n} from \"./types.js\";\n\n/**\n * Client for Google Scholar — search, author profiles, citation charts,\n * and citation formats.\n *\n * Search results carry doc `id`, `type` badge, wrapped `inline_links`\n * (versions + cited_by + related), PDF `resources`, and author objects\n * with `author_id` for pipe-through into {@link ScholarClient.author}.\n * The author endpoint returns structured `interests_detailed`,\n * publications with per-article `citation_id` + nested `cited_by`, and\n * lifetime + since-year citation stats.\n *\n * @example\n * ```typescript\n * const papers = await client.google.scholar.search({\n * q: \"transformer neural networks\",\n * as_ylo: 2020,\n * });\n * const first = papers.scholar_results[0];\n * // Pipe a profiled author into the author endpoint:\n * if (first.authors[0].author_id) {\n * const profile = await client.google.scholar.author({\n * author_id: first.authors[0].author_id,\n * });\n * }\n * ```\n */\nexport class ScholarClient {\n constructor(private readonly client: BaseClient) {}\n\n /**\n * Search Google Scholar. Returns each result with doc `id`, `type`\n * badge, wrapped `inline_links`, PDF `resources`, and structured\n * authors. Envelope includes `scholar_results` alias,\n * `related_searches`, and matched `profiles` cards.\n */\n async search(params: ScholarSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/scholar/search\", {\n params: { ...params },\n });\n }\n\n /** Search Google Scholar for author profiles by name. */\n async profiles(params: ScholarProfilesParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/scholar/profiles\", {\n params: { ...params },\n });\n }\n\n /**\n * Full Scholar author profile: structured `interests_detailed`,\n * publications (with per-article `citation_id` + nested\n * `cited_by{value, link, citation_id}`), stats, and co-authors.\n */\n async author(params: ScholarAuthorParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/scholar/author\", {\n params: { ...params },\n });\n }\n\n /** Citations-per-year chart for a Scholar author. */\n async authorCitation(params: ScholarAuthorCitationParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/scholar/author/citation\", {\n params: { ...params },\n });\n }\n\n /**\n * MLA / APA / Chicago / Harvard / Vancouver citation formats plus\n * BibTeX / RIS / EndNote / RefWorks export links for a paper.\n */\n async cite(params: ScholarCiteParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/scholar/cite\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Web Search (SERP) API client.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, GoogleSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Web Search.\n *\n * @example\n * ```typescript\n * const serp = await client.google.search.search({ q: \"python 3.13\" });\n * for (const r of serp.organic_results as any[]) {\n * console.log(r.title, r.link);\n * }\n * ```\n */\nexport class SearchClient {\n constructor(private readonly client: BaseClient) {}\n\n /**\n * Search Google and get a structured SERP response with organic results,\n * knowledge graph, People Also Ask, related searches, AI overview, and\n * pagination.\n */\n async search(params: GoogleSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/search\", { params: { ...params } });\n }\n\n /**\n * Lightweight Google Search — organic results + related searches only.\n *\n * ~40% faster than {@link search}. Skips ads, Knowledge Graph, AI\n * Overview, local pack, news, inline videos, and shopping blocks.\n * Credit cost is configured per-endpoint by admins — query\n * `/public/pricing` for the live rate.\n *\n * @example\n * ```typescript\n * const lite = await client.google.search.light({ q: \"python 3.13\" });\n * ```\n */\n async light(params: GoogleSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/search\", {\n params: { ...params, mode: \"fast\" },\n });\n }\n}\n","/**\n * Google Shopping API client — search and product detail.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n GoogleResponse,\n ShoppingClickParams,\n ShoppingProductParams,\n ShoppingSearchParams,\n} from \"./types.js\";\n\n/**\n * Client for Google Shopping endpoints.\n *\n * Each search tile now carries Google's native `gpcid`, `catalog_id`,\n * `headline_offer_docid`, `image_docid`, and `mid`, so callers can pipe a\n * tile directly into `client.google.products.detail()` for full specs\n * plus merchant offers via the fast `/async/oapv` RPC (~2s).\n *\n * @example\n * ```typescript\n * const products = await client.google.shopping.search({ q: \"laptop\" });\n * const first = (products.results as any[])[0];\n * const detail = await client.google.products.detail({\n * product_id: first.gpcid,\n * q: \"laptop\",\n * include_offers: true, // real merchant URLs from /async/piu_ps\n * });\n * ```\n */\nexport class ShoppingClient {\n constructor(private readonly client: BaseClient) {}\n\n /** Search Google Shopping for products. */\n async search(params: ShoppingSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/shopping/search\", {\n params: { ...params },\n });\n }\n\n /** Fetch the Google Shopping product detail page by `product_id`. */\n async product(params: ShoppingProductParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/shopping/product\", {\n params: { ...params },\n });\n }\n\n /**\n * Resolve the direct merchant URL for a Shopping product tile via\n * Google's \"I'm Feeling Lucky\" redirect (scoped to the card's `source`\n * merchant via the `site:` operator). You only pay for the call when\n * you actually want the merchant link — no bulk enrichment of every\n * tile.\n */\n async click(params: ShoppingClickParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/shopping/product/click\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Shorts API client — short-form vertical video results.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, ShortsSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Shorts search (`udm=39`).\n *\n * Returns a carousel of short-form videos — YouTube Shorts plus\n * TikToks, Instagram Reels, Facebook Reels, and other platforms.\n * Every tile carries `title`, `link`, `source` (platform),\n * `account_name`, `thumbnail`, `image` (inline preview),\n * `duration`, and `video_id` (YouTube only).\n *\n * @example\n * ```typescript\n * const shorts = await client.google.shorts.search({ q: \"cooking hacks\" });\n * for (const v of shorts.short_videos_results) {\n * console.log(v.rank, v.title, v.source, v.account_name);\n * }\n * ```\n */\nexport class ShortsClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: ShortsSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/shorts/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Trends API client — interest, regions, related, trending.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type {\n GoogleResponse,\n TrendsAutocompleteParams,\n TrendsInterestParams,\n TrendsRegionsParams,\n TrendsRelatedParams,\n TrendsSearchParams,\n TrendsTrendingNowParams,\n TrendsTrendingParams,\n} from \"./types.js\";\n\n/**\n * Client for Google Trends endpoints.\n *\n * @example\n * ```typescript\n * const interest = await client.google.trends.interest({\n * q: \"python,javascript\",\n * date: \"today 12-m\",\n * });\n * ```\n */\nexport class TrendsClient {\n constructor(private readonly client: BaseClient) {}\n\n async interest(params: TrendsInterestParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/interest\", {\n params: { ...params },\n });\n }\n\n async regions(params: TrendsRegionsParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/regions\", {\n params: { ...params },\n });\n }\n\n async related(params: TrendsRelatedParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/related\", {\n params: { ...params },\n });\n }\n\n async trending(params: TrendsTrendingParams = {}): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/trending\", {\n params: { ...params },\n });\n }\n\n /**\n * Current trending searches with the full Google Trends UI filter set\n * — `geo`, `hours`, `category`, `status`, `sort`, `hl`.\n */\n async trendingNow(params: TrendsTrendingNowParams = {}): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/trending-now\", {\n params: { ...params },\n });\n }\n\n /**\n * Unified Google Trends query — pick the response shape via\n * `data_type` (TIMESERIES | GEO_MAP | GEO_MAP_0 | RELATED_TOPICS |\n * RELATED_QUERIES).\n */\n async search(params: TrendsSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/search\", {\n params: { ...params },\n });\n }\n\n /**\n * Return categorized Knowledge Graph topic entities (`mid`, `type`,\n * direct link into Trends explore) for a query prefix. Distinct from\n * Google Search autocomplete.\n */\n async autocomplete(params: TrendsAutocompleteParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/trends/autocomplete\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Videos API client.\n *\n * Returns up to 10 tiles per page with `title`, `link`\n * (YouTube / Vimeo / etc.), `displayed_link`, `snippet`, `thumbnail`,\n * `image` (inline base-64), `favicon`, `duration`, `channel`,\n * `source` (platform), `date`, `video_id`, and raw `extensions`.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport type { GoogleResponse, VideosSearchParams } from \"./types.js\";\n\n/**\n * Client for Google Videos search.\n *\n * @example\n * ```typescript\n * const res = await client.google.videos.search({ q: \"python tutorial\" });\n * for (const v of res.results) {\n * console.log(v.rank, v.title, v.duration, v.channel);\n * }\n * ```\n */\nexport class VideosClient {\n constructor(private readonly client: BaseClient) {}\n\n async search(params: VideosSearchParams): Promise<GoogleResponse> {\n return this.client.request<GoogleResponse>(\"/v1/google/videos/search\", {\n params: { ...params },\n });\n }\n}\n","/**\n * Google Scraper API aggregator — exposes all 16 Google product sub-clients.\n */\n\nimport type { BaseClient } from \"../internal/client.js\";\nimport { AiModeClient } from \"./ai-mode.js\";\nimport { AutocompleteClient } from \"./autocomplete.js\";\nimport { FinanceClient } from \"./finance.js\";\nimport { FlightsClient } from \"./flights.js\";\nimport { HotelsClient } from \"./hotels.js\";\nimport { ImagesClient } from \"./images.js\";\nimport { JobsClient } from \"./jobs.js\";\nimport { LensClient } from \"./lens.js\";\nimport { MapsClient } from \"./maps.js\";\nimport { NewsClient } from \"./news.js\";\nimport { PatentsClient } from \"./patents.js\";\nimport { ProductsClient } from \"./products.js\";\nimport { ScholarClient } from \"./scholar.js\";\nimport { SearchClient } from \"./search.js\";\nimport { ShoppingClient } from \"./shopping.js\";\nimport { ShortsClient } from \"./shorts.js\";\nimport { TrendsClient } from \"./trends.js\";\nimport { VideosClient } from \"./videos.js\";\n\n/**\n * Google Scraper API client with access to all 19 Google product APIs.\n *\n * @example\n * ```typescript\n * const client = new ScrapeBadger({ apiKey: \"key\" });\n *\n * const serp = await client.google.search.search({ q: \"python 3.13\" });\n * const places = await client.google.maps.search({ q: \"coffee shops sf\" });\n * const products = await client.google.shopping.search({ q: \"laptop\" });\n *\n * // Per-product merchant URL enrichment\n * const enriched = await client.google.shopping.click({\n * title: (products.results as any[])[0].title,\n * source: (products.results as any[])[0].source,\n * });\n * console.log(enriched.merchant_url);\n *\n * // New in v0.3: Shorts, Flights, and Scholar depth\n * const shorts = await client.google.shorts.search({ q: \"cooking hacks\" });\n * const flights = await client.google.flights.search({\n * departure_id: \"JFK\",\n * arrival_id: \"LHR\",\n * outbound_date: \"2026-06-15\",\n * return_date: \"2026-06-22\",\n * });\n * const profiles = await client.google.scholar.profiles({\n * mauthors: \"Geoffrey Hinton\",\n * });\n * ```\n */\nexport class GoogleClient {\n /** Google Web Search (SERP) — with optional deferred AI Overview follow-up. */\n readonly search: SearchClient;\n /** Google Maps — places, reviews, photos, posts. */\n readonly maps: MapsClient;\n /** Google News — articles, topics, trending. */\n readonly news: NewsClient;\n /** Google Hotels — search and property details. */\n readonly hotels: HotelsClient;\n /** Google Trends — interest, regions, related, trending, topic autocomplete. */\n readonly trends: TrendsClient;\n /** Google Jobs. */\n readonly jobs: JobsClient;\n /** Google Shopping — search, details, click enrichment. */\n readonly shopping: ShoppingClient;\n /** Google Patents — search and document details. */\n readonly patents: PatentsClient;\n /** Google Scholar — search, profiles, author, author citation, cite formats. */\n readonly scholar: ScholarClient;\n /** Google Autocomplete — search suggestions. */\n readonly autocomplete: AutocompleteClient;\n /** Google Images. */\n readonly images: ImagesClient;\n /** Google Videos. */\n readonly videos: VideosClient;\n /** Google Finance — stock and index quotes. */\n readonly finance: FinanceClient;\n /** Google AI Mode — generative answer responses. */\n readonly aiMode: AiModeClient;\n /** Google Lens — visual image search. */\n readonly lens: LensClient;\n /** Google Shorts — short-form vertical video results (udm=39). */\n readonly shorts: ShortsClient;\n /** Google Flights — one-way, round-trip, and multi-city itineraries. */\n readonly flights: FlightsClient;\n /** Google Products — immersive product detail. */\n readonly products: ProductsClient;\n\n constructor(client: BaseClient) {\n this.search = new SearchClient(client);\n this.maps = new MapsClient(client);\n this.news = new NewsClient(client);\n this.hotels = new HotelsClient(client);\n this.trends = new TrendsClient(client);\n this.jobs = new JobsClient(client);\n this.shopping = new ShoppingClient(client);\n this.patents = new PatentsClient(client);\n this.scholar = new ScholarClient(client);\n this.autocomplete = new AutocompleteClient(client);\n this.images = new ImagesClient(client);\n this.videos = new VideosClient(client);\n this.finance = new FinanceClient(client);\n this.aiMode = new AiModeClient(client);\n this.lens = new LensClient(client);\n this.shorts = new ShortsClient(client);\n this.flights = new FlightsClient(client);\n this.products = new ProductsClient(client);\n }\n}\n","/**\n * Main ScrapeBadger client.\n *\n * This is the primary entry point for the ScrapeBadger SDK.\n */\n\nimport { BaseClient } from \"./internal/client.js\";\nimport { type ScrapeBadgerConfig, resolveConfig, getApiKeyFromEnv } from \"./internal/config.js\";\nimport { TwitterClient } from \"./twitter/client.js\";\nimport { WebClient } from \"./web/client.js\";\nimport { VintedClient } from \"./vinted/client.js\";\nimport { GoogleClient } from \"./google/client.js\";\n\n/**\n * ScrapeBadger API client.\n *\n * The main client for interacting with the ScrapeBadger API.\n * Provides access to all available scrapers through typed sub-clients.\n *\n * @example\n * ```typescript\n * import { ScrapeBadger } from \"scrapebadger\";\n *\n * // Create client with API key\n * const client = new ScrapeBadger({ apiKey: \"your-api-key\" });\n *\n * // Or use environment variable (SCRAPEBADGER_API_KEY)\n * const client = new ScrapeBadger();\n *\n * // Access Twitter API\n * const tweet = await client.twitter.tweets.getById(\"1234567890\");\n * const user = await client.twitter.users.getByUsername(\"elonmusk\");\n *\n * // Search with automatic pagination\n * for await (const tweet of client.twitter.tweets.searchAll(\"python\")) {\n * console.log(tweet.text);\n * }\n *\n * // Collect all results into an array\n * import { collectAll } from \"scrapebadger\";\n * const tweets = await collectAll(\n * client.twitter.tweets.searchAll(\"python\", { maxItems: 100 })\n * );\n * ```\n */\nexport class ScrapeBadger {\n private readonly baseClient: BaseClient;\n\n /** Twitter API client */\n readonly twitter: TwitterClient;\n\n /** Web scraping API client */\n readonly web: WebClient;\n\n /** Vinted scraper API client */\n readonly vinted: VintedClient;\n\n /** Google Scraper API client — 19 Google product APIs */\n readonly google: GoogleClient;\n\n /**\n * Create a new ScrapeBadger client.\n *\n * @param config - Configuration options. If apiKey is not provided,\n * it will be read from the SCRAPEBADGER_API_KEY environment variable.\n * @throws Error if no API key is provided or found in environment.\n *\n * @example\n * ```typescript\n * // With explicit API key\n * const client = new ScrapeBadger({ apiKey: \"your-api-key\" });\n *\n * // With custom options\n * const client = new ScrapeBadger({\n * apiKey: \"your-api-key\",\n * baseUrl: \"https://custom.api.com\",\n * timeout: 60000,\n * maxRetries: 5\n * });\n *\n * // Using environment variable\n * // Set SCRAPEBADGER_API_KEY=your-api-key\n * const client = new ScrapeBadger();\n * ```\n */\n constructor(config: Partial<ScrapeBadgerConfig> = {}) {\n // Use provided API key or fall back to environment variable\n const apiKey = config.apiKey ?? getApiKeyFromEnv();\n\n if (!apiKey) {\n throw new Error(\n \"API key is required. Pass it in the config or set SCRAPEBADGER_API_KEY environment variable.\"\n );\n }\n\n const resolvedConfig = resolveConfig({ ...config, apiKey });\n this.baseClient = new BaseClient(resolvedConfig);\n\n // Initialize sub-clients\n this.twitter = new TwitterClient(this.baseClient);\n this.web = new WebClient(this.baseClient);\n this.vinted = new VintedClient(this.baseClient);\n this.google = new GoogleClient(this.baseClient);\n }\n}\n"]}
|