@godspeedsystems/core
Version:
> 4th Generation Declarative Microservice Framework
396 lines (394 loc) • 14.5 kB
JavaScript
/*
* You are allowed to study this software for learning and local * development purposes only. Any other use without explicit permission by Mindgrep, is prohibited.
* © 2022 Mindgrep Technologies Pvt Ltd
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
checkDatasource: function() {
return checkDatasource;
},
checkFunctionExists: function() {
return checkFunctionExists;
},
compileScript: function() {
return compileScript;
},
getAtPath: function() {
return getAtPath;
},
getParseDurationPkg: function() {
return getParseDurationPkg;
},
isPlainObject: function() {
return isPlainObject;
},
prepareScript: function() {
return prepareScript;
},
removeNulls: function() {
return removeNulls;
},
setAtPath: function() {
return setAtPath;
}
});
const _interfaces = require("./interfaces");
const _coffeescript = /*#__PURE__*/ _interop_require_default(require("coffeescript"));
const _config = /*#__PURE__*/ _interop_require_default(require("config"));
const _expandVariables = /*#__PURE__*/ _interop_require_default(require("./expandVariables"));
const _fs = /*#__PURE__*/ _interop_require_wildcard(require("fs"));
const _assert = /*#__PURE__*/ _interop_require_wildcard(require("assert"));
const _buffer = /*#__PURE__*/ _interop_require_wildcard(require("buffer"));
const _child_process = /*#__PURE__*/ _interop_require_wildcard(require("child_process"));
const _cluster = /*#__PURE__*/ _interop_require_wildcard(require("cluster"));
const _dgram = /*#__PURE__*/ _interop_require_wildcard(require("dgram"));
const _dns = /*#__PURE__*/ _interop_require_wildcard(require("dns"));
const _events = /*#__PURE__*/ _interop_require_wildcard(require("events"));
const _http = /*#__PURE__*/ _interop_require_wildcard(require("http"));
const _https = /*#__PURE__*/ _interop_require_wildcard(require("https"));
const _net = /*#__PURE__*/ _interop_require_wildcard(require("net"));
const _os = /*#__PURE__*/ _interop_require_wildcard(require("os"));
const _path = /*#__PURE__*/ _interop_require_wildcard(require("path"));
const _querystring = /*#__PURE__*/ _interop_require_wildcard(require("querystring"));
const _readline = /*#__PURE__*/ _interop_require_wildcard(require("readline"));
const _stream = /*#__PURE__*/ _interop_require_wildcard(require("stream"));
const _string_decoder = /*#__PURE__*/ _interop_require_wildcard(require("string_decoder"));
const _timers = /*#__PURE__*/ _interop_require_wildcard(require("timers"));
const _tls = /*#__PURE__*/ _interop_require_wildcard(require("tls"));
const _url = /*#__PURE__*/ _interop_require_wildcard(require("url"));
const _util = /*#__PURE__*/ _interop_require_wildcard(require("util"));
const _zlib = /*#__PURE__*/ _interop_require_wildcard(require("zlib"));
const _logger = require("../logger");
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _async_to_generator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const isPlainObject = (value)=>(value === null || value === void 0 ? void 0 : value.constructor) === Object;
function getAtPath(obj, path) {
const keys = path.split('.');
for (const key of keys){
if (key in obj) {
//obj[key]
obj = obj[key];
} else {
return undefined;
}
}
return obj;
}
function setAtPath(o, path, value) {
const keys = path.split('.');
let obj = o;
//prepare the array to ensure that there is nested PlainObject till the last key
//Ensure there is an PlainObject as value till the second last key
for(let i = 0; i < keys.length - 1; i++){
const key = keys[i];
if (obj[key] !== undefined && obj[key] !== null) {
//obj[key] has a non null value
obj = obj[key];
} else {
obj = obj[key] = {};
}
}
const lastKey = keys[keys.length - 1];
obj[lastKey] = value;
}
function checkDatasource(workflowJson, datasources, location) {
for (let task of workflowJson.tasks){
if (task.tasks) {
//sub-workflow
const status = checkDatasource(task, datasources, location);
if (!status.success) {
return status;
}
} else {
if (task.fn.includes('datasource.')) {
var _task_fn, _task_fn1;
/*
for eg., in workflow tasks,
any task can point to datasource as below
...
fn: datasource.mongo.Post.findMany
or
fn: datasource.redis.get
...
So, the `mongo`or `redis` in the previous example, is the name actual datasource, whereas `datasource`is just the namespace
to differentiate from com.gs functions.
While loading the workflows, we only check for the available datasource name, in loaded datasource
and rest is handled by the actual datasource implementation.
*/ let dsName;
if (((_task_fn = task.fn) === null || _task_fn === void 0 ? void 0 : _task_fn.match(/<(.*?)%/)) && ((_task_fn1 = task.fn) === null || _task_fn1 === void 0 ? void 0 : _task_fn1.includes('%>'))) {
const extractDynamicDatasource = task.fn.match(/<%[^%>]+%>/);
if (extractDynamicDatasource) {
const script = (0, _expandVariables.default)(extractDynamicDatasource[0], location);
dsName = script;
}
} else {
dsName = task.fn.split('.')[1];
}
if (!(dsName in datasources)) {
_logger.logger.error('datasource %s is not present in datasources', dsName);
const message = `datasource ${dsName} is not present in datasources`;
return new _interfaces.GSStatus(false, 500, message);
}
}
}
}
return new _interfaces.GSStatus(true, undefined);
}
function prepareScript(str, location) {
var _config_defaults;
//@ts-ignore
global.fs = _fs;
//@ts-ignore
global.assert = _assert;
//@ts-ignore
global.buffer = _buffer;
//@ts-ignore
global.child_process = _child_process;
//@ts-ignore
global.cluster = _cluster;
//@ts-ignore
global.dgram = _dgram;
//@ts-ignore
global.dns = _dns;
//@ts-ignore
global.events = _events;
//@ts-ignore
global.http = _http;
//@ts-ignore
global.https = _https;
//@ts-ignore
global.net = _net;
//@ts-ignore
global.os = _os;
//@ts-ignore
global.path = _path;
//@ts-ignore
global.querystring = _querystring;
//@ts-ignore
global.readline = _readline;
//@ts-ignore
global.stream = _stream;
//@ts-ignore
global.string_decoder = _string_decoder;
//@ts-ignore
global.timers = _timers;
//@ts-ignore
global.tls = _tls;
//@ts-ignore
global.url = _url;
//@ts-ignore
global.util = _util;
//@ts-ignore
global.zlib = _zlib;
let langs = /<(.*?)%/.exec(str);
//@ts-ignore
const lang = langs[1] || ((_config_defaults = _config.default.defaults) === null || _config_defaults === void 0 ? void 0 : _config_defaults.lang) || _config.default.lang || 'js';
str = str.trim();
if (str.match(/^<(.*?)%/) && str.match(/%>$/)) {
let temp = str.replace(/^<(.*?)%/, '').replace(/%>$/, '');
if (!temp.includes('%>')) {
str = temp;
}
}
if (str.match(/<(.*?)%/) && str.match(/%>/)) {
str = "'" + str.replace(/<(.*?)%/g, "' + ").replace(/%>/g, " + '") + "'";
}
// logger.debug('lang: %s', lang);
// logger.debug('script: %s', str);
str = str.trim();
const initialStr = str;
if (!/\breturn\b/.test(str)) {
str = 'return ' + str;
}
if (lang === 'coffee') {
try {
str = _coffeescript.default.compile(str, {
bare: true
});
} catch (err) {
_logger.logger.fatal(location, 'Error in compiling coffee script %s. Error message %s\n error %o %o', str, err.message, err, new Error().stack);
process.exit(1);
}
}
let prepareScriptFunction;
try {
prepareScriptFunction = Function('config', 'inputs', 'outputs', 'mappings', 'task_value', str);
} catch (err) {
_logger.logger.fatal(location, 'Caught exception in javascript compilation, script: %s compiled script %s. Error message %s\n error %o %o', initialStr, str, err.message, err, err.stack);
process.exit(1);
}
return prepareScriptFunction;
}
function compileScript(args, location) {
if (!args) {
return ()=>args;
}
if (typeof args == 'object') {
if (isPlainObject(args)) {
let out = {};
for(let k in args){
location.argsName = k;
out[k] = compileScript(args[k], location);
}
return function(config, inputs, outputs, mappings, task_value) {
let returnObj = {};
for(let k in out){
if (out[k] instanceof Function) {
returnObj[k] = out[k](config, inputs, outputs, mappings, task_value);
}
}
return returnObj;
};
} else if (Array.isArray(args)) {
let out = [];
for(let k in args){
location.index = k;
out[k] = compileScript(args[k], location);
}
return function(config, inputs, outputs, mappings, task_value) {
let returnObj = [];
for(let k in out){
if (out[k] instanceof Function) {
returnObj.push(out[k](config, inputs, outputs, mappings, task_value));
} else {
returnObj.push(out[k]);
}
}
return returnObj;
};
} else {
return ()=>args;
}
} else if (typeof args == 'string') {
if (args.match(/(^|\/):([^/]+)/)) {
_logger.logger.debug('before replacing path params %s', args);
args = args.replace(/(^|\/):([^/]+)/g, '$1<%inputs.params.$2%>');
_logger.logger.debug('after replacing path params %s', args);
}
if (args.match(/<(.*?)%/) && args.includes('%>')) {
return prepareScript(args, location);
}
}
return ()=>args;
}
function checkFunctionExists(events, functions) {
for(let event in events){
if (!(events[event].fn in functions)) {
_logger.logger.error('function %s of event %s is not present in functions', events[event].fn, event);
const msg = `function ${events[event].fn} of event ${event} is not present in functions`;
return new _interfaces.GSStatus(false, 500, msg);
}
}
return new _interfaces.GSStatus(true, undefined);
}
function removeNulls(obj) {
const isArray = Array.isArray(obj);
for (const k of Object.keys(obj)){
if (obj[k] === null) {
if (isArray) {
//@ts-ignore
obj.splice(k, 1);
} else {
delete obj[k];
}
} else if (typeof obj[k] === 'object') {
removeNulls(obj[k]);
}
//@ts-ignore
if (isArray && obj.length === k) {
removeNulls(obj);
}
}
return obj;
}
function getParseDurationPkg() {
return _getParseDurationPkg.apply(this, arguments);
}
function _getParseDurationPkg() {
_getParseDurationPkg = _async_to_generator(function*() {
const { default: _parseDuration } = yield Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("parse-duration")));
return _parseDuration;
});
return _getParseDurationPkg.apply(this, arguments);
}