kenya-locations
Version:
A comprehensive and intuitive TypeScript package for working with Kenyan administrative divisions (counties, sub-counties, constituencies, and wards)
495 lines (369 loc) ⢠13.8 kB
Markdown
# š°šŖ Kenya Locations
A comprehensive and intuitive TypeScript package for working with Kenyan administrative divisions
including the complete hierarchy: **Counties ā Localities ā Areas**, plus sub-counties,
constituencies, and wards.
## Author
**David Amunga**
Website: [https://davidamunga.com](https://davidamunga.com)
## Features
- šļø **Complete Administrative Hierarchy** - County ā Locality ā Area with sub-counties,
constituencies, and wards
- š **Intuitive chainable API** for navigating Kenya's administrative hierarchy
- š **Fuzzy search** capabilities across all administrative levels (counties, localities, areas,
constituencies, wards, sub-counties)
- š§© **TypeScript support** with full type definitions
- š **Lightning-fast performance** with optimized Maps and pre-computed relationships
- š **Complete data** for all 47 counties, their localities, areas, sub-counties, constituencies,
and wards
- š± **Lightweight** with minimal dependencies
- š **Well-documented** API with examples
- ā
**Well-tested** with comprehensive unit tests
## Installation
```bash
npm install kenya-locations
```
## Hierarchy
The library supports the complete Kenyan administrative hierarchy:
```
County (47 counties)
āāā Locality (e.g., Westlands, Embakasi)
ā āāā Area (e.g., Gigiri, Karen C)
āāā Sub-County
āāā Constituency (e.g., Westlands)
ā āāā Ward (e.g., Mountain View)
```
## Usage
### Basic Usage
You can use the standalone functions directly:
```typescript
import {
getCounties,
county,
getConstituencies,
getConstituencyByCode,
getWards,
getWardsInCounty,
getCountyOfWard,
search,
getSubCounties,
getSubCountiesInCounty,
getCountyOfSubCounty,
getWardsInSubCounty,
getLocalities,
getAreas,
getLocalityByName,
getAreaByName,
getLocalitiesInCounty,
getAreasInLocality,
getAreasInCounty,
getCountyOfLocality,
getCountyOfArea,
getLocalityOfArea,
locality,
} from "kenya-locations";
// Get all counties
const allCounties = getCounties();
// Get a specific county by name or code
const mombasa = county("Mombasa"); // or county('001')
// Get all constituencies
const constituencies = getConstituencies();
// Get a specific constituency by code
const changamwe = getConstituencyByCode("290");
// Access county information directly from constituency
console.log(changamwe?.county.name); // "Mombasa"
console.log(changamwe?.county.code); // "001"
// Get all wards
const wards = getWards();
// Get all wards in a county
const wardsInMombasa = getWardsInCounty("001");
// Get the county a ward belongs to
const wardCounty = getCountyOfWard("0001");
// Get all sub-counties
const allSubCounties = getSubCounties();
// Get all sub-counties in a county (supports both name and code)
const subCountiesInMombasa = getSubCountiesInCounty("Mombasa"); // by name
const subCountiesInMombasaByCode = getSubCountiesInCounty("001"); // by code
// Get the county a sub-county belongs to
const subCountyCounty = getCountyOfSubCounty("subCountyName");
// Get all wards in a sub-county
const wardsInSubCounty = getWardsInSubCounty("subCountyCode");
```
### Working with Localities and Areas
```typescript
import {
getLocalities,
getAreas,
getLocalityByName,
getAreaByName,
getLocalitiesInCounty,
getAreasInLocality,
getAreasInCounty,
getCountyOfLocality,
getCountyOfArea,
getLocalityOfArea,
locality,
} from "kenya-locations";
// Get all localities
const allLocalities = getLocalities();
// Get all areas
const allAreas = getAreas();
// Get a specific locality by name
const westlands = getLocalityByName("Westlands");
console.log(westlands?.county); // "Nairobi"
// Get a specific area by name
const gigiri = getAreaByName("Gigiri");
console.log(gigiri?.locality); // "Westlands"
console.log(gigiri?.county); // "Nairobi"
// Get all localities in a county
const nairobiLocalities = getLocalitiesInCounty("Nairobi");
// Get all areas in a locality
const westlandsAreas = getAreasInLocality("Westlands");
// Get all areas in a county
const nairobiAreas = getAreasInCounty("Nairobi");
// Find parent entities
const areaCounty = getCountyOfArea("Gigiri"); // County object
const areaLocality = getLocalityOfArea("Gigiri"); // Locality object
const localityCounty = getCountyOfLocality("Westlands"); // County object
// Get locality with optional county filter
const westlandsInNairobi = locality("Westlands", "Nairobi");
const anyWestlands = locality("Westlands"); // First match
```
### Chainable API
The package provides a chainable API for navigating the administrative hierarchy:
```typescript
import { county, getLocalityByName } from "kenya-locations";
// Working with Counties
const nairobi = county("Nairobi");
// Get constituencies in a county
const constituencies = nairobi?.constituencies();
// Get a specific constituency in a county
const westlands = nairobi?.constituency("Westlands");
// Get localities in a county
const localities = nairobi?.localities();
// Get a specific locality in a county
const embakasi = nairobi?.locality("Embakasi");
// Get areas in a county
const areas = nairobi?.areas();
// Get areas in a specific locality within a county
const westlandsAreas = nairobi?.areasByLocality("Westlands");
// Access county information directly from constituency
console.log(westlands?.county.name); // "Nairobi"
console.log(westlands?.county.code); // "047"
// Get wards in a constituency
const wards = westlands?.wards();
// Get a specific ward in a constituency
const ward = westlands?.ward("Mountain View");
// Working with Localities
const westlandsLocality = getLocalityByName("Westlands");
// Get all areas in this locality
const areas = westlandsLocality?.areas();
// Get a specific area in the locality
const gigiri = westlandsLocality?.area("Gigiri");
// Get the county this locality belongs to
const county = westlandsLocality?.getCounty();
```
### Search Functionality
The package includes a powerful fuzzy search feature that works across all administrative levels:
```typescript
import { search } from "kenya-locations";
// Search across all administrative levels
const results = search("Westlands");
/*
Results include:
[
{ type: 'locality', item: { name: 'Westlands', county: 'Nairobi' } },
{ type: 'constituency', item: { code: '290', name: 'Westlands', county: { code: '047', name: 'Nairobi' } } },
{ type: 'area', item: { name: 'Gigiri', locality: 'Westlands', county: 'Nairobi' } },
// ... more results
]
*/
// Search for areas
const areaResults = search("Gigiri");
/*
Results:
[
{ type: 'area', item: { name: 'Gigiri', locality: 'Westlands', county: 'Nairobi' } }
]
*/
// Search with limit
const limitedResults = search("Nairobi", 5); // Maximum 5 results
// Search handles typos and partial matches
const typoResults = search("Nairob"); // Still finds Nairobi-related locations
```
### Complete Hierarchy Navigation Example
```typescript
import { county, getAreaByName, getLocalityOfArea, getCountyOfArea } from "kenya-locations";
// Start from county and drill down
const nairobi = county("Nairobi");
const westlands = nairobi?.locality("Westlands");
const gigiri = westlands?.area("Gigiri");
console.log(`Found: ${gigiri.name} in ${gigiri.locality}, ${gigiri.county}`);
// Start from area and go up the hierarchy
const area = getAreaByName("Gigiri");
const locality = getLocalityOfArea("Gigiri");
const county = getCountyOfArea("Gigiri");
console.log(`Hierarchy: ${county?.name} ā ${locality?.name} ā ${area?.name}`);
// Output: "Hierarchy: Nairobi ā Westlands ā Gigiri"
```
### Error Handling
```typescript
import { county, getLocalityByName, NotFoundError } from "kenya-locations";
try {
const nairobi = county("Nairobi");
const locality = nairobi?.locality("NonExistentLocality");
} catch (error) {
if (error instanceof NotFoundError) {
console.log("Locality not found:", error.message);
}
}
try {
const westlands = getLocalityByName("Westlands");
const area = westlands?.area("NonExistentArea");
} catch (error) {
if (error instanceof NotFoundError) {
console.log("Area not found:", error.message);
}
}
```
## Examples
The package includes comprehensive examples:
- `examples/basic-usage.html`: A complete interactive example showing all functionality including
the County ā Locality ā Area hierarchy
- All functions demonstrated with working code
- Search functionality across all administrative levels
To run the examples:
```bash
# Clone the repository
git clone https://github.com/DavidAmunga/kenya-locations.git
# Navigate to the project
cd kenya-locations
# Install dependencies
npm install
# Build the library
npm run build
# Open examples/basic-usage.html in your browser
```
## API Reference
### Main Functions
#### Counties
- `getCounties()`: Get all counties
- `county(nameOrCode)`: Get a county by name or code
#### Localities
- `getLocalities()`: Get all localities
- `getLocalityByName(name)`: Get a locality by name
- `getLocalitiesInCounty(countyName)`: Get all localities in a county
- `getCountyOfLocality(localityName)`: Get the county a locality belongs to
- `locality(name, countyName?)`: Get a locality by name, optionally filtered by county
#### Areas
- `getAreas()`: Get all areas
- `getAreaByName(name)`: Get an area by name
- `getAreasInLocality(localityName)`: Get all areas in a locality
- `getAreasInCounty(countyName)`: Get all areas in a county
- `getCountyOfArea(areaName)`: Get the county an area belongs to
- `getLocalityOfArea(areaName)`: Get the locality an area belongs to
#### Constituencies
- `getConstituencies()`: Get all constituencies
- `getConstituencyByCode(code)`: Get a constituency by code
- `getCountyOfConstituency(constituencyCode)`: Get the county a constituency belongs to
#### Wards
- `getWards()`: Get all wards
- `getWardsInCounty(countyNameOrCode)`: Get all wards in a county
- `getWardsInConstituency(constituencyCode)`: Get all wards in a constituency
- `getCountyOfWard(wardCode)`: Get the county a ward belongs to
#### Sub-Counties
- `getSubCounties()`: Get all sub-counties
- `getSubCountiesInCounty(countyNameOrCode)`: Get all sub-counties in a county
- `getCountyOfSubCounty(subCountyName)`: Get the county a sub-county belongs to
- `getWardsInSubCounty(subCountyCode)`: Get all wards in a sub-county
#### Search
- `search(query, limit?)`: Search across all administrative levels (counties, localities, areas,
constituencies, wards, sub-counties)
### Wrapper Classes
#### CountyWrapper Class
- `code`: Get the county code
- `name`: Get the county name
- `data`: Get all data for the county
- `constituencies()`: Get all constituencies in this county
- `constituency(nameOrCode)`: Get a constituency by name or code
- `localities()`: Get all localities in this county
- `locality(name)`: Get a locality by name
- `areas()`: Get all areas in this county
- `areasByLocality(localityName)`: Get areas in a specific locality
- `wards()`: Get all wards in this county
#### ConstituencyWrapper Class
- `code`: Get the constituency code
- `name`: Get the constituency name
- `county`: Get the county object this constituency belongs to (contains code and name)
- `data`: Get all data for the constituency
- `getCounty()`: Get the county this constituency belongs to as a CountyWrapper
- `wards()`: Get all wards in this constituency
- `ward(nameOrCode)`: Get a ward by name or code
#### LocalityWrapper Class
- `name`: Get the locality name
- `county`: Get the county name this locality belongs to
- `data`: Get all data for the locality
- `getCounty()`: Get the county this locality belongs to as a CountyWrapper
- `areas()`: Get all areas in this locality
- `area(name)`: Get an area by name
### Data Interfaces
```typescript
interface County {
code: string;
name: string;
}
interface Locality {
name: string;
county: string;
}
interface Area {
name: string;
locality: string;
county: string;
}
interface Constituency {
code: string;
name: string;
county: County;
}
interface Ward {
code: string;
name: string;
constituencyCode: string;
}
interface SubCounty {
code: string;
name: string;
county: string;
}
interface SearchResult {
type: "county" | "constituency" | "ward" | "sub-county" | "locality" | "area";
item: County | Constituency | Ward | SubCounty | Locality | Area;
}
```
## Contributing
Contributions are welcome! We especially welcome contributions to expand our locality and area data.
š **[Read our detailed Contributing Guidelines](CONTRIBUTING.md)** for information on:
- How to add new counties, sub-counties, constituencies, wards, localities, and areas
- Data structure and validation requirements
- Testing procedures
- Submission guidelines
šŖ **Pre-commit Hooks**: This project uses automated pre-commit hooks to ensure code quality and
data integrity. When you commit changes, the following happen automatically:
- Code formatting and linting
- Data validation (when data files are changed)
- Test execution
- Commit message format validation
š **Learn More**: See [Pre-commit Hooks Documentation](docs/PRE_COMMIT_HOOKS.md) for detailed
information.
Please feel free to submit a Pull Request following our guidelines.
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Data Sources
The data in this package is sourced from official records of:
- Independent Electoral and Boundaries Commission (IEBC) of Kenya
- Kenya National Bureau of Statistics (KNBS)
- County government records for locality and area classifications
## Acknowledgments
- The Independent Electoral and Boundaries Commission (IEBC) of Kenya
- Kenya National Bureau of Statistics (KNBS)
- County governments for locality and area data