i18n-iso-cities 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/index.d.mts +91 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.js +120 -0
- package/dist/index.mjs +89 -0
- package/langs/ar.json +421 -0
- package/langs/en.json +421 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 houssam966
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# i18n-iso-cities
|
|
2
|
+
|
|
3
|
+
Multilingual city name translations organized by ISO 3166-1 alpha-2 country codes.
|
|
4
|
+
Modeled after [i18n-iso-countries](https://www.npmjs.com/package/i18n-iso-countries) — register only the locales you need for tree-shaking.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install i18n-iso-cities
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import cities from 'i18n-iso-cities';
|
|
16
|
+
|
|
17
|
+
// Import only the locales you need (tree-shakeable)
|
|
18
|
+
import en from 'i18n-iso-cities/langs/en.json';
|
|
19
|
+
import ar from 'i18n-iso-cities/langs/ar.json';
|
|
20
|
+
|
|
21
|
+
cities.registerLocale(en);
|
|
22
|
+
cities.registerLocale(ar);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Translate a city name (with country code)
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
cities.getName('SA', 'Riyadh', 'ar'); // 'الرياض'
|
|
29
|
+
cities.getName('AE', 'Dubai', 'ar'); // 'دبي'
|
|
30
|
+
cities.getName('EG', 'Cairo', 'ar'); // 'القاهرة'
|
|
31
|
+
cities.getName('US', 'New York', 'ar'); // 'نيويورك'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Translate without country code (convenience)
|
|
35
|
+
|
|
36
|
+
Useful when you get city names from APIs (e.g. Instagram demographics) without country codes.
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
cities.translate('Riyadh', 'ar'); // 'الرياض'
|
|
40
|
+
cities.translate('london', 'ar'); // 'لندن' (case-insensitive)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Get all cities for a country
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
cities.getAll('QA', 'ar');
|
|
47
|
+
// [
|
|
48
|
+
// { name: 'Al Daayen', translation: 'الضعاين' },
|
|
49
|
+
// { name: 'Al Khor', translation: 'الخور' },
|
|
50
|
+
// { name: 'Al Rayyan', translation: 'الريان' },
|
|
51
|
+
// { name: 'Al Shamal', translation: 'الشمال' },
|
|
52
|
+
// { name: 'Al Wakrah', translation: 'الوكرة' },
|
|
53
|
+
// { name: 'Doha', translation: 'الدوحة' },
|
|
54
|
+
// ...
|
|
55
|
+
// ]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Reverse lookup (translated → original)
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
cities.getOriginalName('الرياض', 'ar');
|
|
62
|
+
// { countryCode: 'SA', name: 'Riyadh' }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Utility methods
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
cities.getCountryCodes('ar'); // ['SA', 'AE', 'KW', 'QA', ...]
|
|
69
|
+
cities.getSupportedLocales(); // ['en', 'ar']
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Supported Locales
|
|
73
|
+
|
|
74
|
+
| Locale | Language |
|
|
75
|
+
|--------|----------|
|
|
76
|
+
| `en` | English |
|
|
77
|
+
| `ar` | Arabic |
|
|
78
|
+
|
|
79
|
+
## Covered Countries
|
|
80
|
+
|
|
81
|
+
### Arab World (comprehensive coverage)
|
|
82
|
+
🇸🇦 Saudi Arabia (70+ cities) · 🇦🇪 UAE · 🇰🇼 Kuwait · 🇶🇦 Qatar · 🇧🇭 Bahrain · 🇴🇲 Oman
|
|
83
|
+
🇵🇸 Palestine · 🇯🇴 Jordan · 🇪🇬 Egypt · 🇱🇧 Lebanon · 🇮🇶 Iraq · 🇱🇾 Libya
|
|
84
|
+
🇸🇩 Sudan · 🇲🇦 Morocco · 🇹🇳 Tunisia · 🇩🇿 Algeria · 🇸🇾 Syria · 🇾🇪 Yemen
|
|
85
|
+
|
|
86
|
+
### Major World Cities
|
|
87
|
+
🇬🇧 United Kingdom · 🇺🇸 United States · 🇫🇷 France · 🇩🇪 Germany · 🇹🇷 Turkey · 🇮🇳 India · 🇵🇰 Pakistan
|
|
88
|
+
|
|
89
|
+
## Contributing
|
|
90
|
+
|
|
91
|
+
### Adding a new locale
|
|
92
|
+
|
|
93
|
+
1. Create `langs/<locale>.json` following the existing format:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"locale": "fr",
|
|
98
|
+
"cities": {
|
|
99
|
+
"SA": {
|
|
100
|
+
"Riyadh": "Riyad",
|
|
101
|
+
"Jeddah": "Djeddah"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
2. The keys must match the English city names in `langs/en.json`.
|
|
108
|
+
3. Submit a pull request.
|
|
109
|
+
|
|
110
|
+
### Adding cities
|
|
111
|
+
|
|
112
|
+
1. Add the city to **all** locale files (`en.json`, `ar.json`, etc.).
|
|
113
|
+
2. Keep cities alphabetically sorted within each country.
|
|
114
|
+
3. Run `npm test` to verify data integrity.
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
### `registerLocale(data: LocaleData): void`
|
|
119
|
+
Register a locale. Must be called before using other methods.
|
|
120
|
+
|
|
121
|
+
### `getName(countryCode: string, cityName: string, locale: string): string | undefined`
|
|
122
|
+
Get translated city name by country code and English name.
|
|
123
|
+
|
|
124
|
+
### `translate(cityName: string, locale: string): string | undefined`
|
|
125
|
+
Translate a city name without specifying country code (case-insensitive, first match).
|
|
126
|
+
|
|
127
|
+
### `getAll(countryCode: string, locale: string): CityEntry[]`
|
|
128
|
+
Get all cities for a country, sorted by English name.
|
|
129
|
+
|
|
130
|
+
### `getOriginalName(translatedName: string, locale: string): CityLookup | undefined`
|
|
131
|
+
Reverse lookup: translated name → `{ countryCode, name }`.
|
|
132
|
+
|
|
133
|
+
### `getCountryCodes(locale: string): string[]`
|
|
134
|
+
Get all country codes that have data for a locale.
|
|
135
|
+
|
|
136
|
+
### `getSupportedLocales(): string[]`
|
|
137
|
+
Get all registered locale codes.
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT © [houssam966](https://github.com/houssam966)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n-iso-cities
|
|
3
|
+
*
|
|
4
|
+
* Multilingual city name translations organized by ISO 3166-1 country codes.
|
|
5
|
+
* Modeled after i18n-iso-countries — register only the locales you need.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import cities from 'i18n-iso-cities';
|
|
9
|
+
* import en from 'i18n-iso-cities/langs/en.json';
|
|
10
|
+
* import ar from 'i18n-iso-cities/langs/ar.json';
|
|
11
|
+
*
|
|
12
|
+
* cities.registerLocale(en);
|
|
13
|
+
* cities.registerLocale(ar);
|
|
14
|
+
*
|
|
15
|
+
* cities.getName('SA', 'Riyadh', 'ar'); // 'الرياض'
|
|
16
|
+
* cities.translate('Riyadh', 'ar'); // 'الرياض'
|
|
17
|
+
* cities.getAll('SA', 'ar'); // [{ name: 'Riyadh', translation: 'الرياض' }, ...]
|
|
18
|
+
* cities.getOriginalName('الرياض', 'ar'); // { countryCode: 'SA', name: 'Riyadh' }
|
|
19
|
+
*/
|
|
20
|
+
interface LocaleData {
|
|
21
|
+
locale: string;
|
|
22
|
+
cities: Record<string, Record<string, string>>;
|
|
23
|
+
}
|
|
24
|
+
interface CityEntry {
|
|
25
|
+
name: string;
|
|
26
|
+
translation: string;
|
|
27
|
+
}
|
|
28
|
+
interface CityLookup {
|
|
29
|
+
countryCode: string;
|
|
30
|
+
name: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Register a locale. Call this once per locale before using other methods.
|
|
34
|
+
* Locales are tree-shakeable — only import the ones you need.
|
|
35
|
+
*/
|
|
36
|
+
declare function registerLocale(data: LocaleData): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get the translated name of a city in a specific country.
|
|
39
|
+
*
|
|
40
|
+
* @param countryCode - ISO 3166-1 alpha-2 country code (e.g. "SA")
|
|
41
|
+
* @param cityName - English city name (e.g. "Riyadh")
|
|
42
|
+
* @param locale - Target locale (e.g. "ar")
|
|
43
|
+
* @returns Translated city name, or undefined if not found
|
|
44
|
+
*/
|
|
45
|
+
declare function getName(countryCode: string, cityName: string, locale: string): string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Translate a city name without specifying a country code.
|
|
48
|
+
* Searches all registered countries in the locale; returns first match.
|
|
49
|
+
* Useful for translating raw API responses (e.g. Instagram demographics).
|
|
50
|
+
*
|
|
51
|
+
* @param cityName - English city name (case-insensitive)
|
|
52
|
+
* @param locale - Target locale
|
|
53
|
+
* @returns Translated name, or undefined
|
|
54
|
+
*/
|
|
55
|
+
declare function translate(cityName: string, locale: string): string | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Get all cities for a country in a given locale.
|
|
58
|
+
*
|
|
59
|
+
* @param countryCode - ISO 3166-1 alpha-2 code
|
|
60
|
+
* @param locale - Target locale
|
|
61
|
+
* @returns Array of { name, translation } objects sorted by English name
|
|
62
|
+
*/
|
|
63
|
+
declare function getAll(countryCode: string, locale: string): CityEntry[];
|
|
64
|
+
/**
|
|
65
|
+
* Reverse-lookup: given a translated city name, find the original English name
|
|
66
|
+
* and country code.
|
|
67
|
+
*
|
|
68
|
+
* @param translatedName - City name in the target locale (e.g. "الرياض")
|
|
69
|
+
* @param locale - The locale of the translated name
|
|
70
|
+
* @returns { countryCode, name } or undefined
|
|
71
|
+
*/
|
|
72
|
+
declare function getOriginalName(translatedName: string, locale: string): CityLookup | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Get all country codes that have city data for a given locale.
|
|
75
|
+
*/
|
|
76
|
+
declare function getCountryCodes(locale: string): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Get all registered locales.
|
|
79
|
+
*/
|
|
80
|
+
declare function getSupportedLocales(): string[];
|
|
81
|
+
declare const _default: {
|
|
82
|
+
registerLocale: typeof registerLocale;
|
|
83
|
+
getName: typeof getName;
|
|
84
|
+
translate: typeof translate;
|
|
85
|
+
getAll: typeof getAll;
|
|
86
|
+
getOriginalName: typeof getOriginalName;
|
|
87
|
+
getCountryCodes: typeof getCountryCodes;
|
|
88
|
+
getSupportedLocales: typeof getSupportedLocales;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export { type CityEntry, type CityLookup, type LocaleData, _default as default, getAll, getCountryCodes, getName, getOriginalName, getSupportedLocales, registerLocale, translate };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n-iso-cities
|
|
3
|
+
*
|
|
4
|
+
* Multilingual city name translations organized by ISO 3166-1 country codes.
|
|
5
|
+
* Modeled after i18n-iso-countries — register only the locales you need.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import cities from 'i18n-iso-cities';
|
|
9
|
+
* import en from 'i18n-iso-cities/langs/en.json';
|
|
10
|
+
* import ar from 'i18n-iso-cities/langs/ar.json';
|
|
11
|
+
*
|
|
12
|
+
* cities.registerLocale(en);
|
|
13
|
+
* cities.registerLocale(ar);
|
|
14
|
+
*
|
|
15
|
+
* cities.getName('SA', 'Riyadh', 'ar'); // 'الرياض'
|
|
16
|
+
* cities.translate('Riyadh', 'ar'); // 'الرياض'
|
|
17
|
+
* cities.getAll('SA', 'ar'); // [{ name: 'Riyadh', translation: 'الرياض' }, ...]
|
|
18
|
+
* cities.getOriginalName('الرياض', 'ar'); // { countryCode: 'SA', name: 'Riyadh' }
|
|
19
|
+
*/
|
|
20
|
+
interface LocaleData {
|
|
21
|
+
locale: string;
|
|
22
|
+
cities: Record<string, Record<string, string>>;
|
|
23
|
+
}
|
|
24
|
+
interface CityEntry {
|
|
25
|
+
name: string;
|
|
26
|
+
translation: string;
|
|
27
|
+
}
|
|
28
|
+
interface CityLookup {
|
|
29
|
+
countryCode: string;
|
|
30
|
+
name: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Register a locale. Call this once per locale before using other methods.
|
|
34
|
+
* Locales are tree-shakeable — only import the ones you need.
|
|
35
|
+
*/
|
|
36
|
+
declare function registerLocale(data: LocaleData): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get the translated name of a city in a specific country.
|
|
39
|
+
*
|
|
40
|
+
* @param countryCode - ISO 3166-1 alpha-2 country code (e.g. "SA")
|
|
41
|
+
* @param cityName - English city name (e.g. "Riyadh")
|
|
42
|
+
* @param locale - Target locale (e.g. "ar")
|
|
43
|
+
* @returns Translated city name, or undefined if not found
|
|
44
|
+
*/
|
|
45
|
+
declare function getName(countryCode: string, cityName: string, locale: string): string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Translate a city name without specifying a country code.
|
|
48
|
+
* Searches all registered countries in the locale; returns first match.
|
|
49
|
+
* Useful for translating raw API responses (e.g. Instagram demographics).
|
|
50
|
+
*
|
|
51
|
+
* @param cityName - English city name (case-insensitive)
|
|
52
|
+
* @param locale - Target locale
|
|
53
|
+
* @returns Translated name, or undefined
|
|
54
|
+
*/
|
|
55
|
+
declare function translate(cityName: string, locale: string): string | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Get all cities for a country in a given locale.
|
|
58
|
+
*
|
|
59
|
+
* @param countryCode - ISO 3166-1 alpha-2 code
|
|
60
|
+
* @param locale - Target locale
|
|
61
|
+
* @returns Array of { name, translation } objects sorted by English name
|
|
62
|
+
*/
|
|
63
|
+
declare function getAll(countryCode: string, locale: string): CityEntry[];
|
|
64
|
+
/**
|
|
65
|
+
* Reverse-lookup: given a translated city name, find the original English name
|
|
66
|
+
* and country code.
|
|
67
|
+
*
|
|
68
|
+
* @param translatedName - City name in the target locale (e.g. "الرياض")
|
|
69
|
+
* @param locale - The locale of the translated name
|
|
70
|
+
* @returns { countryCode, name } or undefined
|
|
71
|
+
*/
|
|
72
|
+
declare function getOriginalName(translatedName: string, locale: string): CityLookup | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Get all country codes that have city data for a given locale.
|
|
75
|
+
*/
|
|
76
|
+
declare function getCountryCodes(locale: string): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Get all registered locales.
|
|
79
|
+
*/
|
|
80
|
+
declare function getSupportedLocales(): string[];
|
|
81
|
+
declare const _default: {
|
|
82
|
+
registerLocale: typeof registerLocale;
|
|
83
|
+
getName: typeof getName;
|
|
84
|
+
translate: typeof translate;
|
|
85
|
+
getAll: typeof getAll;
|
|
86
|
+
getOriginalName: typeof getOriginalName;
|
|
87
|
+
getCountryCodes: typeof getCountryCodes;
|
|
88
|
+
getSupportedLocales: typeof getSupportedLocales;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export { type CityEntry, type CityLookup, type LocaleData, _default as default, getAll, getCountryCodes, getName, getOriginalName, getSupportedLocales, registerLocale, translate };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
default: () => index_default,
|
|
24
|
+
getAll: () => getAll,
|
|
25
|
+
getCountryCodes: () => getCountryCodes,
|
|
26
|
+
getName: () => getName,
|
|
27
|
+
getOriginalName: () => getOriginalName,
|
|
28
|
+
getSupportedLocales: () => getSupportedLocales,
|
|
29
|
+
registerLocale: () => registerLocale,
|
|
30
|
+
translate: () => translate
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
var locales = {};
|
|
34
|
+
var reverseCache = {};
|
|
35
|
+
var flatCache = {};
|
|
36
|
+
function invalidateCache(locale) {
|
|
37
|
+
delete reverseCache[locale];
|
|
38
|
+
delete flatCache[locale];
|
|
39
|
+
}
|
|
40
|
+
function ensureReverse(locale) {
|
|
41
|
+
if (!reverseCache[locale]) {
|
|
42
|
+
const map = /* @__PURE__ */ new Map();
|
|
43
|
+
const countries = locales[locale];
|
|
44
|
+
if (countries) {
|
|
45
|
+
for (const [countryCode, cityMap] of Object.entries(countries)) {
|
|
46
|
+
for (const [name, translation] of Object.entries(cityMap)) {
|
|
47
|
+
if (!map.has(translation)) {
|
|
48
|
+
map.set(translation, { countryCode, name });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
reverseCache[locale] = map;
|
|
54
|
+
}
|
|
55
|
+
return reverseCache[locale];
|
|
56
|
+
}
|
|
57
|
+
function ensureFlat(locale) {
|
|
58
|
+
if (!flatCache[locale]) {
|
|
59
|
+
const map = /* @__PURE__ */ new Map();
|
|
60
|
+
const countries = locales[locale];
|
|
61
|
+
if (countries) {
|
|
62
|
+
for (const cityMap of Object.values(countries)) {
|
|
63
|
+
for (const [name, translation] of Object.entries(cityMap)) {
|
|
64
|
+
const key = name.toLowerCase();
|
|
65
|
+
if (!map.has(key)) {
|
|
66
|
+
map.set(key, translation);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
flatCache[locale] = map;
|
|
72
|
+
}
|
|
73
|
+
return flatCache[locale];
|
|
74
|
+
}
|
|
75
|
+
function registerLocale(data) {
|
|
76
|
+
if (!data?.locale || !data?.cities) return;
|
|
77
|
+
locales[data.locale] = data.cities;
|
|
78
|
+
invalidateCache(data.locale);
|
|
79
|
+
}
|
|
80
|
+
function getName(countryCode, cityName, locale) {
|
|
81
|
+
return locales[locale]?.[countryCode.toUpperCase()]?.[cityName];
|
|
82
|
+
}
|
|
83
|
+
function translate(cityName, locale) {
|
|
84
|
+
if (!cityName) return void 0;
|
|
85
|
+
return ensureFlat(locale).get(cityName.toLowerCase());
|
|
86
|
+
}
|
|
87
|
+
function getAll(countryCode, locale) {
|
|
88
|
+
const cityMap = locales[locale]?.[countryCode.toUpperCase()];
|
|
89
|
+
if (!cityMap) return [];
|
|
90
|
+
return Object.entries(cityMap).map(([name, translation]) => ({ name, translation })).sort((a, b) => a.name.localeCompare(b.name));
|
|
91
|
+
}
|
|
92
|
+
function getOriginalName(translatedName, locale) {
|
|
93
|
+
if (!translatedName) return void 0;
|
|
94
|
+
return ensureReverse(locale).get(translatedName);
|
|
95
|
+
}
|
|
96
|
+
function getCountryCodes(locale) {
|
|
97
|
+
return Object.keys(locales[locale] ?? {});
|
|
98
|
+
}
|
|
99
|
+
function getSupportedLocales() {
|
|
100
|
+
return Object.keys(locales);
|
|
101
|
+
}
|
|
102
|
+
var index_default = {
|
|
103
|
+
registerLocale,
|
|
104
|
+
getName,
|
|
105
|
+
translate,
|
|
106
|
+
getAll,
|
|
107
|
+
getOriginalName,
|
|
108
|
+
getCountryCodes,
|
|
109
|
+
getSupportedLocales
|
|
110
|
+
};
|
|
111
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
112
|
+
0 && (module.exports = {
|
|
113
|
+
getAll,
|
|
114
|
+
getCountryCodes,
|
|
115
|
+
getName,
|
|
116
|
+
getOriginalName,
|
|
117
|
+
getSupportedLocales,
|
|
118
|
+
registerLocale,
|
|
119
|
+
translate
|
|
120
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var locales = {};
|
|
3
|
+
var reverseCache = {};
|
|
4
|
+
var flatCache = {};
|
|
5
|
+
function invalidateCache(locale) {
|
|
6
|
+
delete reverseCache[locale];
|
|
7
|
+
delete flatCache[locale];
|
|
8
|
+
}
|
|
9
|
+
function ensureReverse(locale) {
|
|
10
|
+
if (!reverseCache[locale]) {
|
|
11
|
+
const map = /* @__PURE__ */ new Map();
|
|
12
|
+
const countries = locales[locale];
|
|
13
|
+
if (countries) {
|
|
14
|
+
for (const [countryCode, cityMap] of Object.entries(countries)) {
|
|
15
|
+
for (const [name, translation] of Object.entries(cityMap)) {
|
|
16
|
+
if (!map.has(translation)) {
|
|
17
|
+
map.set(translation, { countryCode, name });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
reverseCache[locale] = map;
|
|
23
|
+
}
|
|
24
|
+
return reverseCache[locale];
|
|
25
|
+
}
|
|
26
|
+
function ensureFlat(locale) {
|
|
27
|
+
if (!flatCache[locale]) {
|
|
28
|
+
const map = /* @__PURE__ */ new Map();
|
|
29
|
+
const countries = locales[locale];
|
|
30
|
+
if (countries) {
|
|
31
|
+
for (const cityMap of Object.values(countries)) {
|
|
32
|
+
for (const [name, translation] of Object.entries(cityMap)) {
|
|
33
|
+
const key = name.toLowerCase();
|
|
34
|
+
if (!map.has(key)) {
|
|
35
|
+
map.set(key, translation);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
flatCache[locale] = map;
|
|
41
|
+
}
|
|
42
|
+
return flatCache[locale];
|
|
43
|
+
}
|
|
44
|
+
function registerLocale(data) {
|
|
45
|
+
if (!data?.locale || !data?.cities) return;
|
|
46
|
+
locales[data.locale] = data.cities;
|
|
47
|
+
invalidateCache(data.locale);
|
|
48
|
+
}
|
|
49
|
+
function getName(countryCode, cityName, locale) {
|
|
50
|
+
return locales[locale]?.[countryCode.toUpperCase()]?.[cityName];
|
|
51
|
+
}
|
|
52
|
+
function translate(cityName, locale) {
|
|
53
|
+
if (!cityName) return void 0;
|
|
54
|
+
return ensureFlat(locale).get(cityName.toLowerCase());
|
|
55
|
+
}
|
|
56
|
+
function getAll(countryCode, locale) {
|
|
57
|
+
const cityMap = locales[locale]?.[countryCode.toUpperCase()];
|
|
58
|
+
if (!cityMap) return [];
|
|
59
|
+
return Object.entries(cityMap).map(([name, translation]) => ({ name, translation })).sort((a, b) => a.name.localeCompare(b.name));
|
|
60
|
+
}
|
|
61
|
+
function getOriginalName(translatedName, locale) {
|
|
62
|
+
if (!translatedName) return void 0;
|
|
63
|
+
return ensureReverse(locale).get(translatedName);
|
|
64
|
+
}
|
|
65
|
+
function getCountryCodes(locale) {
|
|
66
|
+
return Object.keys(locales[locale] ?? {});
|
|
67
|
+
}
|
|
68
|
+
function getSupportedLocales() {
|
|
69
|
+
return Object.keys(locales);
|
|
70
|
+
}
|
|
71
|
+
var index_default = {
|
|
72
|
+
registerLocale,
|
|
73
|
+
getName,
|
|
74
|
+
translate,
|
|
75
|
+
getAll,
|
|
76
|
+
getOriginalName,
|
|
77
|
+
getCountryCodes,
|
|
78
|
+
getSupportedLocales
|
|
79
|
+
};
|
|
80
|
+
export {
|
|
81
|
+
index_default as default,
|
|
82
|
+
getAll,
|
|
83
|
+
getCountryCodes,
|
|
84
|
+
getName,
|
|
85
|
+
getOriginalName,
|
|
86
|
+
getSupportedLocales,
|
|
87
|
+
registerLocale,
|
|
88
|
+
translate
|
|
89
|
+
};
|