midas-core
Version:
Enrich data with APIs
392 lines (326 loc) • 13.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Utils
// Utils
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _recursiveIterator = require('recursive-iterator');
var _recursiveIterator2 = _interopRequireDefault(_recursiveIterator);
var _camelcase = require('camelcase');
var _camelcase2 = _interopRequireDefault(_camelcase);
var _TypeChecker = require('./../Utils/TypeChecker');
var _TypeChecker2 = _interopRequireDefault(_TypeChecker);
var _ArrayUtils = require('./../Utils/ArrayUtils');
var _ArrayUtils2 = _interopRequireDefault(_ArrayUtils);
var _csvjson = require('csvjson');
var _csvjson2 = _interopRequireDefault(_csvjson);
var _xlsx = require('xlsx');
var _xlsx2 = _interopRequireDefault(_xlsx);
var _readJsonSync = require('read-json-sync');
var _readJsonSync2 = _interopRequireDefault(_readJsonSync);
var _jsonpath = require('jsonpath');
var _jsonpath2 = _interopRequireDefault(_jsonpath);
var _inquirer = require('inquirer');
var _inquirer2 = _interopRequireDefault(_inquirer);
var _colors = require('colors');
var _colors2 = _interopRequireDefault(_colors);
var _prettyjson = require('prettyjson');
var _prettyjson2 = _interopRequireDefault(_prettyjson);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Wizard = function () {
function Wizard() {
_classCallCheck(this, Wizard);
}
_createClass(Wizard, [{
key: '_transform_to_config_object',
value: function _transform_to_config_object(object) {
var config = { source: {}, target: {}, enrichers: [] };
var rate_limit = { number_of_requests: -1, time_window: 's' };
// Source
config.name = object.name;
config.source[object.source_type] = {};
config.source[object.source_type].path = object.source_path;
// Enricher
var enricher_name = this._has_custom_enricher(object) ? (0, _camelcase2.default)(object.custom_enricher) : (0, _camelcase2.default)(object.enricher);
// check if rate limit is set
if (typeof object.rate_limit !== 'undefined') {
var limits = object.rate_limit.split('/');
if (['s', 'm', 'h'].indexOf(limits[1]) > -1) {
rate_limit.number_of_requests = limits[0];
rate_limit.time_window = limits[1];
}
}
if (object.enricher !== 'no') {
config.enrichers = [{
name: enricher_name,
path: this._resolve_enricher_parent_path(enricher_name),
config: {
input_parameter: object.source_object_path,
target_property: object.target_property_name,
rate_limit: rate_limit
}
}];
} else {
config.enrichers = [{
name: "NAME_OF_YOUR_ENRICHER",
path: "ABSOLUTE_PATH_TO_YOUR_ENRICHER",
config: {
input_parameter: object.source_object_path,
target_property: object.target_property_name,
rate_limit: rate_limit
}
}];
}
// Add configs for pre-defined enricher
if (!this._has_custom_enricher(object) && enricher_name === 'openWeather') {
config.enrichers[0].config['api_key'] = object.enricher_config_api_key;
}
// Target
if (object.target_type === 'alter source') {
config.target[object.source_type] = {};
config.target[object.source_type].path = object.source_path;
} else {
// ONLY TARGET FOR ALPHA
config.target[object.source_type] = {};
config.target[object.source_type].path = object.source_path;
//config.target[object.target_type] = {};
//config.target[object.target_type].path = object.target_path;
}
return config;
}
}, {
key: '_has_custom_enricher',
value: function _has_custom_enricher(answers) {
return typeof answers.custom_enricher !== 'undefined';
}
}, {
key: '_resolve_enricher_parent_path',
value: function _resolve_enricher_parent_path(name) {
var base_path = __dirname + '/../Enrichers/';
if (name === 'openWeather') {
return base_path;
}
return process.cwd();
}
}, {
key: '_create_enricher',
value: function _create_enricher(name) {
name = (0, _camelcase2.default)(name);
var enricher_template = '\n"use strict";\nvar Enricher = class Enricher {\n\n constructor(rp, inputData, config) {\n //npm request-promise is used for handling requests\n //see: https://github.com/request/request-promise\n this.rp = rp;\n //loads inputData of the target file specified in the source object path in your config\n this.inputData = inputData;\n //loads config for this enrichment\n this.config = config;\n }\n\n getConfig() {\n return this.config;\n }\n\n getName() {\n return \'Enricher\';\n }\n\n setData(inputData) {\n this.inputData = inputData;\n }\n\n process(inputData) {\n\n if (typeof inputData != \'undefined\' && inputData != null) {\n this.inputData = inputData;\n }\n\n // Do stuff here\n\n\n return Promise.resolve(this.inputData); \n }\n\n // eof class\n};\n\nmodule.exports.Enricher = Enricher;\n\t\t';
var new_enricher_source = enricher_template.replace(/Enricher/g, name);
var enricher_path = process.cwd() + '/' + name + '.js';
_fsExtra2.default.writeFileSync(enricher_path, new_enricher_source);
return enricher_path;
}
}, {
key: '_process_answers',
value: function _process_answers(answers) {
var _this = this;
var config_object = this._transform_to_config_object(answers);
var config_string = JSON.stringify(config_object, null, '\t');
var config_save_path = process.cwd() + '/' + config_object.name.toLowerCase().replace(/\s/g, "_") + '_midas.json';
if (this._has_custom_enricher(answers)) {
this._create_enricher(answers.custom_enricher);
}
var config_save_state = _fsExtra2.default.outputJson(config_save_path, config_object, { spaces: '\t' });
config_save_state.then(function () {
console.log('');
console.log('--------------------------------------------------------------');
console.log('✅ New enrichment job successfully created '.green.bold);
console.log('');
console.log(' ⚠️ You can freely customize your enrichment job using your own enrichers and config'.cyan);
console.log('Check out https://midas.science/guide'.cyan);
console.log('');
// Notify user that s/he has to add an enricher themself
if (!_this._has_custom_enricher(answers)) {
console.log('');
console.log(' ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️');
console.log('Currently you didn\'t specify any enricher for your process'.bold);
console.log('Create or add one before start your enrichement process'.bold);
console.log(' ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️');
console.log('');
console.log('');
}
console.log('Start enrichment process via '.green.bold);
console.log('midas enrich -c "' + config_save_path + '"');
console.log('--------------------------------------------------------------');
console.log('');
}).catch(function (err) {
return console.log('Something went wrong');
});
}
}, {
key: 'start',
value: function start() {
var _this2 = this;
var questions = _inquirer2.default.prompt([{
type: 'input',
name: 'name',
message: "Chose a name for your enrichment process:"
}, {
type: 'list',
name: 'source_type',
message: 'What\'s your data source?',
choices: ['CSV', 'JSON', 'XLSX'],
filter: function filter(val) {
return val.toLowerCase();
}
}, {
when: function when(response) {
return response.source_type === 'csv';
},
type: 'input',
name: 'csv_delimiter',
message: "What\'s the delimiter of your CSV file?"
}, {
when: function when(response) {
return true;
},
type: 'input',
name: 'source_path',
message: "Where is your file located? (Enter the absolute path)",
validate: function validate(value) {
if (_fsExtra2.default.existsSync(value)) {
return true;
}
return 'File not found :/';
}
}, {
when: function when(response) {
return true;
},
type: 'input',
name: 'source_object_path',
message: function message(response) {
if (response.json_path_validate === 'n') {
return 'Just try again';
} else {
return 'Define the JSON path of your input parameter';
}
},
validate: function validate(value, response) {
// Extract data schema
var data_set = null;
if (response.source_type === 'xlsx') {
var wb = _xlsx2.default.readFile(response.source_path, { type: "file" });
data_set = _xlsx2.default.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { raw: false, header: 1 });
data_set = _ArrayUtils2.default.arrayObjectify(data_set);
} else if (response.source_type === 'csv') {
var options = {
delimiter: response.csv_delimiter,
quote: '"'
};
var _data = _fsExtra2.default.readFileSync(response.source_path, { encoding: 'utf8' });
data_set = _csvjson2.default.toObject(_data, options);
} else if (response.source_type === 'json') {
data_set = (0, _readJsonSync2.default)(response.source_path);
}
var jp_source_data = null;
try {
jp_source_data = _jsonpath2.default.nodes(data_set, value);
} catch (e) {
return 'Please enter a valid json path';
}
var example_data_point = 'Not found';
if (jp_source_data.length > 0 && typeof jp_source_data[0].value !== 'undefined') {
example_data_point = jp_source_data[0].value;
} else {
return 'Please enter a valid json path';
}
var example_data_point_type = (typeof example_data_point === 'undefined' ? 'undefined' : _typeof(example_data_point)).bold;
if (Array.isArray(example_data_point)) {
example_data_point_type = 'array'.bold;
}
console.log('');
console.log('');
console.log('This will be the input for your enricher:');
console.log('Example (first row / data point):');
console.log('');
console.log('Type ' + example_data_point_type);
if ((typeof example_data_point === 'undefined' ? 'undefined' : _typeof(example_data_point)) === 'object') {
console.log(_prettyjson2.default.render(example_data_point));
} else {
console.log(example_data_point.blue);
}
console.log('');
console.log('');
return true;
}
}, {
type: 'list',
name: 'enricher',
message: 'Do you want to create a new enricher?',
choices: ['Yes', 'No'],
filter: function filter(val) {
var return_value = val;
if (val === 'Yes') {
return_value = 'custom';
}
return (0, _camelcase2.default)(return_value);
}
}, {
when: function when(response) {
return response.enricher === 'custom';
},
type: 'input',
name: 'custom_enricher',
message: 'Specify a name for your new enricher',
filter: function filter(val) {
return val;
}
}, {
when: function when(response) {
return true;
},
type: 'input',
name: 'target_property_name',
message: "Name of the enriched property?"
}, {
when: function when(response) {
return true;
},
type: 'list',
name: 'rate_limit_yesno',
message: "Do you need rate limiting?",
choices: ['Yes', 'No'],
filter: function filter(val) {
return val.toLowerCase();
}
}, {
when: function when(response) {
return response.rate_limit_yesno === 'yes';
},
type: 'input',
name: 'rate_limit',
message: "Define your rate limit via NUMBER_OF_REQUESTS/TIME_UNIT (e.g. 100/s would mean midas will make a maximum of 100 requests per second)",
filter: function filter(val) {
return val.toLowerCase();
},
validate: function validate(value, response) {
var split = value.split('/');
if (split.length != 2) {
return false;
}
if (['s', 'm', 'h'].indexOf(split[1]) <= -1) {
return false;
}
if (/^\d+$/.test(split[0]) == false) {
return false;
}
return true;
}
}]);
questions.then(function (answers) {
_this2._process_answers(answers);
});
// eof
}
}]);
return Wizard;
}();
exports.default = Wizard;