npm package: @razorpay/i18nify-js
Description: _A one-stop solution built in javascript to provide internationalization support._
Author: tarun khanna
Latest version: 1.12.8

# i18nify-JS

_A one-stop solution built in javascript to provide internationalization support._

Hey, dive into this JavaScript toolkit—it's like having a magic kit for your app! 🪄✨ Picture this: modules for phoneNumber, currency, date—they're like enchanted tools that make your app talk fluently in any language, anywhere! It's your ticket to making your app a global citizen, no matter where it goes!

And hey, hang tight—I'll break down each of these enchanting modules in the sections coming up! 🌍📱💸🗓️

## Install

`yarn add @razorpay/i18nify-js`

## Local Setup / Want to Contribute ?

Here's your roadmap to getting this party started:

- First things first, clone this treasure trove of code (repository).
- Once you've done that, make sure all the buddies (dependencies) are in place by hitting `yarn install`
- You are good to go, go ahead find issues and raise your PR to fix those. Happy coding!!
- To create a build run following command: `yarn build`

Go on, code conqueror, the adventure awaits!

## Modules

### Core Module

Welcome to the command center for your i18n experience! This module serves as the control hub, housing the essential functions to manage your i18n settings seamlessly. This module offers a trio of functions to handle all your i18n needs. Whether it's checking the current state, customizing settings, or starting afresh, this module has got you covered in managing your i18n world! 🚀

#### Functions

**setState(newState: Partial `<I18nState>`):** Customize and update your i18n state with ease! Whether you're changing locales or tweaking directions, this function is your ticket to tailor your i18n experience precisely how you want it! 🎨

```
import { setState } from "@razorpay/i18nify-js/core";

// Set a new locale
setState({ locale: 'en-US' });
```

**getState():** Peek into the current i18n state - the active locale, direction, and country settings - at any time, giving you a snapshot of your i18n setup! 📸

```
import { getState } from '@razorpay/i18nify-js/core';

// Get the current state
const currentState = getState();
console.log(currentState);
    /*
    {
        locale: 'en-US',
        direction: '',
        country: '',
      }
    */
```

**resetState():** Made a mess? No worries! Hit the reset button with this function. It's the ultimate undo for your i18n adjustments, whisking your settings back to their pristine defaults. Fresh start, anyone? 🆕

```
import { resetState } from "@razorpay/i18nify-js/core";

// Reset everything!
resetState();
```

### Module 01: Currency

This module's your go-to guru for everything currency/number-related. 🤑 It's all about formatting, validations, and handy tricks to make dealing with money/numbers a breeze. Here are the cool APIs and utilities this Currency Module gives you to play with! 🚀💸

#### convertToMajorUnit(amount, options)

💵🔄 This function is your go-to tool for scaling currency values from lower to major units. Just input the amount in a minor unit (like cents or pence) along with the currency code, and voilà! You get the amount in a major unit (like dollars or pounds). And if you stumble upon an unsupported currency code, it'll promptly let you know by throwing an error.

##### Examples

```javascript
console.log(convertToMajorUnit(10000, { currency: 'USD' })); // Outputs the amount in dollars for 10000 cents (e.g., 100.00)
console.log(convertToMajorUnit(5000, { currency: 'GBP' })); // Converts 5000 pence to pounds (e.g., 50.00)
```

#### convertToMinorUnit(amount, options)

💵🔄 This function is your go-to tool for scaling currency values from higher to minor units. Just input the amount in a major unit (like dollars or pounds) along with the currency code, and voilà! You get the amount in a minor unit (like cents or pence). And if you stumble upon an unsupported currency code, it'll promptly let you know by throwing an error.

##### Examples

```javascript
console.log(convertToMinorUnit(100, { currency: 'USD' })); // Outputs the amount in cents for 10000 dollars (e.g., 10000)
console.log(convertToMinorUnit(50, { currency: 'GBP' })); // Converts 50 pounds to pence (e.g., 5000)
```

#### formatNumber(amount, options)

🎩✨ This little wizard helps you jazz up numerical values in all sorts of fancy ways. And guess what? It uses the Internationalization API (Intl) to sprinkle that magic dust and give you snazzy, locale-specific number formats—especially for currencies! 🌟💸

##### Examples

```javascript
console.log(formatNumber('1000.5', { currency: 'USD' })); // $1,000.50

console.log(
  formatNumber('1500', {
    currency: 'EUR',
    locale: 'fr-FR',
    intlOptions: {
      currencyDisplay: 'code',
    },
  }),
); // 1 500,00 EUR

console.log(
  formatNumber('5000', {
    currency: 'JPY',
    intlOptions: {
      currencyDisplay: 'narrowSymbol',
    },
  }),
); // ¥5,000
```

#### getCurrencyList()

🌍💰 It's your easy-peasy way to snag a whole list of currencies with their symbols and names. Simple, straightforward, and totally handy!

##### Examples

```javascript
console.log(getCurrencyList()); /* {
  AED: {
    symbol: 'د.إ',
    name: 'United Arab Emirates Dirham',
    lowerUnitName: 'Fils',
  },
  ALL: {
    symbol: 'Lek',
    name: 'Albanian Lek',
    lowerUnitName: 'Qindarka',
  },
  AMD: {
    symbol: '֏',
    name: 'Armenian Dram',
    lowerUnitName: 'Luma',
  },
  ARS: {
    symbol: 'ARS',
    name: 'Argentine Peso',
    lowerUnitName: 'Centavo',
  },
  AUD: {
    symbol: 'A$',
    name: 'Australian Dollar',
    lowerUnitName: 'Cent',
  },
  ... rest of the country
} */
```

#### getCurrencySymbol(currencyCode)

Picture this: it's like having a cool decoder ring for currency codes! 🔍💰 This little guy, grabs the symbol for a currency code from its secret stash.

##### Examples

```javascript
console.log(getCurrencySymbol('USD')); // $

console.log(getCurrencySymbol('UZS')); // so'm

console.log(getCurrencySymbol('OMR')); // ر.ع.
```

#### formatNumberByParts(amount, options)

This slick function breaks down numbers into separate pieces using Intl.NumberFormat. It's like taking apart a puzzle 🧩 — currency symbol here, integers there, decimals in their place—with a fail-proof system to handle any formatting hiccups 🥴 along the way. Smooth operator, right?

##### Examples

```javascript
console.log(
  formatNumberByParts(12345.67, {
    currency: 'USD',
    locale: 'en-US',
  }),
); /* {
    "currency": "$",
    "integer": "12,345",
    "decimal": ".",
    "fraction": "67",
    "isPrefixSymbol": true,
    "rawParts": [
        {
            "type": "currency",
            "value": "$"
        },
        {
            "type": "integer",
            "value": "12"
        },
        {
            "type": "group",
            "value": ","
        },
        {
            "type": "integer",
            "value": "345"
        },
        {
            "type": "decimal",
            "value": "."
        },
        {
            "type": "fraction",
            "value": "67"
        }
    ]
} */

console.log(
  formatNumberByParts(12345.67, {
    currency: 'XYZ',
    locale: 'en-US',
  }),
); /* {
    "currency": "XYZ",
    "integer": "12,345",
    "decimal": ".",
    "fraction": "67",
    "isPrefixSymbol": true,
    "rawParts": [
        {
            "type": "currency",
            "value": "XYZ"
        },
        {
            "type": "literal",
            "value": " "
        },
        {
            "type": "integer",
            "value": "12"
        },
        {
            "type": "group",
            "value": ","
        },
        {
            "type": "integer",
            "value": "345"
        },
        {
            "type": "decimal",
            "value": "."
        },
        {
            "type": "fraction",
            "value": "67"
        }
    ]
} */

console.log(
  formatNumberByParts(12345.67, {
    currency: 'EUR',
    locale: 'fr-FR',
  }),
); /* {
    "integer": "12 345",
    "decimal": ",",
    "fraction": "67",
    "currency": "€",
    "isPrefixSymbol": false,
    "rawParts": [
        {
            "type": "integer",
            "value": "12"
        },
        {
            "type": "group",
            "value": " "
        },
        {
            "type": "integer",
            "value": "345"
        },
        {
            "type": "decimal",
            "value": ","
        },
        {
            "type": "fraction",
            "value": "67"
        },
        {
            "type": "literal",
            "value": " "
        },
        {
            "type": "currency",
            "value": "€"
        }
    ]
} */

console.log(
  formatNumberByParts(12345.67, {
    currency: 'JPY',
    locale: 'ja-JP',
  }),
); /* {
    "currency": "￥",
    "integer": "12,346",
    "isPrefixSymbol": true,
    "rawParts": [
        {
            "type": "currency",
            "value": "￥"
        },
        {
            "type": "integer",
            "value": "12"
        },
        {
            "type": "group",
            "value": ","
        },
        {
            "type": "integer",
            "value": "346"
        }
    ]
} */

console.log(
  formatNumberByParts(12345.67, {
    currency: 'OMR',
    locale: 'ar-OM',
  }),
); /* {
    "integer": "١٢٬٣٤٥",
    "decimal": "٫",
    "fraction": "٦٧٠",
    "currency": "ر.ع.",
    "isPrefixSymbol": false,
    "rawParts": [
        {
            "type": "literal",
            "value": " "
        },
        {
            "type": "integer",
            "value": "١٢"
        },
        {
            "type": "group",
            "value": "٬"
        },
        {
            "type": "integer",
            "value": "٣٤٥"
        },
        {
            "type": "decimal",
            "value": "٫"
        },
        {
            "type": "fraction",
            "value": "٦٧٠"
        },
        {
            "type": "literal",
            "value": " "
        },
        {
            "type": "currency",
            "value": "ر.ع."
        },
        {
            "type": "literal",
            "value": " "
        }
    ]
} */
```

### Module 02: Phone Number

This module's your phone's best friend, handling all things phone number-related. 📱 It's the go-to for formatting, checking if those digits are legit, and all those handy phone-related tricks. And guess what? It's got a bunch of cool stuff—APIs and utilities—just waiting for you to dive in and make your phone game strong! 🚀🔢

#### isValidPhoneNumber(phoneNumber, countryCode)

📞 It's like the phone number detective, using fancy patterns to check if a number is the real deal for a specific country code. So, it's pretty simple: if it says true, your number's good to go for that country; if it's false, time to double-check those digits! 🕵️‍♂️🔍

##### Examples

```javascript
// Basic Validation
console.log(isValidPhoneNumber('+14155552671')); // true

// Specifying Country Code for Validation
console.log(isValidPhoneNumber('0501234567', 'AE')); // true

// Auto-Detecting Country Code
console.log(isValidPhoneNumber('+447700900123')); // true

// Handling Invalid Numbers
console.log(isValidPhoneNumber('123456789', 'US')); // false

// Invalid Country Code
console.log(isValidPhoneNumber('+123456789')); // false

// Empty Phone Number
console.log(isValidPhoneNumber('')); // false

// Non-Standard Formatting
console.log(isValidPhoneNumber('(555) 555-5555')); // true
```

#### formatPhoneNumber(phoneNumber, countryCode)

📞 It's like your personal phone number stylist, working its magic to make those digits look all snazzy. You can tell it the country code, or it'll figure it out itself—then presto! It hands you back a phone number looking sharp and dapper in that country's typical style. ✨🌍

##### Examples

```javascript
// Basic Formatting
console.log(formatPhoneNumber('+14155552671')); // '+1 415-555-2671'

// Specifying Country Code for Formatting
console.log(formatPhoneNumber('0501234567', 'AE')); // '050 123 4567'

// Auto-Detecting Country Code for Formatting
console.log(formatPhoneNumber('+447700900123')); // '+44 7700 900123'

// Handling Invalid Numbers for Formatting
console.log(formatPhoneNumber('123456789', 'US')); // '123456789'

// Invalid Country Code for Formatting
console.log(formatPhoneNumber('+123456789')); // '+123456789'

// Empty Phone Number
console.log(formatPhoneNumber('')); // Throws an Error: 'Parameter `phoneNumber` is invalid!'

// Non-Standard Formatting
console.log(formatPhoneNumber('(555) 555-5555')); // '555 555 5555'
```

#### parsePhoneNumber(phoneNumber, country)

🕵️‍♂️📞 This clever function digs deep into a phone number, pulling out all the juicy details: country code, dial code, the number all dolled up, and even the format it follows. What's cool? It hands you back an object filled with all these deets, making it a breeze to access everything about that phone number. It's like having the ultimate phone number cheat sheet! 🌟

##### Examples

```javascript
// Formatting a Phone Number
const phoneNumber = '+1 (555) 123-4567';
const parsedInfo = parsePhoneNumber(phoneNumber);
console.log('Country Code:', parsedInfo.countryCode); // 'US'
console.log('Formatted Number:', parsedInfo.formattedPhoneNumber); // '555-123-4567'
console.log('Dial Code:', parsedInfo.dialCode); // '+1'
console.log('Format Template:', parsedInfo.formatTemplate); // 'xxx-xxx-xxxx'

// Parsing a Phone Number with Specified Country Code
const phoneNumber = '987654321'; // Phone number without country code
const countryCode = 'IN'; // Specifying the country code (India)
const parsedInfo = parsePhoneNumber(phoneNumber, countryCode);
console.log('Country Code:', parsedInfo.countryCode); // 'IN'
console.log('Formatted Number:', parsedInfo.formattedPhoneNumber); // '98-765-4321'
console.log('Dial Code:', parsedInfo.dialCode);
('');
console.log('Format Template:', parsedInfo.formatTemplate);
('xxxx xxxxxx');

// Handling Invalid Phone Numbers
try {
  const invalidPhoneNumber = ''; // Empty phone number
  // This will throw an error since the phone number is empty
  const parsedInfo = parsePhoneNumber(invalidPhoneNumber);
  // If the parsePhoneNumber function succeeds, log the parsed information
  console.log('Country Code:', parsedInfo.countryCode);
  console.log('Formatted Number:', parsedInfo.formattedPhoneNumber);
} catch (error) {
  console.error('Error:', error.message); // 'Parameter `phoneNumber` is invalid!'
}

// Obtaining Format Information for a Country Code
const countryCode = 'JP'; // Country code for Japan
// Get the format information without providing a phone number
const parsedInfo = parsePhoneNumber('', countryCode);
console.log('Country Code:', parsedInfo.countryCode); // 'JP'
console.log('Format Template:', parsedInfo.formatTemplate); // 'xxx-xxxx-xxxx'
```

#### getDialCodes()

🌍🔢 This function is a comprehensive directory of international dial codes, mapped to their respective country codes. Whether you're coding a global application or just need to reference international dialing formats, this function provides a quick and accurate reference, organizing the world's dial codes in a clean, easy-to-use format.

##### Examples

```javascript
console.log(getDialCodes()); /*
    {
      US: '+1',
      RU: '+7',
      KZ: '+7',
      EG: '+20',
      ZA: '+27',
      GR: '+30',
      NL: '+31',
      BE: '+32',
      FR: '+33',
      ES: '+34',
      HU: '+36',
      IT: '+39',
      VA: '+39',
      RO: '+40',
      CH: '+41',
      AT: '+43',
      GB: '+44',
      MM: '+95',
      IR: '+98',
      SS: '+211',
      MA: '+212',
      EH: '+212',
      DZ: '+213',
      TN: '+216',
      LY: '+218',
      GM: '+220',
      SN: '+221',
      // ... rest of the country 
    }
*/
```

#### getDialCodeByCountryCode(countryCode)

📞🗺️ This function is your quick access to finding the dial code for any specific country, utilizing the country's ISO code. Perfect for applications that require validating user input for phone numbers or enhancing UIs with country-specific details. It ensures you get the exact dial code you need, and if the country code doesn't match, it alerts you right away with an error.

##### Examples

```javascript
console.log(getDialCodeByCountryCode('BR')); // Outputs the dial code for Brazil (+55)
console.log(getDialCodeByCountryCode('DE')); // Outputs the dial code for Germany (+49)
```

#### getMaskedPhoneNumber(options)

📞🔒 The getMaskedPhoneNumber function is a versatile tool designed to handle phone number formatting and masking based on the specific requirements of different countries. This function is ideal for applications that require the display of partially hidden phone numbers for security purposes or privacy concerns. It supports a wide range of configurations, including options to mask portions of the phone number, specify the number of digits to mask, and choose whether to mask digits from the beginning or end of the number.

##### Examples

```javascript
// Masking a U.S. phone number completely
console.log(
  getMaskedPhoneNumber({
    countryCode: 'US',
    phoneNumber: '2025550125',
    withDialCode: true,
  }),
);
// Output: +1 xxx-xxx-xxxx

// Partially masking an Indian phone number, hiding the last 6 digits with maskingStyle: suffix
console.log(
  getMaskedPhoneNumber({
    countryCode: 'IN',
    phoneNumber: '9876543210',
    maskingOptions: {
      maskingStyle: 'suffix',
      maskedDigitsCount: 6,
      maskingChar: '*',
    },
    withDialCode: true,
  }),
);
// Output: +91 9876 ******

// Partially masking an Indian phone number, hiding the first 6 digits with maskingStyle: prefix
console.log(
  getMaskedPhoneNumber({
    countryCode: 'IN',
    phoneNumber: '9876543210',
    maskingOptions: {
      maskingStyle: 'prefix',
      maskedDigitsCount: 6,
      maskingChar: '*',
    },
    withDialCode: true,
  }),
);
// Output: +91 **** 543210

// Partially masking an Indian phone number, hiding the first 6 digits with maskingStyle: full
console.log(
  getMaskedPhoneNumber({
    countryCode: 'IN',
    phoneNumber: '9876543210',
    maskingOptions: {
      maskingStyle: 'full',
      maskingChar: '*',
    },
    withDialCode: true,
  }),
);
// Output: +91 **** ******

// Partially masking an Indian phone number, hiding the first 6 digits with maskingStyle: alternate
console.log(
  getMaskedPhoneNumber({
    countryCode: 'IN',
    phoneNumber: '9876543210',
    maskingOptions: {
      maskingStyle: 'alternate',
      maskingChar: '*',
    },
    withDialCode: true,
  }),
);
// Output: +91 9*7* 5*3*1*

// Formatting and completely masking a phone number for Brazil without specifying a phone number
console.log(
  getMaskedPhoneNumber({
    countryCode: 'BR',
  }),
);
// Output: xx xxxx-xxxx
```

### Module 03: Geo Module 🌍

Dive into the digital atlas with the Geo Module 🌍, your ultimate toolkit for accessing geo contextual data from around the globe 🌐. Whether you're infusing your projects with national pride 🎉 or exploring different countries 🤔, this module is like a magic carpet ride 🧞‍♂️. With a range of functions at your disposal ✨, incorporating global data 🚩 into your app has never been easier. Let's explore these global gems 🌟:

The Geo Module is designed to enrich your applications by providing easy access to high-quality flag images and emojis, country information, states, cities, and zip codes for every country.

> **Note:** Below APIs in the Geo module currently support a limited set of countries.
>
> 1. getStates
> 2. getCities
> 3. getZipcodes
> 4. getZipcodesByCity
>
> These countries are 'IN', 'MY', 'SG' and 'US'.

#### getCityByZipcode

The getCityByZipcode API allows you to retrieve the name of a city based on a given zipcode. This function is particularly useful for applications that need to map zipcodes to city names, providing a seamless way to enhance user experience with localized data.

##### Parameters:

- `zipcode` (string): The zipcode for which you want to find the city name.
- `countryCode` (optional, string): The country code to narrow down the search. If not provided, the function searches across all supported countries.

##### Returns:

- A promise that resolves to the city name if found, or rejects with an error if the zipcode is invalid or not found.

##### Example:

```javascript
import { getCityByZipcode } from 'i18nify-js';

// Example with country code
getCityByZipcode('90001', 'US')
  .then((cityName) => console.log(cityName))
  .catch((error) => console.error(error));

// Example without country code
getCityByZipcode('90001')
  .then((cityName) => console.log(cityName))
  .catch((error) => console.error(error));
```

#### getAllCountries

Looking for a global adventure? The getAllCountries API is your passport to a world of fun facts! Get ready to explore every country on the map, complete with cool details like names, languages, currencies, dial codes, and even their snazzy flags.

##### Examples

```javascript
// Fetching the list of all countries
const res = await getAllCountries();
console.log(res);
/*
    "AF": {
      "country_name": "Afghanistan",
      "continent_code": "AS",
      "continent_name": "Asia",
      "alpha_3": "AFG",
      "numeric_code": "004",
      "flag": "https://flagcdn.com/af.svg",
      "sovereignty": "UN member state",
      "dial_code": "+93",
      "supported_currency": [
        "AFN"
      ],
      "timezones": {
        "Asia/Kabul": {
          "utc_offset": "UTC +04:30"
        }
      },
      "timezone_of_capital": "Asia/Kabul",
      "locales": {
        "fa_AF": {
          "name": "Persian (Afghanistan)"
        },
        "ps": {
          "name": "Pashto"
        },
        "uz_AF": {
          "name": "Uzbek"
        },
        "tk": {
          "name": "Turkmen"
        }
      },
      "default_locale": "fa_AF",
      "default_currency": "AFN"
    },
    // more_countries
*/
```

#### getDefaultLocaleByCountry

The getDefaultLocaleByCountry API simplifies the process of retrieving the default locale for any country. With a quick query, it provides the primary locale used in the specified country, ensuring seamless localization for applications.

##### Examples

```javascript
// Getting default locale of a country
const res = await getDefaultLocaleByCountry('AF');
console.log(res);
/*
    fa_AF
*/

// Passing invalid country code
getDefaultLocaleByCountry('XYZ').catch((err) => {
  console.log(err);
}); // Outputs Invalid country code: XYZ
```

#### getByCountry

The getByCountry API offers a treasure trove of information about any country in the world. With a single query, you can uncover details like country names, languages, currencies, dial codes, timezones, and even links to their flags. It's a perfect tool for building apps that need geographic or cultural context.

##### Examples

```javascript
// Fetching the metadata for a country
const res = await getByCountry('AF');
console.log(res);
/*
    {
      "country_name": "Afghanistan",
      "continent_code": "AS",
      "continent_name": "Asia",
      "alpha_3": "AFG",
      "numeric_code": "004",
      "flag": "https://flagcdn.com/af.svg",
      "sovereignty": "UN member state",
      "dial_code": "+93",
      "supported_currency": [
        "AFN"
      ],
      "timezones": {
        "Asia/Kabul": {
          "utc_offset": "UTC +04:30"
        }
      },
      "timezone_of_capital": "Asia/Kabul",
      "locales": {
        "fa_AF": {
          "name": "Persian (Afghanistan)"
        },
        "ps": {
          "name": "Pashto"
        },
        "uz_AF": {
          "name": "Uzbek"
        },
        "tk": {
          "name": "Turkmen"
        }
      },
      "default_locale": "fa_AF",
      "default_currency": "AFN"
    }
*/
```

#### getLocaleList()

🌐 This function fetches a comprehensive mapping of country codes to their supported locale codes. It's your go-to tool for discovering which locales are available for each country! The function returns a promise that resolves to an object where each key is a country code, and its value is an array of supported locale codes.

```javascript
const locales = await getLocaleList();
console.log(locales);
/* Output:
{
  "IN": ["hi_IN", "en_IN"],
  "US": ["en_US"],
  // ... other countries and their locales
}
*/
```

#### getDefaultLocaleList() 🌐

The `getDefaultLocaleList` API provides a comprehensive mapping of country codes to their default locale codes. This function is particularly useful when you need to quickly identify the primary language/locale used in each country. It returns a promise that resolves to an object where each key is a country code, and its value is the default locale code for that country.

##### Examples

```javascript
// Fetching default locales for all countries
const defaultLocales = await getDefaultLocaleList();
console.log(defaultLocales);
/* Output:
{
  "AF": "fa_AF",    // Afghanistan's default locale
  "IN": "en_IN",    // India's default locale
  "US": "en_US",    // United States' default locale
  "JP": "ja_JP",    // Japan's default locale
  // ... other countries and their default locales
}
*/

// Error handling
try {
  const defaultLocales = await getDefaultLocaleList();
} catch (error) {
  console.error(error.message);
  // Handles various error cases like:
  // - Network errors
  // - Invalid response format
  // - Empty response data
}
```

#### getLocaleByCountry

The getLocaleByCountry API is your multilingual compass, helping you discover all the supported locales for any country. Perfect for building apps that need to handle multiple language variants within a single country, it returns an array of locale codes that are officially used in the specified country.

##### Examples

```javascript
// Getting all supported locales for a country
const res = await getLocaleByCountry('AF');
console.log(res);
/*
    [
        "fa_AF",
        "ps",
        "uz_AF",
        "tk"
    ]
*/

// Passing invalid country code
getLocaleByCountry('XYZ').catch((err) => {
  console.log(err);
}); // Outputs Invalid country code: XYZ
```

#### getStates(country_code)

Embark on a state-by-state discovery with the getStates API! Get access to a treasure trove of state information, including names, time zones, and even a list of vibrant cities within each state.

##### Examples

```javascript
// Getting list of all states
const res = await getStates('IN');
console.log(res);
/*
{"NL": {"name": "Nagaland",
      "cities": [{"name": "Wokha",
        "timezone": "Asia/Kolkata",
        "zipcodes": ["797111"],
        "region_name": "nan"},
        {"name": "Mokokchūng",
          "timezone": "Asia/Kolkata",
          "zipcodes": ["798601",
            "798601",
            "798604",
            "798607",
            "798614",
            "798615",
            "798618"],
          "region_name": "nan"},
        {"name": "Kohima",
          "timezone": "Asia/Kolkata",
          "zipcodes": ["797001",
            "797002",
            "797003",
            "797006",
            "797105",
            "797109",
            "797120"],
          "region_name": "nan"},
        {"name": "Dimāpur",
          "timezone": "Asia/Kolkata",
          "zipcodes": ["797103",
            "797103",
            "797106",
            "797112",
            "797115",
            "797116",
            "797118"],
          "region_name": "nan"}]}
          // ...more_states
          }
*/

// Passing invalid country code
getStates('XYZ').catch((err) => {
  console.log(err);
}); // Outputs Invalid country code: XYZ
```

#### getStatesByZipCode(zipcode, countryCode?)

🏘️ Want to find out which state a zipcode belongs to? The getStatesByZipCode API is your trusty guide! Just provide a zipcode, and optionally a country code, and it'll fetch the state information for you. If you don't specify a country, it'll search across all supported countries to find your zipcode's home state. Perfect for address validation, location-based services, or just satisfying your geographical curiosity! 🌍🔍

##### Examples

```javascript
// Finding state for a specific zipcode in a country
const stateInfo = await getStatesByZipCode('110001', 'IN');
console.log(stateInfo);
/*
{
  code: 'DL',
  name: 'Delhi',
  country: 'IN'
}
*/

// Searching across all supported countries
const stateInfo = await getStatesByZipCode('110001');
console.log(stateInfo);
/*
{
  code: 'DL',
  name: 'Delhi',
  country: 'IN'
}
*/

// Handling invalid zipcodes
try {
  await getStatesByZipCode('999999', 'IN');
} catch (error) {
  console.error(error.message);
  // Outputs: Zipcode "999999" not found in any supported country. Please ensure you provide a valid zipcode that exists within the specified countries.
}

// Handling invalid country codes
try {
  await getStatesByZipCode('110001', 'XX');
} catch (error) {
  console.error(error.message);
  // Outputs: Invalid country code: XX. Please ensure you provide a valid country code.
}
```

#### getCities(country_code, states_code)

Uncover the charm of cities worldwide with the getCities API! This dynamic tool fetches an array of cities complete with their names, time zones, and region names, providing a detailed glimpse into urban life across the globe.

##### Examples

```javascript
// Getting list of all cities for a country
const res = await getCities('IN');
console.log(res);
/*
 [{
    name: 'Tughlakābād',
    timezone: 'Asia/Kolkata',
    zipcodes: [],
    region_name: 'nan',
  },
  {
    name: 'Sabzi Mandi',
    timezone: 'Asia/Kolkata',
    zipcodes: [],
    region_name: 'nan',
  },
  {
    name: 'Pālam',
    timezone: 'Asia/Kolkata',
    zipcodes: ['517401', '517401'],
    region_name: 'nan',
  },
  {
    name: 'New Delhi',
    timezone: 'Asia/Kolkata',
    zipcodes: ['110001', '110020', '110029', '110084'],
    region_name: 'nan',
  },
  // ...more_cities
  ]
*/

// Getting list of all cities within a state
const res = await getCities('IN', 'DL');
console.log(res);
/*
 [{
    name: 'Tughlakābād',
    timezone: 'Asia/Kolkata',
    zipcodes: [],
    region_name: 'nan',
  },
  {
    name: 'Sabzi Mandi',
    timezone: 'Asia/Kolkata',
    zipcodes: [],
    region_name: 'nan',
  },
  {
    name: 'Pālam',
    timezone: 'Asia/Kolkata',
    zipcodes: ['517401', '517401'],
    region_name: 'nan',
  },
  {
    name: 'New Delhi',
    timezone: 'Asia/Kolkata',
    zipcodes: ['110001', '110020', '110029', '110084'],
    region_name: 'nan',
  },
  // ...more_cities_in_DL
  ]
*/

// Passing invalid country code
getCities('XYZ').catch((err) => {
  console.log(err);
}); // Outputs Invalid country code: XYZ

// Passing invalid state code
getCities('IN', 'XYZ').catch((err) => {
  console.log(err);
}); // Outputs State code XYZ missing in IN
```

#### getZipcodes(country_code, states_code)

Explore postal codes with the getZipcodes API! Discover a list of unique zip codes organized by country and state, making it easy to navigate geographic areas and streamline address-based operations.

##### Examples

```javascript
// Getting list of all cities for a country
const res = await getZipcodes('IN');
console.log(res);
/*
 ['517401', '517401','110001', '110020', '110029', '110084', ...more_zipcodes]
*/

// Getting list of all cities within a state
const res = await getZipcodes('IN', 'DL');
console.log(res);
/*
 ['517401', '517401','110001', '110020', '110029', '110084', ...more_zipcodes_in_DL]
*/

// Passing invalid country code
getZipcodes('XYZ').catch((err) => {
  console.log(err);
}); // Outputs Invalid country code: XYZ

// Passing invalid state code
getZipcodes('IN', 'XYZ').catch((err) => {
  console.log(err);
}); // Outputs State code XYZ missing in IN
```

#### getZipcodesByCity(countryCode, cityIdentifier)

🏙️ Get all postal codes for a specific city! This versatile API accepts either a city name or city code and returns an array of zipcodes. Perfect for address validation and location-based services!

##### Parameters

- `countryCode`: A valid country code (e.g., 'IN' for India)
- `cityIdentifier`: The city name (e.g., 'New Delhi')

##### Returns

Promise that resolves to an array of zipcodes for the specified city.

##### Examples

```javascript
// Using city name
const delhiZipcodes = await getZipcodesByCity('IN', 'New Delhi');
console.log(delhiZipcodes); // ['110001', '110002', ...]

// Case-insensitive matching works too!
const eastDelhiZipcodes = await getZipcodesByCity('IN', 'East Delhi');
console.log(eastDelhiZipcodes); // ['110031', '110032', ...]
```

##### Error Handling

```javascript
try {
  const zipcodes = await getZipcodesByCity('XYZ', 'Invalid City');
} catch (error) {
  console.error(error.message);
  // Outputs: Invalid country code: XYZ. Please ensure you provide a valid country code.
  // or: City with identifier "Invalid City" not found in XYZ...
}
```

#### validateZipCode(zipcode, countryCode?) 🔍

The `validateZipCode` API helps you verify if a zipcode exists in a specific country or across all supported countries. This function is particularly useful for address validation, form verification, and ensuring postal codes are valid before processing.

##### Parameters

- `zipcode` (string): The zipcode to validate
- `countryCode` (optional, string): The country code to validate against. If not provided, searches across all supported countries.

##### Returns

Promise that resolves to:

- `true` if the zipcode exists in the specified country (or any country if no country code is provided)
- `false` if the zipcode is not found

##### Examples

```javascript
// Validating a zipcode in a specific country
const isValid = await validateZipCode('110001', 'IN');
console.log(isValid); // true (for Delhi, India)

// Validating a zipcode across all supported countries
const existsAnywhere = await validateZipCode('90001');
console.log(existsAnywhere); // true (if found in any country)

// Handling invalid zipcodes
const invalidZip = await validateZipCode('00000', 'IN');
console.log(invalidZip); // false

// Handling invalid country codes
try {
  await validateZipCode('110001', 'XYZ');
} catch (error) {
  console.error(error.message);
  // Outputs: Invalid country code: XYZ. Please ensure you provide a valid country code.
}

// Handling empty zipcodes
try {
  await validateZipCode('');
} catch (error) {
  console.error(error.message);
  // Outputs: Zipcode is required. Please provide a valid zipcode.
}
```

##### Error Handling

The API throws errors in the following cases:

- When the zipcode is empty or contains only whitespace
- When an invalid country code is provided
- When the API request fails while searching in a specific country

For multi-country searches (when no country code is provided), errors are silently handled by returning `false`, allowing the search to continue with other countries.

#### getFlagOfCountry(countryCode) 🏁

Source for flag images: [FlagCDN](https://flagcdn.com/).

Retrieve flag images for any ISO country code 🌍✈️ with a simple API call, bolstering your application's global engagement 🌐 and honoring worldwide diversity 🏳️. This method efficiently integrates international flags into your digital projects, leveraging high-resolution SVG formats from a reliable source.

##### Examples

```javascript
// Fetching the flag of the United States 🇺🇸
console.log(getFlagOfCountry('US'));
/*
{
    "original": "https://flagcdn.com/US.svg",
    "4X3": "https://unpkg.com/@razorpay/i18nify-js/lib/assets/flags/us.svg"
}
*/

// Fetching the flag of India 🇮🇳
console.log(getFlagOfCountry('IN'));
/*
{
    "original": "https://flagcdn.com/IN.svg",
    "4X3": "https://unpkg.com/@razorpay/i18nify-js/lib/assets/flags/in.svg"
}
*/

// When you wander off the map with an invalid country code
try {
  console.log(getFlagOfCountry('XX')); // Oops, this will throw an error
} catch (error) {
  console.error(error.message); // Politely informs 'Invalid country code: XX'
}
```

#### getFlagsForAllCountries() 🌐

Source for flag images: [FlagCDN](https://flagcdn.com/).

Access a comprehensive collection of global flags with an ISO country code 🌍✈️—serving as your digital passport 🛂 to a visually unified world. This feature amplifies your app's international flair 🌐 and celebrates cultural diversity 🏳️🔍 by embedding flags from every recognized nation.

##### Examples

```javascript
// Embracing the flags of all nations
const allFlags = getFlagsForAllCountries();
console.log(allFlags);
/*
Behold, an object where each key is a country code linked to its flag's URL, such as:
{
  US: {
    "original": "https://flagcdn.com/US.svg",
    "4X3": "https://unpkg.com/@razorpay/i18nify-js/lib/assets/flags/us.svg"
  },
  IN: {
    "original": "https://flagcdn.com/IN.svg",
    "4X3": "https://unpkg.com/@razorpay/i18nify-js/lib/assets/flags/in.svg"
  },
  ...
}
*/
```

### Module 04: Date & Time Module

This module provides functions for formatting and manipulating dates and times in a locale-sensitive manner using the JavaScript Intl API & Date object.

#### formatDateTime(date, options)

🛠️ Dive into the sophistication of formatDateTime, a highly configurable function designed for developers seeking to master the intricacies of international date and time formatting. Leveraging the robust capabilities of the Intl.DateTimeFormat API, this utility offers unparalleled precision and adaptability in crafting date-time strings. Whether your application caters to a global audience or requires meticulous timestamping, formatDateTime delivers the versatility and accuracy essential for modern software development. 🌍🔧

##### Examples

```javascript
// Comprehensive date-time formatting with custom options
console.log(
  formatDateTime('2024-12-31 23:59', {
    locale: 'en-US',
    dateTimeMode: 'dateTime',
    intlOptions: {
      weekday: 'long',
      year: 'numeric',
      month: 'short',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false,
    },
  }),
); // Outputs 'Tuesday, Dec 31, 2024, 23:59:00'

// Locale-specific date-only formatting
console.log(
  formatDateTime('2024-05-20', {
    locale: 'ja-JP',
    dateTimeMode: 'dateOnly',
  }),
); // Outputs '2024/05/20', adhering to the Japanese date format

// Time-only formatting with emphasis on precision
console.log(
  formatDateTime('2024-05-20 15:45:30', {
    locale: 'fr-FR',
    dateTimeMode: 'timeOnly',
    intlOptions: {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: true,
    },
  }),
); // Outputs '03:45:30 PM', catering to the French preference for 24-hour time with high precision
```

Utilize `formatDateTime` to ensure your application's date and time outputs are not only accurate 🎯 but also culturally and contextually appropriate 🌍. From backend logging systems 🖥️ to user-facing interfaces 📱, this function stands as a testament to your commitment to internationalization 🌐 and user experience excellence ✨. With its straightforward implementation 🛠️ and extensive configuration options ⚙️, `formatDateTime` empowers you to meet the diverse needs of your audience 👥, promoting clarity 📖 and understanding 🤝 across different cultures and languages 🗣️.

#### getRelativeTime(date, options)

⏳🌏 This time-traveling virtuoso effortlessly bridges the gap between dates, offering a glimpse into the past or a peek into the future. With the help of the Internationalization API (Intl), `getRelativeTime` transforms absolute dates into relatable, human-friendly phrases like '3 hours ago' or 'in 2 days'. Whether you're reminiscing the past or anticipating the future, this function keeps you connected to time in the most intuitive way! 🚀🕰️

##### Examples

```javascript
// How long ago was a past date?
console.log(getRelativeTime('2024-01-20')); // Outputs something like '3 days ago'

// How much time until a future date?
console.log(getRelativeTime('2024-01-26')); // Outputs 'in 3 days'

// Customizing output for different locales
console.log(
  getRelativeTime('2024-01-26', { locale: 'fr-FR', baseDate: '2024-01-23' }),
); // Outputs 'dans 3 jours' (in 3 days in French)
```

💡 Pro Tip: `getRelativeTime` is not just a way to express time differences; it's a bridge that connects your users to the temporal context in a way that's both meaningful and culturally aware. Time is more than seconds and minutes; it's a story, and this function helps you tell it! 📖⌚

#### getWeekdays(options)

📅🌐 This global day-namer is your trusty guide through the week, no matter where you are in the world. Using the power of the Internationalization API (Intl), `getWeekdays` serves up the names of all seven days tailored to your chosen locale. From planning international meetings to creating a multilingual planner, this function provides the perfect blend of cultural awareness and practical utility, keeping you in sync with the local rhythm of life, one day at a time! 🌟🗓️

##### Examples

```javascript
// Getting weekdays in English
console.log(getWeekdays({ locale: 'en-US' })); // Outputs ['Sunday', 'Monday', ..., 'Saturday']

// Discovering weekdays in French
console.log(getWeekdays({ locale: 'fr-FR' })); // Outputs ['dimanche', 'lundi', ..., 'samedi']

// Exploring weekdays in Japanese
console.log(getWeekdays({ locale: 'ja-JP' })); // Outputs ['日曜日', '月曜日', ..., '土曜日']
```

💡 Did You Know? The order and names of weekdays vary across cultures and languages. With `getWeekdays`, you can easily cater to a global audience, ensuring that your application speaks their language, quite literally! 🌍🗣️

#### parseDateTime(dateInput, options)

🔍🗓️ The `parseDateTime` function is like a time-traveler's best friend, expertly navigating the complex world of dates and times. Whether it's a string or a Date object you're dealing with, this function seamlessly transforms it into a comprehensive, easy-to-digest package of date information, tailored to any locale you desire. 🌍⏲️

##### Examples

```javascript
// Parsing a date string with default locale and options
const parsed1 = parseDateTime('18/01/2024');
console.log(parsed1); // Outputs object with detailed date components
/*
    {
        "day": "18",
        "month": "01",
        "year": "2024",
        "rawParts": [
            {
                "type": "day",
                "value": "18"
            },
            {
                "type": "literal",
                "value": "/"
            },
            {
                "type": "month",
                "value": "01"
            },
            {
                "type": "literal",
                "value": "/"
            },
            {
                "type": "year",
                "value": "2024"
            }
        ],
        "formattedDate": "18/01/2024",
        "date": "2024-01-17T18:30:00.000Z"
    }
*/

// Parsing with specific locale and formatting options
const parsed2 = parseDateTime('2024-01-23', {
  intlOptions: {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  },
  locale: 'fr-FR',
});
console.log(parsed2); // Outputs object with formatted date in French
/*
    {
        "weekday": "mardi",
        "day": "23",
        "month": "janvier",
        "year": "2024",
        "rawParts": [
            {
                "type": "weekday",
                "value": "mardi"
            },
            {
                "type": "literal",
                "value": " "
            },
            {
                "type": "day",
                "value": "23"
            },
            {
                "type": "literal",
                "value": " "
            },
            {
                "type": "month",
                "value": "janvier"
            },
            {
                "type": "literal",
                "value": " "
            },
            {
                "type": "year",
                "value": "2024"
            }
        ],
        "formattedDate": "mardi 23 janvier 2024",
        "date": "2024-01-22T18:30:00.000Z"
    }
*/

// Parsing a Date object
const parsed3 = parseDateTime(new Date(2024, 0, 23));
console.log(parsed3); // Outputs object with date components for January 23, 2024
/*
    {
        "day": "23",
        "month": "01",
        "year": "2024",
        "rawParts": [
            {
                "type": "day",
                "value": "23"
            },
            {
                "type": "literal",
                "value": "/"
            },
            {
                "type": "month",
                "value": "01"
            },
            {
                "type": "literal",
                "value": "/"
            },
            {
                "type": "year",
                "value": "2024"
            }
        ],
        "formattedDate": "23/01/2024",
        "date": "2024-01-22T18:30:00.000Z"
    }
*/
```

💡 Pro Tip: Leverage `parseDateTime` in applications where detailed date analysis and manipulation are key, such as in calendar apps, scheduling tools, or date-sensitive data processing. It's like having a Swiss Army knife for all things related to dates and times! 📅🛠️

#### Calendar, CalendarDate, CalendarDateTime, Time, ZonedDateTime

Leverage the power of Adobe's @internationalized/date with our module, designed to offer a sophisticated, locale-sensitive approach to managing dates and times. Utilize these advanced tools to create applications that are both intuitive and efficient, ensuring they connect with users worldwide.

Discover more about integrating these powerful components into your software at [Adobe's Internationalized Date Documentation](https://react-spectrum.adobe.com/internationalized/date/index.html).

##### Calendar 📆 [Documentation here](https://react-spectrum.adobe.com/internationalized/date/Calendar.html)

Tailor your app with comprehensive calendar interfaces, ensuring global locale compatibility.

##### CalendarDate 🗓 [Documentation here](https://react-spectrum.adobe.com/internationalized/date/CalendarDate.html)

Focus on date-specific functionalities, perfect for event planning and deadlines without the time zone hassle.

##### CalendarDateTime 📅🕒 [Documentation here](https://react-spectrum.adobe.com/internationalized/date/CalendarDateTime.html)

Merge dates and times seamlessly for scheduling and reminders, with smart time zone handling.

##### Time ⏰ [Documentation here](https://react-spectrum.adobe.com/internationalized/date/Time.html)

Simplify time tracking and events in your app, concentrating solely on time without the date aspect.

##### ZonedDateTime 🌍🕖 [Documentation here](https://react-spectrum.adobe.com/internationalized/date/ZonedDateTime.html)

Master global time zones for scheduling and planning across borders, ensuring accuracy and user relevance.

### Module 05: Banking

This module's your financial sidekick for all things banking! 🏦💰 Whether you're looking for bank codes, payment-related info, or planning to integrate banking details seamlessly into your app, this module has got you covered. No more hunting for bank-specific data—just plug and play! Here are the handy APIs this Banking Module brings to your toolkit. 🚀💳

#### getListOfBanks(\_countryCode)

🏦📋 Need a full list of banks for a specific country? This function delivers exactly that! Just pass in the country code, and it'll fetch an up-to-date list of banks available in that country—no branches included. Perfect for building banking-related features in your app without the hassle of manual data collection. If the country isn't supported, it'll let you know with a friendly error.

##### Examples

```javascript
async function fetchBanks() {
  try {
    const banks = await getListOfBanks('IN');
    console.log(banks);
    // Outputs an array of banks available in India (e.g., [{ name: 'State Bank of India', short_code: 'SBIN' }, { name: 'HDFC Bank', short_code: 'HDFC' }])
  } catch (err) {
    console.error(err.message);
  }
}

fetchBanks();
```