# GeoLite

A lightweight geo data toolkit with countries, states, cities, timezones, currencies, and dialing codes. Works with Prisma and SQLite.

## Features

- 🌍 **Countries**: Get all countries with ISO codes, names, and flag emojis
- 🏛️ **States/Provinces**: Retrieve states/provinces for any country
- 🏙️ **Cities**: Access cities by country and state
- 🕐 **Timezones**: Get timezone information with offsets
- 💰 **Currencies**: Currency data with symbols and decimal places
- 📞 **Dialing Codes**: Phone country codes and formatting examples
- 🗄️ **SQLite Database**: Embedded database with no external dependencies
- ⚡ **Prisma Integration**: Type-safe database queries

## Installation

```bash
npm install geolite@beta
```

## Quick Start

```javascript
import {
  getAllCountries,
  getStatesOfCountry,
  getCitiesOfCountryAndState,
  getAllCurrencies,
  getAllDialingCodes,
  getAllTimezones,
} from "geolite";

// Get all countries
const countries = await getAllCountries();
console.log(countries[0]);
// { code: 'AD', name: 'Andorra', iso3: 'AND', flagEmoji: '🇦🇩' }

// Get states of a country
const usStates = await getStatesOfCountry("US");
console.log(usStates[0]);
// { id: 1, name: 'Alabama', iso2: 'AL', iso3: null }

// Get cities
const californiaCities = await getCitiesOfCountryAndState("US", 5); // California state ID
console.log(californiaCities[0]);
// { id: 1, name: 'Los Angeles' }
```

## API Reference

### Countries

#### `getAllCountries()`

Get all countries with basic information.

```javascript
const countries = await getAllCountries();
// Returns: Array of { code, name, iso3, flagEmoji }
```

#### `getCountryByCode(countryCode)`

Get detailed information about a specific country.

```javascript
const usa = await getCountryByCode("US");
// Returns: { code: 'US', name: 'United States', iso3: 'USA', flagEmoji: '🇺🇸' }
```

### States/Provinces

#### `getStatesOfCountry(countryCode)`

Get all states/provinces for a country.

```javascript
const canadianProvinces = await getStatesOfCountry("CA");
// Returns: Array of { id, name, iso2, iso3 }
```

#### `getStateById(stateId)`

Get detailed information about a specific state.

```javascript
const california = await getStateById(5);
// Returns: { id: 5, name: 'California', iso2: 'CA', iso3: null, country: {...} }
```

### Cities

#### `getCitiesOfCountryAndState(countryCode, stateId?)`

Get cities for a country, optionally filtered by state.

```javascript
// All cities in the US
const usCities = await getCitiesOfCountryAndState("US");

// Cities in California only
const californiaCities = await getCitiesOfCountryAndState("US", 5);
// Returns: Array of { id, name }
```

#### `getCityById(cityId)`

Get detailed information about a specific city.

```javascript
const city = await getCityById(1);
// Returns: { id: 1, name: 'Los Angeles', country: {...}, states: {...} }
```

### Currencies

#### `getAllCurrencies()`

Get all available currencies.

```javascript
const currencies = await getAllCurrencies();
// Returns: Array of { code, name, symbol, decimalPlaces }
console.log(currencies[0]);
// { code: 'USD', name: 'US Dollar', symbol: '$', decimalPlaces: 2 }
```

#### `getCurrencyByCode(currencyCode)`

Get detailed currency information by code.

```javascript
const usd = await getCurrencyByCode("USD");
// Returns: { code: 'USD', name: 'US Dollar', symbol: '$', decimalPlaces: 2, country: {...}, states: [...] }
```

#### `getCurrencyByName(currencyName)`

Get currency information by name.

```javascript
const euro = await getCurrencyByName("Euro");
// Returns: Currency object with related countries and states
```

#### `getCurrencyOfCountry(countryCode)`

Get the primary currency of a country.

```javascript
const currency = await getCurrencyOfCountry("US");
// Returns: { code: 'USD', name: 'US Dollar', symbol: '$', decimalPlaces: 2 }
```

### Dialing Codes

#### `getAllDialingCodes()`

Get all international dialing codes.

```javascript
const dialingCodes = await getAllDialingCodes();
// Returns: Array of { code, root, suffix, example }
console.log(dialingCodes[0]);
// { code: '+1', root: '+1', suffix: null, example: '+1 555 123 4567' }
```

#### `getDialingCodeByCode(dialingCode)`

Get detailed information about a dialing code.

```javascript
const usDialing = await getDialingCodeByCode("+1");
// Returns: { code: '+1', root: '+1', suffix: null, example: '+1 555 123 4567', country: {...}, states: [...] }
```

#### `getDialingCodesOfCountry(countryCode)`

Get all dialing codes for a country.

```javascript
const usCodes = await getDialingCodesOfCountry("US");
// Returns: Array of dialing code objects
```

#### `getDialingCodeOfState(stateId)`

Get the dialing code for a specific state.

```javascript
const stateCode = await getDialingCodeOfState(5); // California
// Returns: Dialing code object or country's primary code as fallback
```

### Timezones

#### `getAllTimezones()`

Get all available timezones.

```javascript
const timezones = await getAllTimezones();
// Returns: Array of { name, offset, offsetMinutes }
console.log(timezones[0]);
// { name: 'America/New_York', offset: '-05:00', offsetMinutes: -300 }
```

#### `getTimezoneByName(name)`

Get detailed timezone information.

```javascript
const timezone = await getTimezoneByName("America/New_York");
// Returns: { name: 'America/New_York', offset: '-05:00', offsetMinutes: -300, country: {...}, states: [...] }
```

#### `getTimezonesOfCountry(countryCode)`

Get all timezones for a country.

```javascript
const usTimezones = await getTimezonesOfCountry("US");
// Returns: Array of timezone objects
```

#### `getTimezonesOfState(stateId)`

Get timezones for a specific state.

```javascript
const californiaTimezones = await getTimezonesOfState(5);
// Returns: Array of timezone objects (falls back to country timezones if none found)
```

#### `getTimezoneOfCity(cityId)`

Get the timezone for a specific city.

```javascript
const cityTimezone = await getTimezoneOfCity(1);
// Returns: Timezone object or null
```

## Usage Examples

### Building a Country/State/City Selector

```javascript
import {
  getAllCountries,
  getStatesOfCountry,
  getCitiesOfCountryAndState,
} from "geolite";

// Populate country dropdown
const countries = await getAllCountries();
const countrySelect = countries.map((country) => ({
  value: country.code,
  label: `${country.flagEmoji} ${country.name}`,
}));

// When user selects a country, populate states
const selectedCountry = "US";
const states = await getStatesOfCountry(selectedCountry);
const stateSelect = states.map((state) => ({
  value: state.id,
  label: state.name,
}));

// When user selects a state, populate cities
const selectedState = 5; // California
const cities = await getCitiesOfCountryAndState(selectedCountry, selectedState);
const citySelect = cities.map((city) => ({
  value: city.id,
  label: city.name,
}));
```

### Phone Number Formatting

```javascript
import { getDialingCodesOfCountry, getDialingCodeByCode } from "geolite";

// Get dialing codes for a country
const usCodes = await getDialingCodesOfCountry("US");
console.log(usCodes[0].example); // "+1 555 123 4567"

// Format phone number with country code
const dialingCode = await getDialingCodeByCode("+1");
const phoneNumber = "5551234567";
const formattedPhone = `${dialingCode.root} ${phoneNumber}`;
console.log(formattedPhone); // "+1 5551234567"
```

### Currency Display

```javascript
import { getCurrencyOfCountry, getCurrencyByCode } from "geolite";

// Display price with country's currency
const currency = await getCurrencyOfCountry("US");
const price = 99.99;
const formattedPrice = `${currency.symbol}${price.toFixed(
  currency.decimalPlaces
)}`;
console.log(formattedPrice); // "$99.99"

// Get currency details
const eur = await getCurrencyByCode("EUR");
console.log(`${eur.name} (${eur.symbol})`); // "Euro (€)"
```

### Timezone Handling

```javascript
import { getTimezonesOfCountry, getTimezoneByName } from "geolite";

// Show all timezones for a country
const usTimezones = await getTimezonesOfCountry("US");
usTimezones.forEach((tz) => {
  console.log(`${tz.name}: UTC${tz.offset}`);
});
// America/New_York: UTC-05:00
// America/Chicago: UTC-06:00
// America/Denver: UTC-07:00
// America/Los_Angeles: UTC-08:00

// Convert time using timezone offset
const timezone = await getTimezoneByName("America/New_York");
const utcTime = new Date();
const localTime = new Date(utcTime.getTime() + timezone.offsetMinutes * 60000);
```

### Complete Location Information

```javascript
import {
  getCountryByCode,
  getStateById,
  getCityById,
  getCurrencyOfCountry,
  getDialingCodesOfCountry,
  getTimezonesOfCountry,
} from "geolite";

async function getLocationDetails(countryCode, stateId, cityId) {
  const [country, state, city, currency, dialingCodes, timezones] =
    await Promise.all([
      getCountryByCode(countryCode),
      getStateById(stateId),
      getCityById(cityId),
      getCurrencyOfCountry(countryCode),
      getDialingCodesOfCountry(countryCode),
      getTimezonesOfCountry(countryCode),
    ]);

  return {
    location: `${city.name}, ${state.name}, ${country.name} ${country.flagEmoji}`,
    currency: `${currency.name} (${currency.symbol})`,
    phone: dialingCodes[0].example,
    timezones: timezones.map((tz) => `${tz.name} (UTC${tz.offset})`),
  };
}

const details = await getLocationDetails("US", 5, 1);
console.log(details);
// {
//   location: "Los Angeles, California, United States 🇺🇸",
//   currency: "US Dollar ($)",
//   phone: "+1 555 123 4567",
//   timezones: ["America/Los_Angeles (UTC-08:00)", ...]
// }
```

## Database Schema

The library uses SQLite with the following main entities:

- **Countries**: ISO codes, names, flag emojis
- **States**: Linked to countries with ISO codes
- **Cities**: Linked to countries and states
- **Currencies**: Codes, names, symbols, decimal places
- **Dialing Codes**: Phone country codes with examples
- **Timezones**: Names, UTC offsets in hours and minutes

## Requirements

- Node.js 14+
- ES Modules support

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Repository

[GitHub Repository](https://github.com/afzal6174/geolite)

## Issues

[Report Issues](https://github.com/afzal6174/geolite/issues)

## Disclaimer

This project is **not affiliated with MaxMind** or its GeoLite2 products in any way.  
All data used in this project is independently collected or derived and does not use or rely on any proprietary database from MaxMind.
