@windingtree/wt-search-api
Version:
NodeJS app that enables quick search over data from Winding Tree platform
66 lines (61 loc) • 1.73 kB
JavaScript
const { QueryParseError } = require('../errors');
const MAX_DISTANCE = 200; // Disallow large distances as they break the approximation.
/**
* Extract location query from the params.
*
* @param {Object} query request GET params
* @return {Array}
* @throw QueryParseError
*
*/
function getFilter (filters) {
if (!(filters instanceof Array)) {
filters = [filters];
}
return filters.map((filter) => {
let [coords, distance] = filter.split(':'),
[lat, lng] = coords.split(',');
[distance, lat, lng] = [distance, lat, lng].map((x) => Number(x));
if ((isNaN(distance) || isNaN(lat) || isNaN(lng)) ||
(lat < -90 || lat > 90) ||
(lng < -180 || lng > 180) ||
(distance < 0)) {
throw new QueryParseError(`Invalid location filter ${filter}.`);
}
if (distance > MAX_DISTANCE) {
throw new QueryParseError(`Maximum allowed distance in a filter is ${MAX_DISTANCE} km`);
}
return {
type: 'location',
condition: { lat: lat, lng: lng, distance: distance },
};
});
}
/**
* Extract location query from the params.
*
* @param {Object} query request GET params
* @return {Object}
* @throw QueryParseError
*
*/
function getSort (sort) {
if (sort instanceof Array) {
throw new QueryParseError('Only one distance-based sort can be specified at once.');
}
const [lat, lng] = sort.split(',').map((x) => Number(x));
if ((isNaN(lat) || isNaN(lng)) ||
(lat < -90 || lat > 90) ||
(lng < -180 || lng > 180)) {
throw new QueryParseError(`Invalid sorting criteria: ${sort}.`);
}
return {
type: 'distance',
data: { lat: lat, lng: lng },
};
}
module.exports = {
getFilter,
getSort,
MAX_DISTANCE,
};