{"version":3,"sources":["../src/lib/auth/oauth.ts","../src/lib/auth/tokenProvider.ts","../src/lib/http/httpClient.ts","../src/lib/kickClient.ts","../src/lib/types.ts","../src/lib/resources/channels.ts","../src/lib/resources/chat.ts","../src/lib/resources/public.ts","../src/lib/resources/users.ts","../src/lib/resources.ts"],"names":["oauth","z","Bottleneck","pRetry","AbortError"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as oauth from 'oauth4webapi';\nimport type { AccessToken, TokenProvider } from './tokenProvider';\n\nexport interface OAuthClientCredentialsConfig {\n  issuerUrl: string;\n  tokenEndpoint: string;\n  clientId: string;\n  clientSecret: string;\n  scope?: string;\n}\n\nexport class ClientCredentialsTokenProvider implements TokenProvider {\n  private cached: AccessToken | undefined;\n  private readonly as: oauth.AuthorizationServer;\n  private readonly client: oauth.Client;\n  private readonly scope: string | undefined;\n\n  constructor(cfg: OAuthClientCredentialsConfig) {\n    this.as = {\n      issuer: cfg.issuerUrl,\n      token_endpoint: cfg.tokenEndpoint,\n    } satisfies oauth.AuthorizationServer;\n\n    this.client = {\n      client_id: cfg.clientId,\n      client_secret: cfg.clientSecret,\n      token_endpoint_auth_method: 'client_secret_basic',\n    } satisfies oauth.Client;\n\n    this.scope = cfg.scope;\n  }\n\n  async getAccessToken(): Promise<AccessToken | undefined> {\n    if (this.cached && !isExpired(this.cached, 30)) {\n      return this.cached;\n    }\n\n    const form = new URLSearchParams();\n    if (this.scope) form.set('scope', this.scope);\n\n    const response = await oauth.clientCredentialsGrantRequest(this.as, this.client, form);\n\n    const result = await oauth.processClientCredentialsResponse(this.as, this.client, response);\n    if (oauth.isOAuth2Error(result)) {\n      throw new Error(`OAuth error: ${result.error}`);\n    }\n\n    const expiresAtEpochMs = result.expires_in ? Date.now() + result.expires_in * 1000 : undefined;\n    const next: AccessToken = {\n      token: result.access_token,\n      ...(expiresAtEpochMs !== undefined ? { expiresAtEpochMs } : {}),\n      ...(result.scope ? { scope: result.scope.split(' ') } : {}),\n    };\n    this.cached = next;\n    return this.cached;\n  }\n\n  async onTokenInvalid(): Promise<void> {\n    this.cached = undefined;\n  }\n}\n\nfunction isExpired(token: AccessToken, skewSeconds: number): boolean {\n  if (!token.expiresAtEpochMs) return false;\n  return Date.now() + skewSeconds * 1000 >= token.expiresAtEpochMs;\n}\n","export interface AccessToken {\n  token: string;\n  expiresAtEpochMs?: number;\n  scope?: string[];\n}\n\nexport interface TokenProvider {\n  getAccessToken(): Promise<AccessToken | undefined>;\n  onTokenInvalid?(): void | Promise<void>;\n}\n\nexport class StaticTokenProvider implements TokenProvider {\n  private readonly token: AccessToken;\n  constructor(token: string) {\n    this.token = { token };\n  }\n  async getAccessToken(): Promise<AccessToken> {\n    return this.token;\n  }\n}\n","import Bottleneck from 'bottleneck';\nimport pRetry, { AbortError } from 'p-retry';\nimport { z } from 'zod';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport interface HttpRequest {\n  method: HttpMethod;\n  url: string;\n  headers?: Record<string, string>;\n  query?: Record<string, string | number | boolean | undefined>;\n  body?: unknown;\n  timeoutMs?: number;\n}\n\nexport interface HttpResponse<T = unknown> {\n  status: number;\n  headers: Record<string, string>;\n  data: T | undefined;\n}\n\nexport interface RetryPolicyOptions {\n  retries: number;\n  minTimeoutMs: number;\n  maxTimeoutMs: number;\n  factor?: number;\n}\n\nexport interface RateLimitOptions {\n  maxConcurrent?: number;\n  minTimeMs?: number;\n}\n\nexport interface HttpClientOptions {\n  baseUrl: string;\n  defaultHeaders?: Record<string, string>;\n  rateLimit?: RateLimitOptions;\n  retry?: RetryPolicyOptions;\n  userAgent?: string | undefined;\n}\n\nexport class ApiError<T = any> extends Error {\n  readonly status: number;\n  readonly data?: T;\n\n  constructor(message: string, status: number, data?: T) {\n    super(message);\n    this.name = 'ApiError';\n    this.status = status;\n    if (data !== undefined) {\n      this.data = data;\n    }\n  }\n}\n\nconst errorResponseSchema = z.object({\n  message: z.string().optional(),\n  error: z.unknown().optional(),\n});\n\nexport class HttpClient {\n  private readonly limiter: Bottleneck | undefined;\n  private readonly options: HttpClientOptions;\n\n  constructor(options: HttpClientOptions) {\n    this.options = options;\n    this.limiter = options.rateLimit\n      ? new Bottleneck({\n          maxConcurrent: options.rateLimit.maxConcurrent ?? 4,\n          minTime: options.rateLimit.minTimeMs ?? 100,\n        })\n      : undefined;\n  }\n\n  async request<T = unknown>(req: HttpRequest): Promise<HttpResponse<T>> {\n    const execute = async (): Promise<HttpResponse<T>> => {\n      const url = this.buildUrl(req.url, req.query);\n      const headers: Record<string, string> = {\n        'content-type': 'application/json',\n        ...(this.options.userAgent ? { 'user-agent': this.options.userAgent } : {}),\n        ...this.options.defaultHeaders,\n        ...req.headers,\n      };\n\n      const controller = new AbortController();\n      const timeout = req.timeoutMs ?? 30_000;\n      const timer = setTimeout(() => controller.abort(), timeout);\n\n      try {\n        const init: globalThis.RequestInit = {\n          method: req.method,\n          headers,\n          signal: controller.signal,\n        };\n        if (req.body !== undefined) {\n          (init as any).body = JSON.stringify(req.body);\n        }\n        const res = await fetch(url, init);\n\n        const responseHeaders: Record<string, string> = {};\n        res.headers.forEach((value, key) => {\n          responseHeaders[key.toLowerCase()] = value;\n        });\n\n        const text = await res.text();\n        const data = text ? (safeJsonParse(text) as T | unknown) : undefined;\n\n        if (!res.ok) {\n          const parsed = errorResponseSchema.safeParse(data);\n          const message =\n            parsed.success && parsed.data.message ? parsed.data.message : `HTTP ${res.status}`;\n          throw new ApiError(message, res.status, data);\n        }\n\n        return { status: res.status, headers: responseHeaders, data: data as T | undefined };\n      } catch (error: any) {\n        if (error?.name === 'AbortError') {\n          throw new ApiError('Request timed out', 408);\n        }\n        throw error;\n      } finally {\n        clearTimeout(timer);\n      }\n    };\n\n    const run = async () => (this.limiter ? this.limiter.schedule(execute) : execute());\n\n    return this.retry(run);\n  }\n\n  private async retry<T>(fn: () => Promise<T>): Promise<T> {\n    const retry = this.options.retry ?? {\n      retries: 3,\n      minTimeoutMs: 250,\n      maxTimeoutMs: 2_000,\n      factor: 2,\n    };\n\n    try {\n      return await pRetry(fn, {\n        retries: retry.retries,\n        factor: retry.factor ?? 2,\n        minTimeout: retry.minTimeoutMs,\n        maxTimeout: retry.maxTimeoutMs,\n        randomize: true,\n        onFailedAttempt: (err) => {\n          const cause = err as any;\n          const status = cause instanceof ApiError ? cause.status : undefined;\n          const retriable = !status || (status >= 500 && status < 600) || status === 429;\n          if (!retriable) {\n            throw new AbortError(cause);\n          }\n        },\n      });\n    } catch (err: any) {\n      if (err instanceof AbortError && (err as any).originalError) {\n        throw (err as any).originalError;\n      }\n      throw err;\n    }\n  }\n\n  private buildUrl(path: string, query?: HttpRequest['query']): string {\n    const base = this.options.baseUrl.replace(/\\/$/, '');\n    const rel = path.startsWith('/') ? path : `/${path}`;\n    const url = new URL(base + rel);\n    if (query) {\n      for (const [key, value] of Object.entries(query)) {\n        if (value === undefined) continue;\n        url.searchParams.set(key, String(value));\n      }\n    }\n    return url.toString();\n  }\n}\n\nfunction safeJsonParse(text: string): unknown {\n  try {\n    return JSON.parse(text);\n  } catch {\n    return text;\n  }\n}\n","import type { TokenProvider } from './auth/tokenProvider';\nimport { HttpClient, type HttpRequest } from './http/httpClient';\n\nexport interface KickClientOptions {\n  baseUrl?: string;\n  tokenProvider?: TokenProvider | undefined;\n  userAgent?: string | undefined;\n}\n\nexport class KickClient {\n  private readonly http: HttpClient;\n  private readonly tokenProvider: TokenProvider | undefined;\n\n  constructor(options: KickClientOptions = {}) {\n    const baseUrl = options.baseUrl ?? 'https://api.kick.com';\n    this.tokenProvider = options.tokenProvider;\n    this.http = new HttpClient({ baseUrl, userAgent: options.userAgent ?? undefined });\n  }\n\n  async request<T>(\n    req: Omit<HttpRequest, 'headers'> & { headers?: Record<string, string> },\n  ): Promise<T> {\n    const headers: Record<string, string> = { ...req.headers };\n\n    if (this.tokenProvider) {\n      const token = await this.tokenProvider.getAccessToken();\n      if (token?.token) {\n        headers['authorization'] = `Bearer ${token.token}`;\n      }\n    }\n\n    const res = await this.http.request<T>({ ...req, headers });\n    return res.data as T;\n  }\n}\n","import { z } from 'zod';\n\nexport const UserSchema = z.object({\n  id: z.number(),\n  username: z.string(),\n  slug: z.string().optional(),\n});\nexport type User = z.infer<typeof UserSchema>;\n\nexport const ChannelSchema = z.object({\n  id: z.number(),\n  slug: z.string(),\n  title: z.string().optional(),\n  is_live: z.boolean().optional(),\n});\nexport type Channel = z.infer<typeof ChannelSchema>;\n","import type { KickClient } from '../kickClient';\nimport { ChannelSchema, type Channel } from '../types';\n\nexport class ChannelsApi {\n  constructor(private readonly client: KickClient) {}\n\n  async getBySlug(slug: string): Promise<Channel> {\n    const data = await this.client.request<unknown>({\n      method: 'GET',\n      url: `/public/v1/channels?slug=${encodeURIComponent(slug)}`,\n    });\n    return ChannelSchema.parse(data);\n  }\n}\n","import type { KickClient } from '../kickClient';\n\nexport interface SendMessageRequest {\n  message: string;\n}\n\nexport interface SendMessageResponse {\n  id: string;\n  message: string;\n}\n\nexport interface ChatRoom {\n  id: string;\n  channel_id: number;\n  slow_mode: boolean;\n  message_interval: number;\n  following_min_duration: number;\n}\n\nexport class ChatApi {\n  constructor(private readonly client: KickClient) {}\n\n  async sendMessage(channelSlug: string, req: SendMessageRequest): Promise<SendMessageResponse> {\n    // Placeholder path; adjust per official docs\n    return this.client.request<SendMessageResponse>({\n      method: 'POST',\n      url: `/channels/${encodeURIComponent(channelSlug)}/chat/messages`,\n      body: req,\n    });\n  }\n\n  async getChatRoom(channelId: number): Promise<ChatRoom> {\n    // Placeholder path; adjust per official docs\n    return this.client.request<ChatRoom>({\n      method: 'GET',\n      url: `/channels/${channelId}/chatroom`,\n    });\n  }\n}\n","import type { KickClient } from '../kickClient';\n\nexport interface UserPublic {\n  id: number;\n  username: string;\n  slug?: string;\n}\n\nexport class PublicApi {\n  constructor(private readonly client: KickClient) {}\n\n  async getUserBySlug(slug: string): Promise<UserPublic> {\n    // Using the public users endpoint - may need to adjust based on actual API capabilities\n    return this.client.request<UserPublic>({\n      method: 'GET',\n      url: `/public/v1/users?slug=${encodeURIComponent(slug)}`,\n    });\n  }\n}\n","import type { KickClient } from '../kickClient';\nimport { UserSchema, type User } from '../types';\n\nexport interface CurrentUser {\n  id: number;\n  username: string;\n  email: string;\n  slug?: string;\n}\n\nexport class UsersApi {\n  constructor(private readonly client: KickClient) {}\n\n  async getById(id: number): Promise<User> {\n    const data = await this.client.request<unknown>({ method: 'GET', url: `/users/${id}` });\n    return UserSchema.parse(data);\n  }\n\n  async getBySlug(slug: string): Promise<User> {\n    // Note: Kick API doesn't have a direct slug lookup, so we'll try the old endpoint for now\n    // This may need to be updated based on actual API capabilities\n    const data = await this.client.request<unknown>({ method: 'GET', url: `/users/${slug}` });\n    return UserSchema.parse(data);\n  }\n\n  async getCurrentUser(): Promise<CurrentUser> {\n    const data = await this.client.request<unknown>({ method: 'GET', url: '/public/v1/users' });\n    return data as CurrentUser;\n  }\n}\n","import type { KickClient } from './kickClient';\nimport { ChannelsApi } from './resources/channels';\nimport { ChatApi } from './resources/chat';\nimport { PublicApi } from './resources/public';\nimport { UsersApi } from './resources/users';\n\nexport class Resources {\n  readonly public: PublicApi;\n  readonly users: UsersApi;\n  readonly channels: ChannelsApi;\n  readonly chat: ChatApi;\n  constructor(client: KickClient) {\n    this.public = new PublicApi(client);\n    this.users = new UsersApi(client);\n    this.channels = new ChannelsApi(client);\n    this.chat = new ChatApi(client);\n  }\n}\n"]}