90 lines
2.8 KiB
JavaScript
90 lines
2.8 KiB
JavaScript
class QueryParser {
|
|
constructor(options) {
|
|
this._commands = options.commands;
|
|
this._searchDelimiter = options.searchDelimiter;
|
|
this._pathDelimiter = options.pathDelimiter;
|
|
this._protocolRegex = /^[a-zA-Z]+:\/\//i;
|
|
this._urlRegex = /^((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)$/i;
|
|
this.parse = this.parse.bind(this);
|
|
}
|
|
|
|
parse(query) {
|
|
const res = { query: query, split: null };
|
|
|
|
if (this._urlRegex.test(query)) {
|
|
const hasProtocol = this._protocolRegex.test(query);
|
|
res.redirect = hasProtocol ? query : 'http://' + query;
|
|
} else {
|
|
const trimmed = query.trim();
|
|
const splitSearch = trimmed.split(this._searchDelimiter);
|
|
const splitPath = trimmed.split(this._pathDelimiter);
|
|
|
|
this._commands.some(({ category, key, name, search, url }) => {
|
|
if (query === key) {
|
|
res.key = key;
|
|
res.isKey = true;
|
|
res.redirect = url;
|
|
return true;
|
|
}
|
|
|
|
if (splitSearch[0] === key && search) {
|
|
res.key = key;
|
|
res.isSearch = true;
|
|
res.split = this._searchDelimiter;
|
|
res.query = QueryParser._shiftAndTrim(splitSearch, res.split);
|
|
res.redirect = QueryParser._prepSearch(url, search, res.query);
|
|
return true;
|
|
}
|
|
|
|
if (splitPath[0] === key) {
|
|
res.key = key;
|
|
res.isPath = true;
|
|
res.split = this._pathDelimiter;
|
|
res.path = QueryParser._shiftAndTrim(splitPath, res.split);
|
|
res.redirect = QueryParser._prepPath(url, res.path);
|
|
return true;
|
|
}
|
|
|
|
if (key === '*') {
|
|
res.redirect = QueryParser._prepSearch(url, search, query);
|
|
}
|
|
});
|
|
}
|
|
|
|
res.color = QueryParser._getColorFromUrl(this._commands, res.redirect);
|
|
return res;
|
|
}
|
|
|
|
static _getColorFromUrl(commands, url) {
|
|
const domain = new URL(url).hostname;
|
|
|
|
return (
|
|
commands
|
|
.filter(c => new URL(c.url).hostname.includes(domain))
|
|
.map(c => c.color)[0] || null
|
|
);
|
|
}
|
|
|
|
static _prepPath(url, path) {
|
|
return QueryParser._stripUrlPath(url) + '/' + path;
|
|
}
|
|
|
|
static _prepSearch(url, searchPath, query) {
|
|
if (!searchPath) return url;
|
|
const baseUrl = QueryParser._stripUrlPath(url);
|
|
const urlQuery = encodeURIComponent(query);
|
|
searchPath = searchPath.replace('{}', urlQuery);
|
|
return baseUrl + searchPath;
|
|
}
|
|
|
|
static _shiftAndTrim(arr, delimiter) {
|
|
arr.shift();
|
|
return arr.join(delimiter).trim();
|
|
}
|
|
|
|
static _stripUrlPath(url) {
|
|
const parser = document.createElement('a');
|
|
parser.href = url;
|
|
return `${parser.protocol}//${parser.hostname}`;
|
|
}
|
|
} |