{"version":3,"sources":["../src/index.ts","../src/utils/cache.ts","../src/utils/retry.ts","../src/core/errors.ts","../src/core/auth.ts","../src/core/interceptors.ts","../src/core/logger.ts","../src/core/http-client.ts","../src/repositories/base.repository.ts","../src/repositories/categories.repository.ts","../src/repositories/comments.repository.ts","../src/repositories/currencies.repository.ts","../src/repositories/expenses.repository.ts","../src/repositories/friends.repository.ts","../src/repositories/groups.repository.ts","../src/repositories/notifications.repository.ts","../src/repositories/users.repository.ts"],"sourcesContent":["/**\n * Splitwise SDK – public API surface.\n *\n * Usage:\n * ```ts\n * import { Splitwise } from \"splitwise-sdk\";\n *\n * const sw = new Splitwise({ accessToken: \"your_token\" });\n * const user = await sw.users.getCurrentUser();\n * ```\n */\n\nimport type { TokenProvider } from \"./core/auth.js\";\nimport { HttpClient, type HttpClientConfig } from \"./core/http-client.js\";\nimport type { Logger, LogLevel } from \"./core/logger.js\";\nimport { CallbackLogger, DefaultLogger } from \"./core/logger.js\";\nimport type { CacheConfig } from \"./utils/cache.js\";\nimport type { RetryConfig } from \"./utils/retry.js\";\n\nimport { CategoriesRepository } from \"./repositories/categories.repository.js\";\nimport { CommentsRepository } from \"./repositories/comments.repository.js\";\nimport { CurrenciesRepository } from \"./repositories/currencies.repository.js\";\nimport { ExpensesRepository } from \"./repositories/expenses.repository.js\";\nimport { FriendsRepository } from \"./repositories/friends.repository.js\";\nimport { GroupsRepository } from \"./repositories/groups.repository.js\";\nimport { NotificationsRepository } from \"./repositories/notifications.repository.js\";\nimport { UsersRepository } from \"./repositories/users.repository.js\";\n\n// ── Options ──────────────────────────────────────────────────────────\n\nexport interface SplitwiseOptions {\n  /**\n   * Access token (string) or an async/sync function that returns one.\n   * OAuth flow / token acquisition is the consumer's responsibility.\n   */\n  accessToken: TokenProvider;\n\n  /** Base URL override for the Splitwise API. */\n  baseUrl?: string;\n\n  /**\n   * Logger instance, callback, or log level string.\n   * - `Logger` object: used directly\n   * - `(msg: string) => void`: wrapped into a structured logger\n   * - `LogLevel` string: creates a DefaultLogger at that level\n   * - `undefined`: defaults to DefaultLogger(\"info\")\n   */\n  logger?: Logger | ((message: string) => void) | LogLevel;\n\n  /** Retry configuration. Set `{ maxRetries: 0 }` to disable retries. */\n  retry?: Partial<RetryConfig>;\n\n  /** Cache configuration. Set `{ enabled: false }` to disable caching. */\n  cache?: Partial<CacheConfig>;\n}\n\n// ── Client ───────────────────────────────────────────────────────────\n\nexport class Splitwise {\n  public readonly users: UsersRepository;\n  public readonly groups: GroupsRepository;\n  public readonly expenses: ExpensesRepository;\n  public readonly friends: FriendsRepository;\n  public readonly comments: CommentsRepository;\n  public readonly notifications: NotificationsRepository;\n  public readonly currencies: CurrenciesRepository;\n  public readonly categories: CategoriesRepository;\n\n  private readonly http: HttpClient;\n\n  constructor(options: SplitwiseOptions) {\n    const logger = resolveLogger(options.logger);\n\n    const httpConfig: HttpClientConfig = {\n      accessToken: options.accessToken,\n      baseUrl: options.baseUrl,\n      logger,\n      retry: options.retry,\n      cache: options.cache,\n    };\n\n    this.http = new HttpClient(httpConfig);\n\n    this.users = new UsersRepository(this.http);\n    this.groups = new GroupsRepository(this.http);\n    this.expenses = new ExpensesRepository(this.http);\n    this.friends = new FriendsRepository(this.http);\n    this.comments = new CommentsRepository(this.http);\n    this.notifications = new NotificationsRepository(this.http);\n    this.currencies = new CurrenciesRepository(this.http);\n    this.categories = new CategoriesRepository(this.http);\n  }\n\n  /** Clear the internal request cache. */\n  clearCache(): void {\n    this.http.clearCache();\n  }\n\n  /** Dispose the client: stop background timers and clear cache. */\n  dispose(): void {\n    this.http.dispose();\n  }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction resolveLogger(\n  input?: Logger | ((message: string) => void) | LogLevel,\n): Logger {\n  if (!input) return new DefaultLogger();\n  if (typeof input === \"string\") return new DefaultLogger(input);\n  if (typeof input === \"function\") return new CallbackLogger(input);\n  return input;\n}\n\n// ── Re-exports ───────────────────────────────────────────────────────\n\n// Error hierarchy\nexport {\n  AuthenticationError,\n  AuthorizationError,\n  ConflictError,\n  NetworkError,\n  NotFoundError,\n  RateLimitError,\n  SplitwiseApiError,\n  SplitwiseError,\n  ValidationError,\n} from \"./core/errors.js\";\n\n// Logger utilities\nexport { CallbackLogger, DefaultLogger, SilentLogger } from \"./core/logger.js\";\nexport type { LogEntry, Logger, LogLevel } from \"./core/logger.js\";\n\n// Auth type\nexport type { TokenProvider } from \"./core/auth.js\";\n\n// Config types\nexport type { HttpClientConfig } from \"./core/http-client.js\";\nexport type { CacheConfig } from \"./utils/cache.js\";\nexport type { RetryConfig } from \"./utils/retry.js\";\n\n// Generated types – re-export for consumer convenience\nexport type * from \"./generated/types.gen.js\";\n\n// Repositories\nexport {\n  CategoriesRepository,\n  CommentsRepository,\n  CurrenciesRepository,\n  ExpensesRepository,\n  FriendsRepository,\n  GroupsRepository,\n  NotificationsRepository,\n  UsersRepository,\n} from \"./repositories/index.js\";\n","/**\n * In-memory TTL cache with token-specific keys and request deduplication.\n *\n * - Only caches GET requests.\n * - Cache keys include endpoint, query params, and a token fingerprint.\n * - In-flight deduplication prevents duplicate concurrent requests.\n * - Write operations (POST/PUT/PATCH/DELETE) invalidate relevant resource caches.\n */\n\nimport { createHash } from \"node:crypto\";\n\nexport interface CacheConfig {\n  /** Whether caching is enabled. Default: true. */\n  enabled: boolean;\n  /** Default TTL in milliseconds. Default: 300 000 (5 min). */\n  defaultTtlMs: number;\n  /** Per-endpoint TTL overrides. Keys are endpoint path prefixes. */\n  ttlOverrides?: Record<string, number>;\n}\n\nexport const DEFAULT_CACHE_CONFIG: CacheConfig = {\n  enabled: true,\n  defaultTtlMs: 300_000,\n  ttlOverrides: {\n    \"/get_currencies\": 86_400_000, // 24h – rarely changes\n    \"/get_categories\": 86_400_000, // 24h – rarely changes\n  },\n};\n\ninterface CacheEntry<T = unknown> {\n  value: T;\n  expiresAt: number;\n}\n\nexport class RequestCache {\n  private readonly cache = new Map<string, CacheEntry>();\n  private readonly inflight = new Map<string, Promise<unknown>>();\n  private sweepTimer?: ReturnType<typeof setInterval>;\n\n  constructor(private readonly config: CacheConfig) {\n    if (config.enabled) {\n      this.sweepTimer = setInterval(() => this.sweep(), 60_000);\n      // Unref so the timer does not keep the Node.js process alive\n      if (typeof this.sweepTimer === \"object\" && \"unref\" in this.sweepTimer) {\n        this.sweepTimer.unref();\n      }\n    }\n  }\n\n  /** Remove all expired entries. */\n  private sweep(): void {\n    const now = Date.now();\n    for (const [key, entry] of this.cache) {\n      if (now > entry.expiresAt) {\n        this.cache.delete(key);\n      }\n    }\n  }\n\n  /** Stop the sweep timer and clear all entries. Call when discarding the client. */\n  dispose(): void {\n    if (this.sweepTimer) {\n      clearInterval(this.sweepTimer);\n      this.sweepTimer = undefined;\n    }\n    this.clear();\n  }\n\n  /**\n   * Build a cache key that is token-specific.\n   */\n  buildKey(\n    endpoint: string,\n    params: Record<string, unknown> | undefined,\n    tokenFingerprint: string,\n  ): string {\n    const paramStr = params\n      ? JSON.stringify(params, Object.keys(params).sort())\n      : \"\";\n    return `${tokenFingerprint}:${endpoint}:${paramStr}`;\n  }\n\n  /**\n   * Hash a token into a short fingerprint to avoid storing raw tokens in cache keys.\n   */\n  static tokenFingerprint(token: string): string {\n    return createHash(\"sha256\").update(token).digest(\"hex\").slice(0, 16);\n  }\n\n  /**\n   * Try to get a cached value. Returns undefined on miss or expiry.\n   */\n  get<T>(key: string): T | undefined {\n    if (!this.config.enabled) return undefined;\n\n    const entry = this.cache.get(key);\n    if (!entry) return undefined;\n\n    if (Date.now() > entry.expiresAt) {\n      this.cache.delete(key);\n      return undefined;\n    }\n\n    return entry.value as T;\n  }\n\n  /**\n   * Store a value in the cache.\n   */\n  set<T>(key: string, value: T, endpoint: string): void {\n    if (!this.config.enabled) return;\n\n    const ttl = this.getTtl(endpoint);\n    this.cache.set(key, {\n      value,\n      expiresAt: Date.now() + ttl,\n    });\n  }\n\n  /**\n   * Deduplicate concurrent GET requests to the same endpoint+params.\n   * If an identical request is already in-flight, await its result.\n   */\n  async dedup<T>(key: string, factory: () => Promise<T>): Promise<T> {\n    const existing = this.inflight.get(key);\n    if (existing) return existing as Promise<T>;\n\n    const promise = factory().finally(() => {\n      this.inflight.delete(key);\n    });\n\n    this.inflight.set(key, promise);\n    return promise;\n  }\n\n  /**\n   * Invalidate all cache entries whose endpoint matches the given resource prefix.\n   * Uses structural matching on the endpoint part of the cache key to avoid\n   * over-invalidation (e.g. \"/get_group\" does not match \"/get_groups\").\n   */\n  invalidate(resourcePrefix: string): void {\n    for (const key of this.cache.keys()) {\n      // Cache-key format: \"<fingerprint>:<endpoint>:<params>\"\n      const firstColon = key.indexOf(\":\");\n      const secondColon = key.indexOf(\":\", firstColon + 1);\n      const endpointPart = key.substring(\n        firstColon + 1,\n        secondColon === -1 ? undefined : secondColon,\n      );\n\n      if (\n        endpointPart === resourcePrefix ||\n        endpointPart.startsWith(resourcePrefix + \"/\")\n      ) {\n        this.cache.delete(key);\n      }\n    }\n  }\n\n  /**\n   * Clear the entire cache.\n   */\n  clear(): void {\n    this.cache.clear();\n    this.inflight.clear();\n  }\n\n  private getTtl(endpoint: string): number {\n    if (this.config.ttlOverrides) {\n      for (const [prefix, ttl] of Object.entries(this.config.ttlOverrides)) {\n        if (endpoint.startsWith(prefix)) return ttl;\n      }\n    }\n    return this.config.defaultTtlMs;\n  }\n}\n","/**\n * Retry utilities for the Splitwise SDK.\n *\n * - Exponential backoff with jitter\n * - Respects `Retry-After` header (RateLimitError)\n * - Only retries retryable errors: network errors + HTTP 408/429/500/502/503/504\n */\n\nimport type { NetworkError, SplitwiseApiError } from \"../core/errors.js\";\n\nexport interface RetryConfig {\n  /** Maximum number of retries. Default: 3. Set to 0 to disable. */\n  maxRetries: number;\n  /** Base delay in milliseconds for exponential backoff. Default: 500. */\n  baseDelayMs: number;\n  /** Maximum delay in milliseconds. Default: 30 000. */\n  maxDelayMs: number;\n}\n\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n  maxRetries: 3,\n  baseDelayMs: 500,\n  maxDelayMs: 30_000,\n};\n\ntype RetryableError = (SplitwiseApiError | NetworkError) & {\n  retryable: boolean;\n};\n\n/**\n * Determine whether a given error should be retried.\n */\nexport function shouldRetry(\n  error: RetryableError,\n  attempt: number,\n  config: RetryConfig,\n): boolean {\n  if (attempt >= config.maxRetries) return false;\n  return error.retryable;\n}\n\n/**\n * Compute the delay before the next retry attempt.\n *\n * Uses exponential backoff with full jitter, capped at `maxDelayMs`.\n * If the error is a RateLimitError with a `retryAfter` value, that\n * value (in seconds) takes precedence.\n */\nexport function computeDelay(\n  error: RetryableError,\n  attempt: number,\n  config: RetryConfig,\n): number {\n  // Respect Retry-After header for 429/503\n  const retryAfter = (error as unknown as { retryAfter?: number }).retryAfter;\n  if (typeof retryAfter === \"number\") {\n    return Math.min(retryAfter * 1000, config.maxDelayMs);\n  }\n\n  // Exponential backoff with full jitter\n  const exponential = config.baseDelayMs * Math.pow(2, attempt);\n  const capped = Math.min(exponential, config.maxDelayMs);\n  return Math.round(Math.random() * capped);\n}\n","/**\n * Typed error hierarchy for the Splitwise SDK.\n *\n * SplitwiseError (base)\n * ├── SplitwiseApiError (HTTP API errors with status, endpoint, requestId)\n * │   ├── AuthenticationError (401)\n * │   ├── AuthorizationError (403)\n * │   ├── NotFoundError (404)\n * │   ├── ValidationError (400/422)\n * │   ├── ConflictError (409)\n * │   └── RateLimitError (429, includes retryAfter)\n * └── NetworkError (fetch/network/timeout failures)\n */\n\nexport class SplitwiseError extends Error {\n  constructor(\n    message: string,\n    public readonly cause?: unknown,\n  ) {\n    super(message);\n    this.name = \"SplitwiseError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n\nexport class SplitwiseApiError extends SplitwiseError {\n  constructor(\n    message: string,\n    public readonly status: number,\n    public readonly endpoint: string,\n    public readonly requestId: string,\n    public readonly details?: unknown,\n    cause?: unknown,\n  ) {\n    super(message, cause);\n    this.name = \"SplitwiseApiError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n\n  /** Whether this error is eligible for automatic retry. */\n  get retryable(): boolean {\n    return [408, 429, 500, 502, 503, 504].includes(this.status);\n  }\n}\n\nexport class AuthenticationError extends SplitwiseApiError {\n  constructor(\n    endpoint: string,\n    requestId: string,\n    details?: unknown,\n    cause?: unknown,\n  ) {\n    super(\n      \"Authentication failed – invalid or missing access token\",\n      401,\n      endpoint,\n      requestId,\n      details,\n      cause,\n    );\n    this.name = \"AuthenticationError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n\nexport class AuthorizationError extends SplitwiseApiError {\n  constructor(\n    endpoint: string,\n    requestId: string,\n    details?: unknown,\n    cause?: unknown,\n  ) {\n    super(\n      \"Authorization failed – insufficient permissions\",\n      403,\n      endpoint,\n      requestId,\n      details,\n      cause,\n    );\n    this.name = \"AuthorizationError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n\nexport class NotFoundError extends SplitwiseApiError {\n  constructor(\n    endpoint: string,\n    requestId: string,\n    details?: unknown,\n    cause?: unknown,\n  ) {\n    super(\n      `Resource not found: ${endpoint}`,\n      404,\n      endpoint,\n      requestId,\n      details,\n      cause,\n    );\n    this.name = \"NotFoundError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n\nexport class ValidationError extends SplitwiseApiError {\n  constructor(\n    status: 400 | 422,\n    endpoint: string,\n    requestId: string,\n    details?: unknown,\n    cause?: unknown,\n  ) {\n    super(\"Validation failed\", status, endpoint, requestId, details, cause);\n    this.name = \"ValidationError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n\nexport class ConflictError extends SplitwiseApiError {\n  constructor(\n    endpoint: string,\n    requestId: string,\n    details?: unknown,\n    cause?: unknown,\n  ) {\n    super(\"Conflict\", 409, endpoint, requestId, details, cause);\n    this.name = \"ConflictError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n}\n\nexport class RateLimitError extends SplitwiseApiError {\n  constructor(\n    endpoint: string,\n    requestId: string,\n    public readonly retryAfter: number | undefined,\n    details?: unknown,\n    cause?: unknown,\n  ) {\n    super(\"Rate limit exceeded\", 429, endpoint, requestId, details, cause);\n    this.name = \"RateLimitError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n\n  override get retryable(): boolean {\n    return true;\n  }\n}\n\nexport class NetworkError extends SplitwiseError {\n  constructor(message: string, cause?: unknown) {\n    super(message, cause);\n    this.name = \"NetworkError\";\n    Object.setPrototypeOf(this, new.target.prototype);\n  }\n\n  get retryable(): boolean {\n    return true;\n  }\n}\n\n/**\n * Parse a Retry-After header value into seconds.\n * Supports both numeric seconds and HTTP-Date format (RFC 9110 §10.2.3).\n */\nexport function parseRetryAfter(\n  header: string | null | undefined,\n): number | undefined {\n  if (!header) return undefined;\n\n  // Try numeric seconds first\n  const seconds = Number(header);\n  if (!isNaN(seconds) && seconds >= 0) {\n    return seconds;\n  }\n\n  // Try HTTP-Date\n  const date = new Date(header);\n  if (!isNaN(date.getTime())) {\n    const diffMs = date.getTime() - Date.now();\n    return Math.max(0, Math.ceil(diffMs / 1000));\n  }\n\n  return undefined;\n}\n\n/**\n * Parse an HTTP response into the appropriate error class.\n */\nexport function parseHttpError(\n  status: number,\n  endpoint: string,\n  requestId: string,\n  body: unknown,\n  retryAfterHeader?: string | null,\n): SplitwiseApiError {\n  switch (status) {\n    case 401:\n      return new AuthenticationError(endpoint, requestId, body);\n    case 403:\n      return new AuthorizationError(endpoint, requestId, body);\n    case 404:\n      return new NotFoundError(endpoint, requestId, body);\n    case 400:\n    case 422:\n      return new ValidationError(status, endpoint, requestId, body);\n    case 409:\n      return new ConflictError(endpoint, requestId, body);\n    case 429: {\n      const retryAfter = parseRetryAfter(retryAfterHeader);\n      return new RateLimitError(endpoint, requestId, retryAfter, body);\n    }\n    default:\n      return new SplitwiseApiError(\n        `API request failed with status ${status}`,\n        status,\n        endpoint,\n        requestId,\n        body,\n      );\n  }\n}\n","/**\n * Authentication module – access token injection only.\n *\n * The SDK does NOT implement OAuth flows. Token acquisition, rotation,\n * and refresh are the responsibility of the SDK consumer. The SDK only\n * sets the `Authorization: Bearer <token>` header.\n */\n\nimport { AuthenticationError } from \"./errors.js\";\n\nexport type TokenProvider = string | (() => string | Promise<string>);\n\n/**\n * Resolve the access token from a static string or a provider function.\n */\nexport async function resolveToken(provider: TokenProvider): Promise<string> {\n  const token = typeof provider === \"function\" ? await provider() : provider;\n  if (!token) {\n    throw new AuthenticationError(\n      \"/\",\n      \"N/A\",\n      \"Access token is empty or undefined\",\n    );\n  }\n  return token;\n}\n\n/**\n * Build the `Authorization` header value.\n */\nexport function bearerHeader(token: string): string {\n  return `Bearer ${token}`;\n}\n","/**\n * Interceptors for the HTTP client.\n *\n * Provides request/response interceptor infrastructure that:\n *   - Injects the Bearer token header\n *   - Generates and propagates requestId\n *   - Measures request duration\n *   - Logs request lifecycle events\n *   - Parses errors through the error hierarchy\n *   - Invokes retry logic for retryable failures\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { computeDelay, shouldRetry, type RetryConfig } from \"../utils/retry.js\";\nimport { bearerHeader, resolveToken, type TokenProvider } from \"./auth.js\";\nimport { NetworkError, parseHttpError, SplitwiseApiError } from \"./errors.js\";\nimport type { Logger } from \"./logger.js\";\n\nexport interface InterceptorContext {\n  tokenProvider: TokenProvider;\n  logger: Logger;\n  retry: RetryConfig;\n  /** Pre-resolved token to avoid redundant resolution (e.g. for cache-key consistency). */\n  resolvedToken?: string;\n}\n\n/**\n * Execute an HTTP request with auth injection, structured logging,\n * error parsing, and retry logic.\n */\nexport async function executeWithInterceptors<T>(\n  ctx: InterceptorContext,\n  method: string,\n  endpoint: string,\n  performRequest: (headers: Record<string, string>) => Promise<Response>,\n): Promise<T> {\n  const requestId = randomUUID();\n  const { logger, retry } = ctx;\n\n  let lastError: SplitwiseApiError | NetworkError | undefined;\n\n  for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {\n    const startTime = performance.now();\n\n    try {\n      const token =\n        ctx.resolvedToken ?? (await resolveToken(ctx.tokenProvider));\n      const headers: Record<string, string> = {\n        Authorization: bearerHeader(token),\n        \"Content-Type\": \"application/json\",\n      };\n\n      logger.log({\n        level: \"debug\",\n        message: \"request started\",\n        requestId,\n        method,\n        endpoint,\n        retryCount: attempt,\n      });\n\n      const response = await performRequest(headers);\n      const durationMs = Math.round(performance.now() - startTime);\n\n      if (response.ok) {\n        logger.log({\n          level: \"info\",\n          message: \"request succeeded\",\n          requestId,\n          method,\n          endpoint,\n          status: response.status,\n          durationMs,\n          retryCount: attempt,\n        });\n\n        // 204 No Content or empty body → return undefined\n        if (\n          response.status === 204 ||\n          response.headers.get(\"content-length\") === \"0\"\n        ) {\n          return undefined as T;\n        }\n\n        // Parse JSON when Content-Type indicates it\n        const contentType = response.headers.get(\"content-type\") ?? \"\";\n        if (contentType.includes(\"application/json\")) {\n          return (await response.json()) as T;\n        }\n\n        // Fallback: try JSON, fall back to text\n        const text = await response.text();\n        if (!text) return undefined as T;\n\n        try {\n          return JSON.parse(text) as T;\n        } catch {\n          return text as T;\n        }\n      }\n\n      // Non-OK response → parse into typed error\n      let body: unknown;\n      try {\n        body = await response.json();\n      } catch {\n        body = await response.text().catch(() => undefined);\n      }\n\n      const error = parseHttpError(\n        response.status,\n        endpoint,\n        requestId,\n        body,\n        response.headers.get(\"Retry-After\"),\n      );\n\n      logger.log({\n        level: \"error\",\n        message: \"request failed\",\n        requestId,\n        method,\n        endpoint,\n        status: response.status,\n        durationMs,\n        retryCount: attempt,\n        error: error.name,\n      });\n\n      if (shouldRetry(error, attempt, retry)) {\n        lastError = error;\n        const delay = computeDelay(error, attempt, retry);\n        await sleep(delay);\n        continue;\n      }\n\n      throw error;\n    } catch (err) {\n      const durationMs = Math.round(performance.now() - startTime);\n\n      // Already a SplitwiseApiError re-thrown from above\n      if (err instanceof SplitwiseApiError) {\n        throw err;\n      }\n\n      // Network / fetch level error\n      const networkError = new NetworkError(\n        (err as Error).message ?? \"Network request failed\",\n        err,\n      );\n\n      logger.log({\n        level: \"error\",\n        message: \"request failed\",\n        requestId,\n        method,\n        endpoint,\n        durationMs,\n        retryCount: attempt,\n        error: networkError.name,\n      });\n\n      if (shouldRetry(networkError, attempt, retry)) {\n        lastError = networkError;\n        const delay = computeDelay(networkError, attempt, retry);\n        await sleep(delay);\n        continue;\n      }\n\n      throw networkError;\n    }\n  }\n\n  // If we exhausted retries, throw the last error\n  throw lastError!;\n}\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Structured logger for the Splitwise SDK.\n *\n * Every HTTP request logs:\n *   - request started\n *   - request succeeded / request failed\n *\n * Standard log fields: requestId, method, endpoint, status, durationMs, retryCount.\n */\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogEntry {\n  level: LogLevel;\n  message: string;\n  requestId?: string;\n  method?: string;\n  endpoint?: string;\n  status?: number;\n  durationMs?: number;\n  retryCount?: number;\n  error?: string;\n  [key: string]: unknown;\n}\n\nexport interface Logger {\n  log(entry: LogEntry): void;\n}\n\nconst LOG_LEVEL_ORDER: Record<LogLevel, number> = {\n  debug: 0,\n  info: 1,\n  warn: 2,\n  error: 3,\n};\n\n/**\n * Default lightweight logger that writes JSON lines to stdout/stderr.\n */\nexport class DefaultLogger implements Logger {\n  constructor(private readonly minLevel: LogLevel = \"info\") {}\n\n  log(entry: LogEntry): void {\n    if (LOG_LEVEL_ORDER[entry.level] < LOG_LEVEL_ORDER[this.minLevel]) return;\n\n    const line = JSON.stringify(entry);\n    if (entry.level === \"error\") {\n      process.stderr.write(line + \"\\n\");\n    } else {\n      process.stdout.write(line + \"\\n\");\n    }\n  }\n}\n\n/**\n * Silent logger – discards all output. Useful for tests.\n */\nexport class SilentLogger implements Logger {\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  log(_entry: LogEntry): void {\n    // intentionally empty\n  }\n}\n\n/**\n * Adapter that wraps a simple `(message: string) => void` callback\n * into the structured Logger interface.\n */\nexport class CallbackLogger implements Logger {\n  constructor(private readonly callback: (message: string) => void) {}\n\n  log(entry: LogEntry): void {\n    this.callback(JSON.stringify(entry));\n  }\n}\n","/**\n * Central HTTP client for the Splitwise SDK.\n *\n * Wires together: auth, interceptors, retry, logging, caching.\n * Repositories use this client for all HTTP communication.\n */\n\nimport {\n  DEFAULT_CACHE_CONFIG,\n  RequestCache,\n  type CacheConfig,\n} from \"../utils/cache.js\";\nimport type { RetryConfig } from \"../utils/retry.js\";\nimport { DEFAULT_RETRY_CONFIG } from \"../utils/retry.js\";\nimport type { TokenProvider } from \"./auth.js\";\nimport { resolveToken } from \"./auth.js\";\nimport {\n  executeWithInterceptors,\n  type InterceptorContext,\n} from \"./interceptors.js\";\nimport type { Logger } from \"./logger.js\";\nimport { DefaultLogger } from \"./logger.js\";\n\nconst DEFAULT_BASE_URL = \"https://secure.splitwise.com/api/v3.0\";\n\nexport interface HttpClientConfig {\n  /** Access token or async provider function. Required. */\n  accessToken: TokenProvider;\n  /** Base URL for the Splitwise API. */\n  baseUrl?: string;\n  /** Logger instance. */\n  logger?: Logger;\n  /** Retry configuration. */\n  retry?: Partial<RetryConfig>;\n  /** Cache configuration. */\n  cache?: Partial<CacheConfig>;\n}\n\nexport class HttpClient {\n  private readonly baseUrl: string;\n  private readonly logger: Logger;\n  private readonly retryConfig: RetryConfig;\n  private readonly cache: RequestCache;\n  private readonly tokenProvider: TokenProvider;\n\n  constructor(config: HttpClientConfig) {\n    this.tokenProvider = config.accessToken;\n    this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n    this.logger = config.logger ?? new DefaultLogger();\n    this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config.retry };\n    this.cache = new RequestCache({ ...DEFAULT_CACHE_CONFIG, ...config.cache });\n  }\n\n  private get interceptorContext(): InterceptorContext {\n    return {\n      tokenProvider: this.tokenProvider,\n      logger: this.logger,\n      retry: this.retryConfig,\n    };\n  }\n\n  /**\n   * Perform a GET request. Results may be served from cache or deduplicated.\n   */\n  async get<T>(endpoint: string, params?: Record<string, unknown>): Promise<T> {\n    const token = await resolveToken(this.tokenProvider);\n    const fingerprint = RequestCache.tokenFingerprint(token);\n    const cacheKey = this.cache.buildKey(endpoint, params, fingerprint);\n\n    // Check cache\n    const cached = this.cache.get<T>(cacheKey);\n    if (cached !== undefined) {\n      this.logger.log({\n        level: \"debug\",\n        message: \"cache hit\",\n        endpoint,\n        requestId: \"cached\",\n      });\n      return cached;\n    }\n\n    // Dedup + fetch\n    return this.cache.dedup(cacheKey, async () => {\n      const url = this.buildUrl(endpoint, params);\n      const result = await executeWithInterceptors<T>(\n        { ...this.interceptorContext, resolvedToken: token },\n        \"GET\",\n        endpoint,\n        (headers) => fetch(url, { method: \"GET\", headers }),\n      );\n      this.cache.set(cacheKey, result, endpoint);\n      return result;\n    });\n  }\n\n  /**\n   * Perform a POST request. Invalidates related caches.\n   */\n  async post<T>(\n    endpoint: string,\n    body?: unknown,\n    invalidatePrefix?: string | ReadonlyArray<string>,\n  ): Promise<T> {\n    const result = await executeWithInterceptors<T>(\n      this.interceptorContext,\n      \"POST\",\n      endpoint,\n      (headers) =>\n        fetch(this.buildUrl(endpoint), {\n          method: \"POST\",\n          headers,\n          body: body ? JSON.stringify(body) : undefined,\n        }),\n    );\n\n    // Invalidate related cached GET results\n    if (invalidatePrefix) {\n      const prefixes = Array.isArray(invalidatePrefix)\n        ? invalidatePrefix\n        : [invalidatePrefix];\n      for (const prefix of prefixes) {\n        this.cache.invalidate(prefix);\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Clear the request cache.\n   */\n  clearCache(): void {\n    this.cache.clear();\n  }\n\n  /**\n   * Dispose the client: stop background timers and clear cache.\n   */\n  dispose(): void {\n    this.cache.dispose();\n  }\n\n  private buildUrl(endpoint: string, params?: Record<string, unknown>): string {\n    let url = `${this.baseUrl}${endpoint}`;\n    if (params && Object.keys(params).length > 0) {\n      const qs = new URLSearchParams();\n      for (const [key, value] of Object.entries(params)) {\n        if (value !== undefined && value !== null) {\n          qs.append(key, String(value));\n        }\n      }\n      url += `?${qs.toString()}`;\n    }\n    return url;\n  }\n}\n","/**\n * Base repository providing common HTTP operations.\n * All resource repositories extend this class.\n */\n\nimport type { HttpClient } from \"../core/http-client.js\";\n\nexport abstract class BaseRepository {\n  constructor(protected readonly http: HttpClient) {}\n}\n","/**\n * Categories repository – thin passthrough with long-lived cache.\n */\n\nimport type { GetGetCategoriesResponse } from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class CategoriesRepository extends BaseRepository {\n  /**\n   * List expense categories.\n   * Results are cached for 24h by default.\n   */\n  async getCategories(): Promise<GetGetCategoriesResponse> {\n    return this.http.get<GetGetCategoriesResponse>(\"/get_categories\");\n  }\n}\n","/**\n * Comments repository – wraps comment-related API endpoints.\n */\n\nimport type {\n  GetGetCommentsResponse,\n  PostCreateCommentData,\n  PostCreateCommentResponse,\n  PostDeleteCommentByIdResponse,\n} from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class CommentsRepository extends BaseRepository {\n  /**\n   * List comments on an expense.\n   */\n  async getComments(expenseId: number): Promise<GetGetCommentsResponse> {\n    return this.http.get<GetGetCommentsResponse>(\"/get_comments\", {\n      expense_id: expenseId,\n    });\n  }\n\n  /**\n   * Create a comment on an expense.\n   */\n  async createComment(\n    body: PostCreateCommentData[\"body\"],\n  ): Promise<PostCreateCommentResponse> {\n    return this.http.post<PostCreateCommentResponse>(\n      \"/create_comment\",\n      body,\n      \"/get_comments\",\n    );\n  }\n\n  /**\n   * Delete a comment.\n   */\n  async deleteComment(id: number): Promise<PostDeleteCommentByIdResponse> {\n    return this.http.post<PostDeleteCommentByIdResponse>(\n      `/delete_comment/${id}`,\n      undefined,\n      \"/get_comments\",\n    );\n  }\n}\n","/**\n * Currencies repository – thin passthrough with long-lived cache.\n */\n\nimport type { GetGetCurrenciesResponse } from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class CurrenciesRepository extends BaseRepository {\n  /**\n   * List supported currencies.\n   * Results are cached for 24h by default.\n   */\n  async getCurrencies(): Promise<GetGetCurrenciesResponse> {\n    return this.http.get<GetGetCurrenciesResponse>(\"/get_currencies\");\n  }\n}\n","/**\n * Expenses repository – wraps expense-related API endpoints.\n */\n\nimport type {\n  GetGetExpenseByIdResponse,\n  GetGetExpensesData,\n  GetGetExpensesResponse,\n  PostCreateExpenseData,\n  PostCreateExpenseResponse,\n  PostDeleteExpenseByIdResponse,\n  PostUndeleteExpenseByIdResponse,\n  PostUpdateExpenseByIdData,\n  PostUpdateExpenseByIdResponse,\n} from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class ExpensesRepository extends BaseRepository {\n  /**\n   * Get details about an expense.\n   */\n  async getExpense(id: number): Promise<GetGetExpenseByIdResponse> {\n    return this.http.get<GetGetExpenseByIdResponse>(`/get_expense/${id}`);\n  }\n\n  /**\n   * List expenses with optional filters.\n   */\n  async getExpenses(\n    params?: GetGetExpensesData[\"query\"],\n  ): Promise<GetGetExpensesResponse> {\n    return this.http.get<GetGetExpensesResponse>(\n      \"/get_expenses\",\n      params as Record<string, unknown> | undefined,\n    );\n  }\n\n  /**\n   * Create an expense.\n   */\n  async createExpense(\n    body: PostCreateExpenseData[\"body\"],\n  ): Promise<PostCreateExpenseResponse> {\n    return this.http.post<PostCreateExpenseResponse>(\n      \"/create_expense\",\n      body,\n      \"/get_expense\",\n    );\n  }\n\n  /**\n   * Update an expense.\n   */\n  async updateExpense(\n    id: number,\n    body: PostUpdateExpenseByIdData[\"body\"],\n  ): Promise<PostUpdateExpenseByIdResponse> {\n    return this.http.post<PostUpdateExpenseByIdResponse>(\n      `/update_expense/${id}`,\n      body,\n      \"/get_expense\",\n    );\n  }\n\n  /**\n   * Delete an expense.\n   */\n  async deleteExpense(id: number): Promise<PostDeleteExpenseByIdResponse> {\n    return this.http.post<PostDeleteExpenseByIdResponse>(\n      `/delete_expense/${id}`,\n      undefined,\n      \"/get_expense\",\n    );\n  }\n\n  /**\n   * Restore a deleted expense.\n   */\n  async undeleteExpense(id: number): Promise<PostUndeleteExpenseByIdResponse> {\n    return this.http.post<PostUndeleteExpenseByIdResponse>(\n      `/undelete_expense/${id}`,\n      undefined,\n      \"/get_expense\",\n    );\n  }\n}\n","/**\n * Friends repository – wraps friend-related API endpoints.\n */\n\nimport type {\n  GetGetFriendByIdResponse,\n  GetGetFriendsResponse,\n  PostCreateFriendData,\n  PostCreateFriendResponse,\n  PostCreateFriendsData,\n  PostCreateFriendsResponse,\n  PostDeleteFriendByIdResponse,\n} from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class FriendsRepository extends BaseRepository {\n  /**\n   * List current user's friends.\n   */\n  async getFriends(): Promise<GetGetFriendsResponse> {\n    return this.http.get<GetGetFriendsResponse>(\"/get_friends\");\n  }\n\n  /**\n   * Get details about a friend.\n   */\n  async getFriend(id: number): Promise<GetGetFriendByIdResponse> {\n    return this.http.get<GetGetFriendByIdResponse>(`/get_friend/${id}`);\n  }\n\n  /**\n   * Add a friend.\n   */\n  async createFriend(\n    body: PostCreateFriendData[\"body\"],\n  ): Promise<PostCreateFriendResponse> {\n    return this.http.post<PostCreateFriendResponse>(\n      \"/create_friend\",\n      body,\n      \"/get_friend\",\n    );\n  }\n\n  /**\n   * Add multiple friends at once.\n   */\n  async createFriends(\n    body: PostCreateFriendsData[\"body\"],\n  ): Promise<PostCreateFriendsResponse> {\n    return this.http.post<PostCreateFriendsResponse>(\n      \"/create_friends\",\n      body,\n      \"/get_friend\",\n    );\n  }\n\n  /**\n   * Delete a friend.\n   */\n  async deleteFriend(id: number): Promise<PostDeleteFriendByIdResponse> {\n    return this.http.post<PostDeleteFriendByIdResponse>(\n      `/delete_friend/${id}`,\n      undefined,\n      \"/get_friend\",\n    );\n  }\n}\n","/**\n * Groups repository – wraps group-related API endpoints.\n */\n\nimport type {\n  GetGetGroupByIdResponse,\n  GetGetGroupsResponse,\n  PostAddUserToGroupData,\n  PostAddUserToGroupResponse,\n  PostCreateGroupData,\n  PostCreateGroupResponse,\n  PostDeleteGroupByIdResponse,\n  PostRemoveUserFromGroupData,\n  PostRemoveUserFromGroupResponse,\n  PostUndeleteGroupByIdResponse,\n} from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class GroupsRepository extends BaseRepository {\n  /**\n   * List current user's groups.\n   */\n  async getGroups(): Promise<GetGetGroupsResponse> {\n    return this.http.get<GetGetGroupsResponse>(\"/get_groups\");\n  }\n\n  /**\n   * Get details about a group.\n   */\n  async getGroup(id: number): Promise<GetGetGroupByIdResponse> {\n    return this.http.get<GetGetGroupByIdResponse>(`/get_group/${id}`);\n  }\n\n  /**\n   * Create a group.\n   */\n  async createGroup(\n    body: PostCreateGroupData[\"body\"],\n  ): Promise<PostCreateGroupResponse> {\n    return this.http.post<PostCreateGroupResponse>(\n      \"/create_group\",\n      body,\n      \"/get_group\",\n    );\n  }\n\n  /**\n   * Delete a group.\n   */\n  async deleteGroup(id: number): Promise<PostDeleteGroupByIdResponse> {\n    return this.http.post<PostDeleteGroupByIdResponse>(\n      `/delete_group/${id}`,\n      undefined,\n      \"/get_group\",\n    );\n  }\n\n  /**\n   * Restore a deleted group.\n   */\n  async undeleteGroup(id: number): Promise<PostUndeleteGroupByIdResponse> {\n    return this.http.post<PostUndeleteGroupByIdResponse>(\n      `/undelete_group/${id}`,\n      undefined,\n      \"/get_group\",\n    );\n  }\n\n  /**\n   * Add a user to a group.\n   */\n  async addUserToGroup(\n    body: PostAddUserToGroupData[\"body\"],\n  ): Promise<PostAddUserToGroupResponse> {\n    return this.http.post<PostAddUserToGroupResponse>(\n      \"/add_user_to_group\",\n      body,\n      \"/get_group\",\n    );\n  }\n\n  /**\n   * Remove a user from a group.\n   */\n  async removeUserFromGroup(\n    body: PostRemoveUserFromGroupData[\"body\"],\n  ): Promise<PostRemoveUserFromGroupResponse> {\n    return this.http.post<PostRemoveUserFromGroupResponse>(\n      \"/remove_user_from_group\",\n      body,\n      \"/get_group\",\n    );\n  }\n}\n","/**\n * Notifications repository – wraps notification-related API endpoints.\n */\n\nimport type {\n  GetGetNotificationsData,\n  GetGetNotificationsResponse,\n} from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class NotificationsRepository extends BaseRepository {\n  /**\n   * List notifications.\n   */\n  async getNotifications(\n    params?: GetGetNotificationsData[\"query\"],\n  ): Promise<GetGetNotificationsResponse> {\n    return this.http.get<GetGetNotificationsResponse>(\n      \"/get_notifications\",\n      params as Record<string, unknown> | undefined,\n    );\n  }\n}\n","/**\n * Users repository – thin passthrough to HTTP client.\n */\n\nimport type {\n  GetGetCurrentUserResponse,\n  GetGetUserByIdResponse,\n  PostUpdateUserByIdData,\n  PostUpdateUserByIdResponse,\n} from \"../generated/types.gen.js\";\nimport { BaseRepository } from \"./base.repository.js\";\n\nexport class UsersRepository extends BaseRepository {\n  /**\n   * Get information about the current user.\n   */\n  async getCurrentUser(): Promise<GetGetCurrentUserResponse> {\n    return this.http.get<GetGetCurrentUserResponse>(\"/get_current_user\");\n  }\n\n  /**\n   * Get information about another user.\n   */\n  async getUser(id: number): Promise<GetGetUserByIdResponse> {\n    return this.http.get<GetGetUserByIdResponse>(`/get_user/${id}`);\n  }\n\n  /**\n   * Update a user.\n   */\n  async updateUser(\n    id: number,\n    body: PostUpdateUserByIdData[\"body\"],\n  ): Promise<PostUpdateUserByIdResponse> {\n    return this.http.post<PostUpdateUserByIdResponse>(\n      `/update_user/${id}`,\n      body,\n      [\"/get_user\", \"/get_current_user\"],\n    );\n  }\n}\n"],"mappings":"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","names":["import_node_crypto"]}