{"version":3,"sources":["../src/errors.ts","../src/config.ts","../src/fetcher.ts","../src/cache.ts","../src/loaders.ts","../src/utils.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Error classes for @countrystatecity/countries-browser\n */\n\nexport class NetworkError extends Error {\n  public readonly url: string;\n  public readonly statusCode?: number;\n\n  /**\n   * Creates a NetworkError for failed HTTP requests.\n   * @param message - Human-readable error description\n   * @param url - The URL that caused the failure\n   * @param statusCode - Optional HTTP status code\n   */\n  constructor(message: string, url: string, statusCode?: number) {\n    super(message);\n    this.name = 'NetworkError';\n    this.url = url;\n    this.statusCode = statusCode;\n  }\n}\n\nexport class TimeoutError extends Error {\n  public readonly timeout: number;\n\n  /**\n   * Creates a TimeoutError for requests that exceeded the time limit.\n   * @param message - Human-readable error description\n   * @param timeout - The timeout duration in milliseconds\n   */\n  constructor(message: string, timeout: number) {\n    super(message);\n    this.name = 'TimeoutError';\n    this.timeout = timeout;\n  }\n}\n","/**\n * Configuration management for @countrystatecity/countries-browser\n */\n\nimport type { ConfigOptions } from './types';\n\ndeclare const __VERSION__: string;\n\ninterface ResolvedConfig {\n  baseURL: string;\n  timeout: number;\n  headers: Record<string, string>;\n  cacheSize: number;\n}\n\nconst DEFAULT_CONFIG: ResolvedConfig = {\n  baseURL: `https://cdn.jsdelivr.net/npm/@countrystatecity/countries-browser@${__VERSION__}/dist`,\n  timeout: 5000,\n  headers: {},\n  cacheSize: 50,\n};\n\nlet currentConfig: ResolvedConfig = { ...DEFAULT_CONFIG };\n\n/**\n * Get the current resolved configuration\n */\nexport function getConfig(): ResolvedConfig {\n  return currentConfig;\n}\n\n/**\n * Override default configuration options\n * @param options - Partial configuration to merge with defaults\n */\nexport function configure(options: ConfigOptions): void {\n  currentConfig = { ...currentConfig, ...options } as ResolvedConfig;\n}\n\n/**\n * Reset configuration to defaults\n */\nexport function resetConfiguration(): void {\n  currentConfig = { ...DEFAULT_CONFIG };\n}\n","/**\n * Fetch wrapper for @countrystatecity/countries-browser\n */\n\nimport { getConfig } from './config';\nimport { NetworkError, TimeoutError } from './errors';\n\n/**\n * Fetch a JSON resource from the configured CDN\n * @param path - Path relative to baseURL (e.g., '/data/countries.json')\n * @returns Parsed JSON data\n * @throws NetworkError on non-2xx response\n */\nexport async function fetchJSON<T>(path: string): Promise<T> {\n  const config = getConfig();\n  const url = `${config.baseURL}${path}`;\n\n  let response: Response;\n  try {\n    response = await fetch(url, {\n      signal: AbortSignal.timeout(config.timeout),\n      headers: {\n        'Accept': 'application/json',\n        ...config.headers,\n      },\n    });\n  } catch (error) {\n    if (error instanceof DOMException && error.name === 'TimeoutError') {\n      throw new TimeoutError(\n        `Request timed out after ${config.timeout}ms: ${path}`,\n        config.timeout,\n      );\n    }\n    throw error;\n  }\n\n  if (!response.ok) {\n    throw new NetworkError(\n      `Failed to load ${path}: ${response.statusText}`,\n      url,\n      response.status,\n    );\n  }\n\n  return response.json() as Promise<T>;\n}\n","/**\n * LRU (Least Recently Used) cache for @countrystatecity/countries-browser\n * Uses Map iteration order (insertion order) for O(1) eviction\n */\n\nexport class LRUCache<K, V> {\n  private cache = new Map<K, V>();\n  private maxSize: number;\n\n  /**\n   * Create a new LRU cache with the given maximum number of entries.\n   * @param maxSize Maximum number of entries before oldest is evicted\n   */\n  constructor(maxSize: number) {\n    this.maxSize = maxSize;\n  }\n\n  /**\n   * Get a value from cache, marking it as most recently used.\n   * Returns undefined on cache miss.\n   */\n  get(key: K): V | undefined {\n    const value = this.cache.get(key);\n    if (value === undefined) return undefined;\n    this.cache.delete(key);\n    this.cache.set(key, value);\n    return value;\n  }\n\n  /**\n   * Store a value in cache, evicting the oldest entry if at capacity.\n   * If the key already exists, its value is updated and it becomes most recent.\n   */\n  set(key: K, value: V): void {\n    this.cache.delete(key);\n    this.cache.set(key, value);\n    if (this.cache.size > this.maxSize) {\n      const oldestKey = this.cache.keys().next().value!;\n      this.cache.delete(oldestKey);\n    }\n  }\n\n  /**\n   * Remove all entries from cache.\n   */\n  clear(): void {\n    this.cache.clear();\n  }\n}\n","/**\n * Data loaders for @countrystatecity/countries-browser\n * Uses fetch API to load JSON from jsDelivr CDN with LRU caching\n */\n\nimport type { ICountry, ICountryMeta, IState, ICity, IRegion, ISubregion } from './types';\nimport { getConfig } from './config';\nimport { fetchJSON } from './fetcher';\nimport { LRUCache } from './cache';\n\nlet cache: LRUCache<string, unknown> | null = null;\n\nfunction getCache(): LRUCache<string, unknown> {\n  if (!cache) {\n    cache = new LRUCache<string, unknown>(getConfig().cacheSize);\n  }\n  return cache;\n}\n\n/**\n * Clear the cache (forces re-initialization on next use, picking up any config changes)\n */\nexport function clearCache(): void {\n  cache = null;\n}\n\n/**\n * Load JSON with caching\n */\nasync function loadCached<T>(key: string): Promise<T> {\n  const c = getCache();\n  const cached = c.get(key);\n  if (cached !== undefined) return cached as T;\n  const data = await fetchJSON<T>(`/data/${key}`);\n  c.set(key, data);\n  return data;\n}\n\n/**\n * Get lightweight list of all countries\n * @returns Array of countries (basic info only)\n */\nexport async function getCountries(): Promise<ICountry[]> {\n  return loadCached<ICountry[]>('countries.json');\n}\n\n/**\n * Get list of all regions (continents)\n * @returns Array of regions\n */\nexport async function getRegions(): Promise<IRegion[]> {\n  return loadCached<IRegion[]>('regions.json');\n}\n\n/**\n * Get list of all subregions\n * @returns Array of subregions\n */\nexport async function getSubregions(): Promise<ISubregion[]> {\n  return loadCached<ISubregion[]>('subregions.json');\n}\n\n/**\n * Get full country metadata including timezones and translations\n * @param countryCode - ISO2 country code (e.g., 'US', 'IN')\n * @returns Full country metadata or null if not found\n */\nexport async function getCountryByCode(countryCode: string): Promise<ICountryMeta | null> {\n  if (!countryCode) return null;\n  try {\n    return await loadCached<ICountryMeta>(`country/${countryCode.toUpperCase()}.json`);\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Get all states/provinces for a specific country\n * @param countryCode - ISO2 country code\n * @returns Array of states or empty array if not found\n */\nexport async function getStatesOfCountry(countryCode: string): Promise<IState[]> {\n  if (!countryCode) return [];\n  try {\n    return await loadCached<IState[]>(`states/${countryCode.toUpperCase()}.json`);\n  } catch {\n    return [];\n  }\n}\n\n/**\n * Get specific state by code\n * @param countryCode - ISO2 country code\n * @param stateCode - State code (e.g., 'CA', 'TX')\n * @returns State object or null if not found\n */\nexport async function getStateByCode(\n  countryCode: string,\n  stateCode: string,\n): Promise<IState | null> {\n  const states = await getStatesOfCountry(countryCode);\n  return states.find((s) => s.iso2 === stateCode) || null;\n}\n\n/**\n * Get all cities in a specific state\n * @param countryCode - ISO2 country code\n * @param stateCode - State code\n * @returns Array of cities or empty array if not found\n */\nexport async function getCitiesOfState(\n  countryCode: string,\n  stateCode: string,\n): Promise<ICity[]> {\n  if (!countryCode || !stateCode) return [];\n  try {\n    return await loadCached<ICity[]>(\n      `cities/${countryCode.toUpperCase()}-${stateCode.toUpperCase()}.json`,\n    );\n  } catch {\n    return [];\n  }\n}\n\n/**\n * Get specific city by ID\n * @param countryCode - ISO2 country code\n * @param stateCode - State code\n * @param cityId - City ID\n * @returns City object or null if not found\n */\nexport async function getCityById(\n  countryCode: string,\n  stateCode: string,\n  cityId: number,\n): Promise<ICity | null> {\n  const cities = await getCitiesOfState(countryCode, stateCode);\n  return cities.find((c) => c.id === cityId) || null;\n}\n\n/**\n * Get ALL cities in an entire country\n * WARNING: Loads all state city files\n * @param countryCode - ISO2 country code\n * @returns Array of all cities in country\n */\nexport async function getAllCitiesOfCountry(countryCode: string): Promise<ICity[]> {\n  const states = await getStatesOfCountry(countryCode);\n  const cityArrays = await Promise.all(\n    states.map((state) => getCitiesOfState(countryCode, state.iso2)),\n  );\n  return cityArrays.flat();\n}\n\n/**\n * Get every city globally\n * WARNING: MASSIVE data\n * @returns Array of all cities worldwide\n */\nexport async function getAllCitiesInWorld(): Promise<ICity[]> {\n  const countries = await getCountries();\n  const allCities: ICity[] = [];\n  for (const country of countries) {\n    const cities = await getAllCitiesOfCountry(country.iso2);\n    allCities.push(...cities);\n  }\n  return allCities;\n}\n","/**\n * Utility functions for @countrystatecity/countries-browser\n */\n\nimport type { ICity, ICountry, ISubregion } from './types';\nimport {\n  getCountries,\n  getStatesOfCountry,\n  getCitiesOfState,\n  getCountryByCode,\n  getSubregions,\n} from './loaders';\n\n/**\n * Validate if a country code exists\n * @param countryCode - ISO2 country code to validate\n * @returns True if the country code is valid\n */\nexport async function isValidCountryCode(countryCode: string): Promise<boolean> {\n  const countries = await getCountries();\n  return countries.some((c) => c.iso2 === countryCode);\n}\n\n/**\n * Validate if a state code exists in a country\n * @param countryCode - ISO2 country code\n * @param stateCode - State code to validate\n * @returns True if the state code is valid for the given country\n */\nexport async function isValidStateCode(countryCode: string, stateCode: string): Promise<boolean> {\n  const states = await getStatesOfCountry(countryCode);\n  return states.some((s) => s.iso2 === stateCode);\n}\n\n/**\n * Search cities by name (partial match, case-insensitive)\n * @param countryCode - ISO2 country code\n * @param stateCode - State code\n * @param searchTerm - Partial city name to search for\n * @returns Array of matching cities\n */\nexport async function searchCitiesByName(\n  countryCode: string,\n  stateCode: string,\n  searchTerm: string,\n): Promise<ICity[]> {\n  const cities = await getCitiesOfState(countryCode, stateCode);\n  const lowerTerm = searchTerm.toLowerCase();\n  return cities.filter((city) => city.name.toLowerCase().includes(lowerTerm));\n}\n\n/**\n * Get country name from ISO2 code\n * @param countryCode - ISO2 country code\n * @returns Country name or null if not found\n */\nexport async function getCountryNameByCode(countryCode: string): Promise<string | null> {\n  const countries = await getCountries();\n  const country = countries.find((c) => c.iso2 === countryCode);\n  return country ? country.name : null;\n}\n\n/**\n * Get state name from codes\n * @param countryCode - ISO2 country code\n * @param stateCode - State code\n * @returns State name or null if not found\n */\nexport async function getStateNameByCode(\n  countryCode: string,\n  stateCode: string,\n): Promise<string | null> {\n  const states = await getStatesOfCountry(countryCode);\n  const state = states.find((s) => s.iso2 === stateCode);\n  return state ? state.name : null;\n}\n\n/**\n * Get timezone for a specific city\n * @param countryCode - ISO2 country code\n * @param stateCode - State code\n * @param cityName - Exact city name\n * @returns Timezone string or null if not found\n */\nexport async function getTimezoneForCity(\n  countryCode: string,\n  stateCode: string,\n  cityName: string,\n): Promise<string | null> {\n  const cities = await getCitiesOfState(countryCode, stateCode);\n  const city = cities.find((c) => c.name === cityName);\n  return city ? city.timezone : null;\n}\n\n/**\n * Get all timezone names for a country\n * @param countryCode - ISO2 country code\n * @returns Array of timezone zone names or empty array if not found\n */\nexport async function getCountryTimezones(countryCode: string): Promise<string[]> {\n  const meta = await getCountryByCode(countryCode);\n  if (!meta || !meta.timezones) return [];\n  return meta.timezones.map((tz) => tz.zoneName);\n}\n\n/**\n * Get all subregions belonging to a region\n * @param regionId - Region ID (see getRegions())\n * @returns Array of subregions\n */\nexport async function getSubregionsOfRegion(regionId: number): Promise<ISubregion[]> {\n  const subregions = await getSubregions();\n  return subregions.filter((s) => s.region_id === regionId);\n}\n\n/**\n * Get all countries in a region\n * @param region - Region name (case-insensitive, e.g. 'Europe') or region ID\n * @returns Array of countries\n */\nexport async function getCountriesByRegion(region: string | number): Promise<ICountry[]> {\n  const countries = await getCountries();\n  if (typeof region === 'number') {\n    return countries.filter((c) => c.region_id === region);\n  }\n  const term = region.toLowerCase();\n  return countries.filter((c) => c.region?.toLowerCase() === term);\n}\n\n/**\n * Get all countries in a subregion\n * @param subregion - Subregion name (case-insensitive, e.g. 'South America') or subregion ID\n * @returns Array of countries\n */\nexport async function getCountriesBySubregion(subregion: string | number): Promise<ICountry[]> {\n  const countries = await getCountries();\n  if (typeof subregion === 'number') {\n    return countries.filter((c) => c.subregion_id === subregion);\n  }\n  const term = subregion.toLowerCase();\n  return countries.filter((c) => c.subregion?.toLowerCase() === term);\n}\n"]}