geocoder-opencagedata
Version:
An OpenCageData geocoder API client that supports caching and is written on typescript
85 lines (84 loc) • 3.31 kB
JavaScript
;
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 : '';
}
}