UNPKG

geocoder-opencagedata

Version:

An OpenCageData geocoder API client that supports caching and is written on typescript

85 lines (84 loc) 3.31 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.geocoder = exports.Geocoder = void 0; const node_fetch_1 = __importDefault(require("node-fetch")); const pace_keeper_1 = require("pace-keeper"); const ENV_API_URL = 'OCD_API_URL'; const ENV_API_KEY = 'OCD_API_KEY'; const PACE_INTERVAL = 1000; const PACE_LIMIT = 1; const DEFAULT_API_URL = "https://api.opencagedata.com/geocode/v1/json"; const DEFAULT_QUERY = { q: '', limit: 1, pretty: 0, no_annotations: 1 }; const CACHE = {}; class Geocoder { constructor({ api_key, api_url, pace_limit, cached } = { cached: true }) { Object.defineProperty(this, 'API_KEY', { enumerable: false, writable: false, value: api_key || process.env[ENV_API_KEY] }); this.API_URL = api_url || process.env[ENV_API_URL] || DEFAULT_API_URL; this.pace = new pace_keeper_1.Pacekeeper({ interval: PACE_INTERVAL, pace: pace_limit || PACE_LIMIT, parse_429: true }); this.cached = cached === undefined ? true : !!cached; } geocode(query) { let q = Object.assign(DEFAULT_QUERY, { key: this.API_KEY }, typeof query === 'string' ? { q: query.trim() } : query); let url = `${this.API_URL}?${Object.keys(q).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(q[key])}`).join('&')}`; if (this.cached) { let cached = CACHE[url.toLowerCase()]; if (cached) return Promise.resolve(cached); } return this.pace .submit(() => node_fetch_1.default(url)).promise .then(res => typeof (res === null || res === void 0 ? void 0 : res.json) === 'function' ? res.json().then(this.cached ? cache_result(url) : build_result) : build_error(res)); } } exports.Geocoder = Geocoder; exports.default = Geocoder; class geocoder extends Geocoder { } //backward compatibility with versions prior to 1.4.0 exports.geocoder = geocoder; function cache_result(url) { return function (res) { let result = new GeoResult(res); if (url && typeof url === 'string') { CACHE[url.toLowerCase()] = result; } return result; }; } function build_result(res) { return new GeoResult(res); } function build_error(res) { return new GeoResult({ status: { code: res === null || res === void 0 ? void 0 : res.status, message: res === null || res === void 0 ? void 0 : res.statusText } }); } class GeoResult { constructor(data) { Object.assign(this, data); } get ok() { var _a; return ((_a = this.status) === null || _a === void 0 ? void 0 : _a.code) === 200 && (this.total_results ? this.total_results > 0 : false); } get geo() { return this.ok && Array.isArray(this.results) && this.results.length > 0 ? this.results[0].geometry : { lat: void 0, lng: void 0 }; } get address() { return this.ok && Array.isArray(this.results) && this.results.length > 0 ? this.results[0].formatted : ''; } }