Skip to content

Commit d464294

Browse files
author
Divyansh Singh
authored
feat: add getLocaleList api in geo module [ROW-569] (#220)
* add new api in geo module - getLocaleList * remove unused imports * refactor api output * add readme * Create fluffy-ways-sing.md
1 parent 2d68274 commit d464294

File tree

5 files changed

+129
-0
lines changed

5 files changed

+129
-0
lines changed

.changeset/fluffy-ways-sing.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@razorpay/i18nify-js": patch
3+
---
4+
5+
feat: add getLocaleList api in geo module

packages/i18nify-js/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,22 @@ console.log(res);
760760
*/
761761
```
762762

763+
#### getLocaleList()
764+
765+
🌐 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.
766+
767+
```javascript
768+
const locales = await getLocaleList();
769+
console.log(locales);
770+
/* Output:
771+
{
772+
"IN": ["hi_IN", "en_IN"],
773+
"US": ["en_US"],
774+
// ... other countries and their locales
775+
}
776+
*/
777+
```
778+
763779
#### getLocaleByCountry
764780

765781
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.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import getLocaleList from '../getLocaleList';
2+
import { I18NIFY_DATA_SOURCE } from '../../shared';
3+
4+
describe('getLocaleList', () => {
5+
const mockResponse = {
6+
metadata_information: {
7+
IN: {
8+
locales: {
9+
hi_IN: { name: 'Hindi' },
10+
en_IN: { name: 'English' },
11+
},
12+
},
13+
US: {
14+
locales: {
15+
en_US: { name: 'English' },
16+
},
17+
},
18+
},
19+
};
20+
21+
beforeEach(() => {
22+
global.fetch = jest.fn(() =>
23+
Promise.resolve({
24+
json: () => Promise.resolve(mockResponse),
25+
}),
26+
) as jest.Mock;
27+
});
28+
29+
afterEach(() => {
30+
jest.resetAllMocks();
31+
});
32+
33+
it('fetches all locales successfully', async () => {
34+
const localeList = await getLocaleList();
35+
expect(global.fetch).toHaveBeenCalledWith(
36+
`${I18NIFY_DATA_SOURCE}/country/metadata/data.json`,
37+
);
38+
expect(localeList).toEqual({
39+
IN: ['hi_IN', 'en_IN'],
40+
US: ['en_US'],
41+
});
42+
});
43+
44+
it('handles API errors correctly', async () => {
45+
const errorMessage = 'Network error';
46+
global.fetch = jest.fn(() =>
47+
Promise.reject(new Error(errorMessage)),
48+
) as jest.Mock;
49+
50+
await expect(getLocaleList()).rejects.toThrow(
51+
`An error occurred while fetching country metadata. The error details are: ${errorMessage}.`,
52+
);
53+
});
54+
55+
it('handles empty response data', async () => {
56+
global.fetch = jest.fn(() =>
57+
Promise.resolve({
58+
json: () => Promise.resolve({ metadata_information: {} }),
59+
}),
60+
) as jest.Mock;
61+
62+
const localeList = await getLocaleList();
63+
expect(localeList).toEqual({});
64+
});
65+
66+
it('handles malformed response data', async () => {
67+
global.fetch = jest.fn(() =>
68+
Promise.resolve({
69+
json: () => Promise.resolve({ invalid_key: {} }),
70+
}),
71+
) as jest.Mock;
72+
73+
await expect(getLocaleList()).rejects.toThrow(
74+
'An error occurred while fetching country metadata.',
75+
);
76+
});
77+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { withErrorBoundary } from '../../common/errorBoundary';
2+
import { I18NIFY_DATA_SOURCE } from '../shared';
3+
4+
/**
5+
* Retrieves the list of locales for a country or all countries
6+
*
7+
* This function makes a network request to central i18nify-data source and
8+
* returns a promise for the locales of a country or all countries
9+
*
10+
* @param {CountryCodeType} [countryCode] - Optional country code to get locales for a specific country
11+
* @returns {Promise} Promise object containing locale information
12+
*/
13+
const getLocaleList = (): Promise<Record<string, string[]>> => {
14+
return fetch(`${I18NIFY_DATA_SOURCE}/country/metadata/data.json`)
15+
.then((res) => res.json())
16+
.then((res) => {
17+
const allLocales: Record<string, string[]> = {};
18+
Object.keys(res.metadata_information).forEach((code) => {
19+
allLocales[code] = Object.keys(res.metadata_information[code].locales);
20+
});
21+
return allLocales;
22+
})
23+
.catch((err) => {
24+
throw new Error(
25+
`An error occurred while fetching country metadata. The error details are: ${err.message}.`,
26+
);
27+
});
28+
};
29+
30+
export default withErrorBoundary<typeof getLocaleList>(getLocaleList);

packages/i18nify-js/src/modules/geo/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export { default as getCities } from './getCities';
66
export { default as getZipcodes } from './getZipcodes';
77
export { default as getByCountry } from './getByCountry';
88
export { default as getDefaultLocaleByCountry } from './getDefaultLocaleByCountry';
9+
export { default as getLocaleList } from './getLocaleList';
910
export { default as getLocaleByCountry } from './getLocaleByCountry';

0 commit comments

Comments
 (0)