adamocomp/parser.js

275 lines
6.6 KiB
JavaScript
Raw Normal View History

2020-05-21 12:08:44 +00:00
'use strict';
const fs = require('fs');
function Parser(options) {
var self = this;
options = options || {};
function debug(message) {
if (self.params.debug_mode) {
console.log(`[DEBUG] ${message}`);
}
}
this.defaults = {
path : './data.json',
query_delim : '/',
debug_mode : false
}
this.params = Object.assign({}, self.defaults, options);
this.data = null;
this.test = {
'valid_deal' : function(query) {
return self.get.deals(query)
.then(function(data) {
if (query == "") return false;
if (data.length > 0) {
return true;
}
return false;
})
},
'valid_cluster' : function(query) {
return self.test.has_hosts(query)
},
'valid_host' : function(query) {
return self.test.has_hosts(query)
},
'has_hosts' : function(query) {
return self.get.hosts(query)
.then(host_list => {
if (query == "") return false;
debug("Host list: "+host_list);
if (host_list.length > 0) {
return true;
}
return false;
})
},
'is_object' : function(obj) {
return (typeof obj === 'object' && obj !== null);
}
}
this.xform = {
'query_str_to_arr' : function(str = "") {
if (!str || str == "" || str == '') {
debug("Transforming empty search string.");
return [];
}
var arr = str.split(self.params.query_delim);
var split_str=""
arr.forEach(term => {
split_str = split_str + " " + term;
})
arr = split_str.split(" ");
arr = arr.filter(term => term != '.');
arr = arr.filter(term => term != '');
debug("Query arr: "+arr);
return arr;
}
}
this.reduce = {
'once' : function(data = {},name = "") {
const addressed = self.address(data,[...name]);
return addressed.data;
},
'fuzzy' : function(data = {},names = []) {
if (!Array.isArray(names) || names.length < 1) {
return data;
}
var name = names.shift();
var result = self.reduce.once(data,name);
names.forEach(name => { result = [...result.map(tree => {
const matches = self.reduce.once(tree,name)
debug(matches);
return matches;
})]})
result.filter(obj => obj);
return result;
},
'exact' : function(data = {},names = []) {
if (!Array.isArray(names) || names.length < 1) {
return data;
}
const addressed = self.address(data,names);
debug("Reduced exact data: "+addressed);
return addressed.data;
}
}
this.address = function(data = {},names = []) {
if (!names || names.length < 1 || !data || data == {}) {
debug("nope");
return { paths: [['.']], data: [data] };
}
var match_paths = new Array();
var match_data = new Array();
var branches = new Array({
root: ".",
data: data
});
for(var i=0; i < branches.length; i++) {
const data = branches[i].data;
const root = branches[i].root;
for (const [name,value] of Object.entries(data)) {
if (self.test.is_object(value)) {
branches.push({
root: [...root,name],
data: value
});
}
if (name == names[0]) {
var match = data;
names.forEach(term => {
debug("Searching for term: "+term);
if (match && match[term]) {
match = match[term];
}
else { match = undefined }
});
if (match) {
const match_path=[...root]
match_paths.push(match_path)
match_data.push(match)
debug("match found:" +match_path+"; "+match);
}
}
}
}
return { paths: match_paths, data: match_data };
}
this.get = {
'raw' : function(){
return new Promise(function(resolve, reject){
if(!self.data){
fs.readFile(
self.params.path,
function(err, data) {
if(err) reject(err);
try {
JSON.parse(data);
self.data = JSON.parse(data)
resolve(self.data)
} catch(err){
reject(err)
}
}
)
} else {
resolve(self.data);
}
})
},
'reduced' : function(names = [],ascent = [],descent = []) {
return self.get.raw().then(entire_data => {
debug(`ascent: ${ascent}`);
debug(`names: ${names}`);
debug(`descent: ${descent}`);
if (names.length+ascent.length+descent.length<1) {
return entire_data;
}
const domain = self.reduce.fuzzy(entire_data,ascent);
const fence = self.reduce.exact(domain,names);
const product = self.reduce.fuzzy(fence,descent);
return product;
//return self.reduce.exact(entire_data,names);
})
},
'addressed' : function(names) {
return self.get.raw().then(entire_data => {
debug(`Addressing raw: ${JSON.stringify(names)}`);
return self.address(entire_data,names);
})
},
'deals' : function(query){
return self.get.addressed(
[...(self.xform.query_str_to_arr(query)),"repo"]
).then(addressed => { return addressed.paths; })
},
'hosts' : function(query){
return self.get.addressed(
[...(self.xform.query_str_to_arr(query))]
).then(cluster_data => {
debug("Cluster search data: "
+JSON.stringify(cluster_data))
const host_matches = cluster_data.data.map(data =>{
debug("Data in cluster: "+JSON.stringify(data))
const hosts = self.address(
data,
["remote","host"]
);
return hosts.paths;
})
return host_matches;
})
},
'host_list': function(query) {
return self.get.hosts(query).then(paths => {
const host_list = paths.map(path_list => {
const return_queries = path_list.map(path_arr => {
var query_str = "";
path_arr = path_arr.filter(e => e != '.');
path_arr.forEach(e => { query_str += e+" "; })
return query_str.trim();
})
return return_queries;
})
return host_list;
})
},
'root' : function(query){
return self.get.addressed(
[...(self.xform.query_str_to_arr(query))]
).then(addressed => { return addressed.paths; })
},
'path' : function(query) {
return self.get.root(query).then(roots => {
var paths = new Array();
debug(`Roots found: ${roots}`);
roots.forEach (
function(root, i, array) {
var str = "";
debug(`Formatting ${root}`);
root.forEach(
function(key,j,arr) {
debug(`${j}: ${key}`);
str = str + "/" + key;
}
)
debug(str);
var query_arr = query.split(" ");
query_arr.forEach(
function(term,j,arr) {
str = str + "/" + term;
})
str = str.slice(3)
paths.push(str);
}
);
return paths;
})
},
'cluster_data' : function(query) {
return self.get.reduced(
self.xform.query_str_to_arr(query),
["clusters"],
["ports","ssh"]
).then(data => { return data; })
},
'data' : function(query) {
return self.get.reduced(
self.xform.query_str_to_arr(query)
).then(data => { return data; })
}
}
};
module.exports = Parser;