Skip to content

930m310n/typescript

Repository files navigation

Geomelon TypeScript Client

TypeScript/JavaScript client for the Geomelon API — a read-only geospatial database of cities, countries, regions, and languages with multilingual support.

Available on RapidAPI. Looking for other ways to integrate? See all official libraries at geomelon.dev/libraries.

The oneshot prefix search is free and requires no API key.

Installation

npm install geomelon

Requirements

  • Node.js 18+ (uses native fetch)
  • A RapidAPI key with access to the Geomelon API

Quick start

import { GeomelonClient } from 'geomelon';

const geo = new GeomelonClient({ apiKey: 'YOUR_RAPIDAPI_KEY' });

// Find cities near a point
const cities = await geo.cities.byCoordinatesClosest({ lat: 41.38, lon: 2.18 });
console.log(cities[0].name); // "Barcelona"

// Search cities by name with language preference
const results = await geo.cities.search({ name: 'tokyo', preferredLanguages: 'ja' });
console.log(results[0].localizedName); // "東京"

CommonJS:

const { GeomelonClient } = require('geomelon');
const geo = new GeomelonClient({ apiKey: 'YOUR_RAPIDAPI_KEY' });

Browser (no build step), via unpkg/jsDelivr — exposes a global Geomelon:

<script src="https://unpkg.com/geomelon/dist/umd/geomelon.min.js"></script>
<script>
  const geo = new Geomelon.GeomelonClient();
  geo.oneshot.search('es', 'es', 'bar').then((cities) => console.log(cities[0].name));
</script>

No API key? Skip apiKey entirely — oneshot search works keyless, every other method throws a GeomelonError telling you to configure one:

const geo = new GeomelonClient();
const cities = await geo.oneshot.search('es', 'es', 'bar'); // works, no signup
await geo.cities.search({ name: 'barc' }); // throws GeomelonError

Configuration

const geo = new GeomelonClient({
  apiKey: 'YOUR_RAPIDAPI_KEY', // optional — omit for keyless oneshot-only mode
  host: 'geomelon.p.rapidapi.com', // optional, override for custom gateway
  freeOneshot: false, // route oneshot to the free keyless host even with an apiKey set
  retries: 0, // retry 429/5xx/network errors this many times with exponential backoff
  timeoutMs: undefined, // default per-request timeout in ms
});

Every method also takes an optional last argument { signal, timeoutMs } to override the timeout or cancel a single call with an AbortController:

const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
await geo.cities.search({ name: 'barc' }, { signal: controller.signal });

API reference

Cities

// Search with filters and pagination
geo.cities.search({
  name: 'paris',          // prefix search (also matches translations)
  countryCode: 'FR',      // ISO 3166-1 alpha-2, case-insensitive
  regionId: 'uuid',
  minPopulation: 100000,
  maxPopulation: 5000000,
  sort: 'population_desc', // population_desc | population_asc | name_asc | name_desc
  preferredLanguages: 'fr,en', // comma-separated, priority order
  limit: 20,
  offset: 0,
})

// Get city by ID
geo.cities.get('964512d1-f150-4876-87ec-0ba47aef694a')

// All translations for a city
geo.cities.translations('964512d1-f150-4876-87ec-0ba47aef694a')

// Settlement types (city, municipality, etc.)
geo.cities.settlementTypes('964512d1-f150-4876-87ec-0ba47aef694a')

// Distance between two cities
geo.cities.distance('uuid-city1', 'uuid-city2') // → { distanceKm: 504.7 }

// Nearest cities to a coordinate
geo.cities.byCoordinatesClosest({ lat: 41.38, lon: 2.18, preferredLanguages: 'en' })

// Most populated cities near a coordinate
geo.cities.byCoordinatesLargest({ lat: 41.38, lon: 2.18, preferredLanguages: 'en' })

Countries

// List countries with optional filters
geo.countries.list({ limit: 200, offset: 0 })
geo.countries.list({ name: 'Spa', preferredLanguages: 'es,en' }) // prefix search
geo.countries.list({ telephoneCode: '+34' })

// Get country by ID (includes embedded translations and regions)
geo.countries.get('a1e06cc1-817c-429f-84f4-6ab51dac9bfa')

// Translations for a country
geo.countries.translations('uuid', { preferredLanguages: 'fr,de' })

// Regions within a country
geo.countries.regions('uuid')

Regions

// List regions, optionally filtered by country
geo.regions.list({ countryId: 'uuid' })

// Get region by ID (includes nested country)
geo.regions.get('dde1e1c6-ca22-48e6-8ad7-f97b141c1929')

// Translations for a region
geo.regions.translations('uuid', { preferredLanguages: 'ca,fr' })

Languages

// List languages sorted by city coverage
geo.languages.list({ limit: 50, offset: 0 })

// Get language by ID
geo.languages.get('08cb6cd7-7c3e-4058-a34a-405052db63ec')

Oneshot prefix search

Free & no API key required. Oneshot is served as static files — no RapidAPI subscription needed.

Fast country-scoped, language-specific city prefix search backed by pre-built static files. Returns up to 10 cities sorted by population, with the requested language name and an optional English fallback.

// Cities in Spain whose Spanish name starts with "bar"
geo.oneshot.search('es', 'es', 'bar')
// → [{ id, name: "Barcelona", population: 1636762, emoji: "🇪🇸", en: "Barcelona" }, ...]

// Cities in Spain whose Catalan name starts with "bar"
geo.oneshot.search('es', 'ca', 'bar')

en is omitted when the requested language is English or no English translation exists. See the Free Autocomplete API section for supported country/language pairs.

Response types

All types are exported for use in TypeScript projects:

import type {
  CityDto,
  CountryDto,
  CountryExtendedDto,
  RegionDto,
  RegionExtendedDto,
  LanguageDto,
  DistanceDto,
  OneshotCityDto,
  SearchCitiesParams,
  // ... all param and response types
} from 'geomelon';

Error handling

The client throws a GeomelonError (extends Error) for non-2xx responses, network failures, timeouts, and missing-API-key calls:

import { GeomelonError } from 'geomelon';

try {
  const city = await geo.cities.get('non-existent-id');
} catch (err) {
  if (err instanceof GeomelonError) {
    err.status;        // 404 (undefined for network/timeout/config errors)
    err.body;           // '{"message":"City non-existent-id not found"}'
    err.isRateLimited;  // true only when status === 429
  }
}

Build

npm install
npm run build       # outputs dist/cjs/, dist/esm/, and dist/umd/
npm test            # runs the unit test suite (node:test, mocked fetch)
npm run check:openapi  # verifies src/types.ts has no fields missing vs. the published OpenAPI spec

About

TypeScript client for the Geomelon API — cities, countries, regions, and languages with multilingual support

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors