@ooneex/country 0.0.1 → 0.0.4
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 +400 -0
- package/dist/index.d.ts +8 -1
- package/package.json +20 -8
- package/dist/ooneex-country-0.0.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -1 +1,401 @@
|
|
|
1
1
|
# @ooneex/country
|
|
2
|
+
|
|
3
|
+
A comprehensive country data library for TypeScript applications with timezone support and multi-language localization. This package provides type-safe access to country information, timezone data, and localized country names in English, French, and Romanian.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
✅ **Country Data** - Complete list of countries with ISO codes and names
|
|
15
|
+
|
|
16
|
+
✅ **Timezone Support** - Full timezone data powered by @vvo/tzdb
|
|
17
|
+
|
|
18
|
+
✅ **Multi-Language** - Localized country names in English, French, and Romanian
|
|
19
|
+
|
|
20
|
+
✅ **Type-Safe** - Full TypeScript support with proper type definitions
|
|
21
|
+
|
|
22
|
+
✅ **Zero Config** - Ready to use out of the box
|
|
23
|
+
|
|
24
|
+
✅ **Lightweight** - Minimal bundle size with tree-shakeable exports
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
### Bun
|
|
29
|
+
```bash
|
|
30
|
+
bun add @ooneex/country
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### pnpm
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @ooneex/country
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Yarn
|
|
39
|
+
```bash
|
|
40
|
+
yarn add @ooneex/country
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### npm
|
|
44
|
+
```bash
|
|
45
|
+
npm install @ooneex/country
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
### Basic Usage
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import type { CountryType, TimeZoneType } from '@ooneex/country';
|
|
54
|
+
|
|
55
|
+
// Type-safe country codes
|
|
56
|
+
const country: CountryType = 'US';
|
|
57
|
+
const timezone: TimeZoneType = 'America/New_York';
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Country Data (English)
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { COUNTRIES } from '@ooneex/country';
|
|
64
|
+
|
|
65
|
+
// Access all countries
|
|
66
|
+
COUNTRIES.forEach(country => {
|
|
67
|
+
console.log(`${country.name} (${country.code})`);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Find a specific country
|
|
71
|
+
const usa = COUNTRIES.find(c => c.code === 'US');
|
|
72
|
+
console.log(usa?.name); // "United States"
|
|
73
|
+
|
|
74
|
+
// Filter countries
|
|
75
|
+
const europeanCountries = COUNTRIES.filter(c =>
|
|
76
|
+
['FR', 'DE', 'IT', 'ES', 'GB'].includes(c.code)
|
|
77
|
+
);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### French Localization
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { COUNTRIES } from '@ooneex/country/fr';
|
|
84
|
+
|
|
85
|
+
// Countries with French names
|
|
86
|
+
COUNTRIES.forEach(country => {
|
|
87
|
+
console.log(`${country.name} (${country.code})`);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const france = COUNTRIES.find(c => c.code === 'FR');
|
|
91
|
+
console.log(france?.name); // "France"
|
|
92
|
+
|
|
93
|
+
const usa = COUNTRIES.find(c => c.code === 'US');
|
|
94
|
+
console.log(usa?.name); // "États-Unis"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Romanian Localization
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { COUNTRIES } from '@ooneex/country/ro';
|
|
101
|
+
|
|
102
|
+
// Countries with Romanian names
|
|
103
|
+
const romania = COUNTRIES.find(c => c.code === 'RO');
|
|
104
|
+
console.log(romania?.name); // "România"
|
|
105
|
+
|
|
106
|
+
const germany = COUNTRIES.find(c => c.code === 'DE');
|
|
107
|
+
console.log(germany?.name); // "Germania"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Working with Timezones
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import type { TimeZoneType } from '@ooneex/country';
|
|
114
|
+
|
|
115
|
+
// Type-safe timezone strings
|
|
116
|
+
const parisTime: TimeZoneType = 'Europe/Paris';
|
|
117
|
+
const tokyoTime: TimeZoneType = 'Asia/Tokyo';
|
|
118
|
+
const newYorkTime: TimeZoneType = 'America/New_York';
|
|
119
|
+
|
|
120
|
+
// Use with Date APIs
|
|
121
|
+
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
122
|
+
timeZone: parisTime,
|
|
123
|
+
dateStyle: 'full',
|
|
124
|
+
timeStyle: 'long'
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
console.log(formatter.format(new Date()));
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Country Selection Component (React Example)
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { COUNTRIES } from '@ooneex/country';
|
|
134
|
+
import type { CountryType } from '@ooneex/country';
|
|
135
|
+
|
|
136
|
+
function CountrySelect({
|
|
137
|
+
value,
|
|
138
|
+
onChange
|
|
139
|
+
}: {
|
|
140
|
+
value: CountryType;
|
|
141
|
+
onChange: (code: CountryType) => void;
|
|
142
|
+
}) {
|
|
143
|
+
return (
|
|
144
|
+
<select
|
|
145
|
+
value={value}
|
|
146
|
+
onChange={(e) => onChange(e.target.value as CountryType)}
|
|
147
|
+
>
|
|
148
|
+
{COUNTRIES.map(country => (
|
|
149
|
+
<option key={country.code} value={country.code}>
|
|
150
|
+
{country.name}
|
|
151
|
+
</option>
|
|
152
|
+
))}
|
|
153
|
+
</select>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API Reference
|
|
159
|
+
|
|
160
|
+
### Constants
|
|
161
|
+
|
|
162
|
+
#### `COUNTRIES`
|
|
163
|
+
|
|
164
|
+
Array of country objects with code and name.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
const COUNTRIES: readonly { code: string; name: string }[];
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Example:**
|
|
171
|
+
```typescript
|
|
172
|
+
import { COUNTRIES } from '@ooneex/country';
|
|
173
|
+
|
|
174
|
+
console.log(COUNTRIES[0]); // { code: 'AF', name: 'Afghanistan' }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Types
|
|
178
|
+
|
|
179
|
+
#### `CountryType`
|
|
180
|
+
|
|
181
|
+
Union type of all valid ISO 3166-1 alpha-2 country codes.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
type CountryType = 'AF' | 'AL' | 'DZ' | 'US' | 'FR' | /* ... */ ;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Example:**
|
|
188
|
+
```typescript
|
|
189
|
+
import type { CountryType } from '@ooneex/country';
|
|
190
|
+
|
|
191
|
+
const country: CountryType = 'US'; // ✓ Valid
|
|
192
|
+
const invalid: CountryType = 'XX'; // ✗ TypeScript error
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### `CountryNameType`
|
|
196
|
+
|
|
197
|
+
Union type of all country names (in English).
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
type CountryNameType = 'Afghanistan' | 'Albania' | 'United States' | /* ... */ ;
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### `TimeZoneType`
|
|
204
|
+
|
|
205
|
+
Union type of all valid IANA timezone identifiers.
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
type TimeZoneType =
|
|
209
|
+
| 'Africa/Abidjan'
|
|
210
|
+
| 'America/New_York'
|
|
211
|
+
| 'Asia/Tokyo'
|
|
212
|
+
| 'Europe/Paris'
|
|
213
|
+
| /* ... */ ;
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Example:**
|
|
217
|
+
```typescript
|
|
218
|
+
import type { TimeZoneType } from '@ooneex/country';
|
|
219
|
+
|
|
220
|
+
const tz: TimeZoneType = 'Europe/London'; // ✓ Valid
|
|
221
|
+
const invalid: TimeZoneType = 'Invalid/Zone'; // ✗ TypeScript error
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Interfaces
|
|
225
|
+
|
|
226
|
+
#### `ICountry`
|
|
227
|
+
|
|
228
|
+
Interface for country entities extending the base interface.
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
interface ICountry extends IBase {
|
|
232
|
+
name: string;
|
|
233
|
+
code: string;
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Properties:**
|
|
238
|
+
- `id` - Unique identifier (from IBase)
|
|
239
|
+
- `name` - Country name
|
|
240
|
+
- `code` - ISO 3166-1 alpha-2 country code
|
|
241
|
+
- `createdAt` - Creation timestamp (from IBase)
|
|
242
|
+
- `updatedAt` - Update timestamp (from IBase)
|
|
243
|
+
|
|
244
|
+
## Module Exports
|
|
245
|
+
|
|
246
|
+
### Main Export (`@ooneex/country`)
|
|
247
|
+
|
|
248
|
+
- English country names
|
|
249
|
+
- All type definitions
|
|
250
|
+
- Timezone types
|
|
251
|
+
|
|
252
|
+
### French Export (`@ooneex/country/fr`)
|
|
253
|
+
|
|
254
|
+
- French localized country names
|
|
255
|
+
- Same structure as main export
|
|
256
|
+
|
|
257
|
+
### Romanian Export (`@ooneex/country/ro`)
|
|
258
|
+
|
|
259
|
+
- Romanian localized country names
|
|
260
|
+
- Same structure as main export
|
|
261
|
+
|
|
262
|
+
## Advanced Usage
|
|
263
|
+
|
|
264
|
+
### Multi-Language Country Selector
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { COUNTRIES as COUNTRIES_EN } from '@ooneex/country';
|
|
268
|
+
import { COUNTRIES as COUNTRIES_FR } from '@ooneex/country/fr';
|
|
269
|
+
import { COUNTRIES as COUNTRIES_RO } from '@ooneex/country/ro';
|
|
270
|
+
import type { CountryType, LocaleType } from '@ooneex/country';
|
|
271
|
+
|
|
272
|
+
const countryLists = {
|
|
273
|
+
en: COUNTRIES_EN,
|
|
274
|
+
fr: COUNTRIES_FR,
|
|
275
|
+
ro: COUNTRIES_RO
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
function getCountryName(code: CountryType, locale: 'en' | 'fr' | 'ro'): string {
|
|
279
|
+
const countries = countryLists[locale];
|
|
280
|
+
const country = countries.find(c => c.code === code);
|
|
281
|
+
return country?.name ?? code;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
console.log(getCountryName('DE', 'en')); // "Germany"
|
|
285
|
+
console.log(getCountryName('DE', 'fr')); // "Allemagne"
|
|
286
|
+
console.log(getCountryName('DE', 'ro')); // "Germania"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Timezone Utilities
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import type { TimeZoneType } from '@ooneex/country';
|
|
293
|
+
|
|
294
|
+
function formatInTimezone(date: Date, timezone: TimeZoneType): string {
|
|
295
|
+
return new Intl.DateTimeFormat('en-US', {
|
|
296
|
+
timeZone: timezone,
|
|
297
|
+
year: 'numeric',
|
|
298
|
+
month: 'long',
|
|
299
|
+
day: 'numeric',
|
|
300
|
+
hour: '2-digit',
|
|
301
|
+
minute: '2-digit',
|
|
302
|
+
timeZoneName: 'short'
|
|
303
|
+
}).format(date);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const now = new Date();
|
|
307
|
+
console.log(formatInTimezone(now, 'America/Los_Angeles'));
|
|
308
|
+
console.log(formatInTimezone(now, 'Europe/Paris'));
|
|
309
|
+
console.log(formatInTimezone(now, 'Asia/Tokyo'));
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Country Code Validation
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import { COUNTRIES } from '@ooneex/country';
|
|
316
|
+
import type { CountryType } from '@ooneex/country';
|
|
317
|
+
|
|
318
|
+
function isValidCountryCode(code: string): code is CountryType {
|
|
319
|
+
return COUNTRIES.some(country => country.code === code);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const input = 'US';
|
|
323
|
+
|
|
324
|
+
if (isValidCountryCode(input)) {
|
|
325
|
+
// TypeScript knows `input` is CountryType here
|
|
326
|
+
const country = COUNTRIES.find(c => c.code === input);
|
|
327
|
+
console.log(country?.name);
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Integration with Forms
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { COUNTRIES } from '@ooneex/country';
|
|
335
|
+
import type { CountryType } from '@ooneex/country';
|
|
336
|
+
|
|
337
|
+
interface AddressForm {
|
|
338
|
+
street: string;
|
|
339
|
+
city: string;
|
|
340
|
+
postalCode: string;
|
|
341
|
+
country: CountryType;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function validateAddress(form: AddressForm): boolean {
|
|
345
|
+
const validCountry = COUNTRIES.some(c => c.code === form.country);
|
|
346
|
+
|
|
347
|
+
if (!validCountry) {
|
|
348
|
+
throw new Error('Invalid country code');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Cron Job with Timezone
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import { Cron, type CronTimeType } from '@ooneex/cron';
|
|
359
|
+
import type { TimeZoneType } from '@ooneex/country';
|
|
360
|
+
|
|
361
|
+
class DailyReportCron extends Cron {
|
|
362
|
+
public getTime(): CronTimeType {
|
|
363
|
+
return 'every 24 hours';
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
public getTimeZone(): TimeZoneType {
|
|
367
|
+
return 'Europe/Paris'; // Run at Paris time
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
public async job(): Promise<void> {
|
|
371
|
+
await this.generateReport();
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## License
|
|
377
|
+
|
|
378
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
379
|
+
|
|
380
|
+
## Contributing
|
|
381
|
+
|
|
382
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
383
|
+
|
|
384
|
+
### Development Setup
|
|
385
|
+
|
|
386
|
+
1. Clone the repository
|
|
387
|
+
2. Install dependencies: `bun install`
|
|
388
|
+
3. Run tests: `bun run test`
|
|
389
|
+
4. Build the project: `bun run build`
|
|
390
|
+
|
|
391
|
+
### Guidelines
|
|
392
|
+
|
|
393
|
+
- Write tests for new features
|
|
394
|
+
- Follow the existing code style
|
|
395
|
+
- Update documentation for API changes
|
|
396
|
+
- Ensure all tests pass before submitting PR
|
|
397
|
+
- Add new localizations following the existing pattern
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
Made with ❤️ by the Ooneex team
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IBase } from "@ooneex/types";
|
|
2
|
+
import { TimeZone } from "@vvo/tzdb";
|
|
1
3
|
declare const COUNTRIES: readonly [{
|
|
2
4
|
readonly name: "Afghanistan";
|
|
3
5
|
readonly code: "AF";
|
|
@@ -688,4 +690,9 @@ declare const COUNTRIES: readonly [{
|
|
|
688
690
|
}];
|
|
689
691
|
type CountryType = (typeof COUNTRIES)[number]["code"];
|
|
690
692
|
type CountryNameType = (typeof COUNTRIES)[number]["name"];
|
|
691
|
-
|
|
693
|
+
type TimeZoneType = TimeZone["name"];
|
|
694
|
+
interface ICountry extends IBase {
|
|
695
|
+
name: string;
|
|
696
|
+
code: string;
|
|
697
|
+
}
|
|
698
|
+
export { TimeZoneType, ICountry, CountryType, CountryNameType };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/country",
|
|
3
|
-
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
3
|
+
"description": "Country data utilities with timezone support and multi-language localization (French, Romanian)",
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -36,11 +36,23 @@
|
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "bunup",
|
|
38
38
|
"lint": "tsgo --noEmit && bunx biome lint",
|
|
39
|
-
"publish
|
|
40
|
-
"
|
|
41
|
-
"publish:dry": "bun publish --dry-run"
|
|
39
|
+
"publish": "bun publish --access public || true",
|
|
40
|
+
"test": "bun test tests"
|
|
42
41
|
},
|
|
43
|
-
"dependencies": {
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@vvo/tzdb": "^6.198.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@ooneex/types": "0.0.1"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"bun",
|
|
50
|
+
"countries",
|
|
51
|
+
"country",
|
|
52
|
+
"i18n",
|
|
53
|
+
"locale",
|
|
54
|
+
"ooneex",
|
|
55
|
+
"timezone",
|
|
56
|
+
"typescript"
|
|
57
|
+
]
|
|
46
58
|
}
|
|
Binary file
|