@innovayse/geo-atlas 2.0.0 → 2.0.2

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/README.md CHANGED
@@ -9,12 +9,14 @@ Zero API calls — all data is bundled locally.
9
9
 
10
10
  ## Features
11
11
 
12
- - **250 countries** with ISO2 codes, flags, phone codes, capitals, coordinates
12
+ - **250 countries** with ISO2/ISO3 codes, flags, phone codes, capitals, coordinates
13
13
  - **147,000+ cities** across all countries with coordinates
14
14
  - **Complete multilingual city names**: English, Russian (ru), Armenian (hy) + 15 more languages
15
- - **Native script** support for each city/country
15
+ - **Country translations**: all 250 countries translated to Russian and Armenian
16
+ - **Native script** support for each city and country
17
+ - **Dual ESM + CJS build** — works in browsers, Node.js, Nuxt 3, Vite
16
18
  - **TypeScript** — full type declarations included
17
- - **Zero dependencies** — fully offline, no API calls
19
+ - **Zero runtime dependencies** — fully offline, no API calls
18
20
 
19
21
  ## Installation
20
22
 
@@ -33,13 +35,29 @@ const countries = CountriesAtlas.getCountries()
33
35
  // [{ iso2: 'AM', name: 'Armenia', native: 'Հայաստան', emoji: '🇦🇲', phone: 374, ... }]
34
36
  ```
35
37
 
36
- ### Get states/regions of a country
38
+ ### Find a country by ISO2
39
+
40
+ ```ts
41
+ const armenia = CountriesAtlas.find('AM')
42
+ // { iso2: 'AM', name: 'Armenia', translations: { hy: 'Հայաստան', ru: 'Армения' }, ... }
43
+ ```
44
+
45
+ ### Get states/regions — sync (Node.js / CJS)
37
46
 
38
47
  ```ts
39
48
  const states = CountriesAtlas.getStates('AM')
40
49
  // [{ name: 'Yerevan', cities: [...] }, ...]
41
50
  ```
42
51
 
52
+ ### Get states/regions — async (Browser / ESM)
53
+
54
+ `getStatesAsync` uses dynamic `import()` and works in all environments including browsers:
55
+
56
+ ```ts
57
+ const states = await CountriesAtlas.getStatesAsync('AM')
58
+ // [{ name: 'Yerevan', cities: [...] }, ...]
59
+ ```
60
+
43
61
  ### Get cities
44
62
 
45
63
  ```ts
@@ -69,6 +87,7 @@ Each city includes:
69
87
  ```ts
70
88
  type Country = {
71
89
  iso2: string // 'AM'
90
+ iso3: string // 'ARM'
72
91
  name: string // 'Armenia'
73
92
  native: string // 'Հայաստան'
74
93
  emoji: string // '🇦🇲'
@@ -76,39 +95,59 @@ type Country = {
76
95
  phone: number // 374
77
96
  latitude: string // '40.0'
78
97
  longitude: string // '45.0'
79
- translations: Record<string, string>
98
+ translations: {
99
+ hy: string // 'Հայաստան'
100
+ ru: string // 'Армения'
101
+ // + 15 more languages
102
+ }
80
103
  currency: string // 'AMD'
81
104
  timezones: Timezone[]
82
105
  }
83
106
  ```
84
107
 
85
- ## Multilingual Helper (Nuxt/Vue)
108
+ ## Nuxt 3 / Vite Setup
109
+
110
+ To prevent esbuild from processing the large JSON data files (which causes OOM crashes), exclude the package from Vite's dependency optimization:
86
111
 
87
112
  ```ts
88
- type GeoLocale = 'en' | 'ru' | 'hy'
113
+ // nuxt.config.ts
114
+ export default defineNuxtConfig({
115
+ vite: {
116
+ optimizeDeps: {
117
+ exclude: ['@innovayse/geo-atlas']
118
+ }
119
+ }
120
+ })
121
+ ```
89
122
 
90
- /** Get localized city name with fallback */
91
- function getCityName(city: CityItem, locale: GeoLocale): string {
92
- if (locale === 'en') return city.name
93
- return city.translations[locale] ?? city.native ?? city.name
94
- }
123
+ Then use `getStatesAsync` for browser-side city loading:
95
124
 
96
- /** Get localized country name with fallback */
97
- function getCountryName(country: CountryItem, locale: GeoLocale): string {
98
- if (locale === 'en') return country.name
99
- return country.translations[locale] ?? country.native ?? country.name
100
- }
101
- ```
125
+ ```ts
126
+ // composables/useCountries.ts
127
+ import { CountriesAtlas } from '@innovayse/geo-atlas'
102
128
 
103
- ## Nuxt 3 / SSR Setup
129
+ // Async works in browser (ESM dynamic import)
130
+ const cities = await CountriesAtlas.getStatesAsync('AM')
131
+
132
+ // Sync — works in Node.js / SSR only
133
+ const cities = CountriesAtlas.getStates('AM')
134
+ ```
104
135
 
105
- Add to `nuxt.config.ts`:
136
+ ## Multilingual Country/City Names
106
137
 
107
138
  ```ts
108
- vite: {
109
- ssr: {
110
- noExternal: ['@innovayse/geo-atlas']
111
- }
139
+ type GeoLocale = 'en' | 'ru' | 'hy'
140
+
141
+ /** Get localized country name with fallback chain */
142
+ function getCountryName(country: Country, locale: GeoLocale): string {
143
+ if (locale === 'en') return country.name
144
+ return country.translations?.[locale] ?? country.native ?? country.name
145
+ }
146
+
147
+ /** Get localized city name with fallback chain */
148
+ function getCityName(city: City, locale: GeoLocale): string {
149
+ if (locale === 'en') return city.name
150
+ return city.translations?.[locale] ?? city.native ?? city.name
112
151
  }
113
152
  ```
114
153
 
@@ -117,8 +156,9 @@ vite: {
117
156
  ```ts
118
157
  import { ValidatorAtlas } from '@innovayse/geo-atlas'
119
158
 
120
- ValidatorAtlas.isValidCountry('AM') // true
121
- ValidatorAtlas.isValidState('AM', 'Yerevan') // true
159
+ ValidatorAtlas.isValidCountry('AM') // true
160
+ ValidatorAtlas.isValidCountry('XX') // false
161
+ ValidatorAtlas.isValidState('AM', 'Yerevan') // true
122
162
  ```
123
163
 
124
164
  ## License
@@ -40,6 +40,13 @@ export declare class CountriesAtlas {
40
40
  * @returns {State[] | undefined} - Array of state objects or undefined if not found.
41
41
  */
42
42
  getStates(iso2: string): State[] | undefined;
43
+ /**
44
+ * Retrieve all states of a country by its ISO2 code using dynamic import (browser-compatible).
45
+ *
46
+ * @param {string} iso2 - ISO2 code of the country.
47
+ * @returns {Promise<State[]>} - Promise resolving to array of state objects.
48
+ */
49
+ getStatesAsync(iso2: string): Promise<State[]>;
43
50
  /**
44
51
  * Find a state by its state code and country ISO2 code.
45
52
  *
@@ -1,4 +1,36 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
2
34
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
36
  };
@@ -83,6 +115,29 @@ class CountriesAtlas {
83
115
  }
84
116
  return undefined;
85
117
  }
118
+ /**
119
+ * Retrieve all states of a country by its ISO2 code using dynamic import (browser-compatible).
120
+ *
121
+ * @param {string} iso2 - ISO2 code of the country.
122
+ * @returns {Promise<State[]>} - Promise resolving to array of state objects.
123
+ */
124
+ getStatesAsync(iso2) {
125
+ var _a, _b;
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ var _c;
128
+ const country = this.find(iso2);
129
+ if (!country || !country.iso2)
130
+ return [];
131
+ try {
132
+ const mod = yield (_c = `../data/countries/${country.iso2.toLowerCase()}.json`, Promise.resolve().then(() => __importStar(require(_c))));
133
+ const data = (_a = mod.default) !== null && _a !== void 0 ? _a : mod;
134
+ return (_b = data.states) !== null && _b !== void 0 ? _b : [];
135
+ }
136
+ catch (_d) {
137
+ return [];
138
+ }
139
+ });
140
+ }
86
141
  // state(iso2: string, stateCode: string): Promise<State | undefined> | undefined {
87
142
  // const country = this.find(iso2);
88
143
  // if (country) {
@@ -14,3 +14,11 @@
14
14
  */
15
15
  export { default as CountriesAtlas } from './helpers/CountriesAtlas';
16
16
  export { default as ValidatorAtlas } from './helpers/ValidatorAtlas';
17
+ export type { Country } from './types/country.interface';
18
+ export type { State } from './types/state.interface';
19
+ export type { City } from './types/city.type';
20
+ export type { Timezone } from './types/timezone.type';
21
+ export type { Translations } from './types/translation.type';
22
+ export type { Currency } from './types/currency.type';
23
+ export type { PhoneCode } from './types/phone-code.interface';
24
+ export type { StateData } from './types/state-data.type';
@@ -40,6 +40,13 @@ export declare class CountriesAtlas {
40
40
  * @returns {State[] | undefined} - Array of state objects or undefined if not found.
41
41
  */
42
42
  getStates(iso2: string): State[] | undefined;
43
+ /**
44
+ * Retrieve all states of a country by its ISO2 code using dynamic import (browser-compatible).
45
+ *
46
+ * @param {string} iso2 - ISO2 code of the country.
47
+ * @returns {Promise<State[]>} - Promise resolving to array of state objects.
48
+ */
49
+ getStatesAsync(iso2: string): Promise<State[]>;
43
50
  /**
44
51
  * Find a state by its state code and country ISO2 code.
45
52
  *
@@ -1,3 +1,12 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import countriesData from '../data/atlas.json';
2
11
  /**
3
12
  * Main helper class for querying countries, states, cities, timezones,
@@ -77,6 +86,28 @@ export class CountriesAtlas {
77
86
  }
78
87
  return undefined;
79
88
  }
89
+ /**
90
+ * Retrieve all states of a country by its ISO2 code using dynamic import (browser-compatible).
91
+ *
92
+ * @param {string} iso2 - ISO2 code of the country.
93
+ * @returns {Promise<State[]>} - Promise resolving to array of state objects.
94
+ */
95
+ getStatesAsync(iso2) {
96
+ var _a, _b;
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ const country = this.find(iso2);
99
+ if (!country || !country.iso2)
100
+ return [];
101
+ try {
102
+ const mod = yield import(`../data/countries/${country.iso2.toLowerCase()}.json`);
103
+ const data = (_a = mod.default) !== null && _a !== void 0 ? _a : mod;
104
+ return (_b = data.states) !== null && _b !== void 0 ? _b : [];
105
+ }
106
+ catch (_c) {
107
+ return [];
108
+ }
109
+ });
110
+ }
80
111
  // state(iso2: string, stateCode: string): Promise<State | undefined> | undefined {
81
112
  // const country = this.find(iso2);
82
113
  // if (country) {
@@ -14,3 +14,11 @@
14
14
  */
15
15
  export { default as CountriesAtlas } from './helpers/CountriesAtlas';
16
16
  export { default as ValidatorAtlas } from './helpers/ValidatorAtlas';
17
+ export type { Country } from './types/country.interface';
18
+ export type { State } from './types/state.interface';
19
+ export type { City } from './types/city.type';
20
+ export type { Timezone } from './types/timezone.type';
21
+ export type { Translations } from './types/translation.type';
22
+ export type { Currency } from './types/currency.type';
23
+ export type { PhoneCode } from './types/phone-code.interface';
24
+ export type { StateData } from './types/state-data.type';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@innovayse/geo-atlas",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Offline countries, states and cities with multilingual support (EN/RU/HY + 15 languages).",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -10,10 +10,58 @@
10
10
  "import": "./dist/esm/index.js",
11
11
  "require": "./dist/cjs/index.js",
12
12
  "types": "./dist/cjs/index.d.ts"
13
+ },
14
+ "./country": {
15
+ "import": "./dist/esm/types/country.interface.js",
16
+ "require": "./dist/cjs/types/country.interface.js",
17
+ "types": "./dist/cjs/types/country.interface.d.ts"
18
+ },
19
+ "./state": {
20
+ "import": "./dist/esm/types/state.interface.js",
21
+ "require": "./dist/cjs/types/state.interface.js",
22
+ "types": "./dist/cjs/types/state.interface.d.ts"
23
+ },
24
+ "./city": {
25
+ "import": "./dist/esm/types/city.type.js",
26
+ "require": "./dist/cjs/types/city.type.js",
27
+ "types": "./dist/cjs/types/city.type.d.ts"
28
+ },
29
+ "./timezone": {
30
+ "import": "./dist/esm/types/timezone.type.js",
31
+ "require": "./dist/cjs/types/timezone.type.js",
32
+ "types": "./dist/cjs/types/timezone.type.d.ts"
33
+ },
34
+ "./translations": {
35
+ "import": "./dist/esm/types/translation.type.js",
36
+ "require": "./dist/cjs/types/translation.type.js",
37
+ "types": "./dist/cjs/types/translation.type.d.ts"
38
+ },
39
+ "./currency": {
40
+ "import": "./dist/esm/types/currency.type.js",
41
+ "require": "./dist/cjs/types/currency.type.js",
42
+ "types": "./dist/cjs/types/currency.type.d.ts"
43
+ },
44
+ "./phone-code": {
45
+ "import": "./dist/esm/types/phone-code.interface.js",
46
+ "require": "./dist/cjs/types/phone-code.interface.js",
47
+ "types": "./dist/cjs/types/phone-code.interface.d.ts"
48
+ }
49
+ },
50
+ "typesVersions": {
51
+ "*": {
52
+ "country": ["./dist/cjs/types/country.interface.d.ts"],
53
+ "state": ["./dist/cjs/types/state.interface.d.ts"],
54
+ "city": ["./dist/cjs/types/city.type.d.ts"],
55
+ "timezone": ["./dist/cjs/types/timezone.type.d.ts"],
56
+ "translations": ["./dist/cjs/types/translation.type.d.ts"],
57
+ "currency": ["./dist/cjs/types/currency.type.d.ts"],
58
+ "phone-code": ["./dist/cjs/types/phone-code.interface.d.ts"]
13
59
  }
14
60
  },
15
61
  "scripts": {
16
- "build": "rm -rf dist && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json"
62
+ "build": "rm -rf dist && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json",
63
+ "test": "vitest run",
64
+ "test:watch": "vitest"
17
65
  },
18
66
  "keywords": [
19
67
  "countries",
@@ -28,8 +76,10 @@
28
76
  ],
29
77
  "license": "MIT",
30
78
  "devDependencies": {
79
+ "@types/node": "^18.19.0",
80
+ "ts-node": "^10.9.2",
31
81
  "typescript": "4.9.5",
32
- "@types/node": "18.19.0"
82
+ "vitest": "^4.1.4"
33
83
  },
34
84
  "files": [
35
85
  "dist/**/*",