botpress
Version:
The world's first CMS for bots. Easily create, manage and extend chatbots.
170 lines (128 loc) • 6.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _eventemitter = require('eventemitter2');
var _eventemitter2 = _interopRequireDefault(_eventemitter);
var _mkdirp = require('mkdirp');
var _mkdirp2 = _interopRequireDefault(_mkdirp);
var _validator = require('./validator');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird2.default(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird2.default.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const PLACING_STEP = 250;
class FlowProvider extends _eventemitter2.default {
constructor({ logger, botfile, projectLocation, ghostManager }) {
super({
wildcard: true,
maxListeners: 100
});
this.logger = logger;
this.botfile = botfile;
this.projectLocation = projectLocation;
this.ghostManager = ghostManager;
this.flowsDir = this.botfile.flowsDir || './flows';
_mkdirp2.default.sync(_path2.default.dirname(this.flowsDir));
this.ghostManager.addRootFolder(this.flowsDir, { filesGlob: '**/*.json' });
}
loadAll() {
var _this = this;
return _asyncToGenerator(function* () {
const flows = yield _this.ghostManager.directoryListing(_this.flowsDir, '.flow.json').map((() => {
var _ref = _asyncToGenerator(function* (flowPath) {
const [flow, uiEq] = (yield _bluebird2.default.map([flowPath, _this._uiPath(flowPath)], function (filePath) {
return _this.ghostManager.readFile(_this.flowsDir, filePath);
})).map(JSON.parse);
if (!flow) {
return null;
}
const schemaError = (0, _validator.validateFlowSchema)(flow);
if (schemaError) {
_this.logger.warn(schemaError);
return null;
}
flow.links = uiEq.links;
// Take position from UI files or create default position
let unplacedIndex = -1;
flow.nodes = flow.nodes.map(function (node) {
const position = _lodash2.default.get(_lodash2.default.find(uiEq.nodes, { id: node.id }), 'position');
unplacedIndex = position ? unplacedIndex : unplacedIndex + 1;
return _extends({}, node, {
x: position ? position.x : 50 + unplacedIndex * PLACING_STEP,
y: position ? position.y : (_lodash2.default.maxBy(flow.nodes, 'y') || { y: 0 }).y + PLACING_STEP
});
});
return _extends({
name: flowPath,
location: flowPath,
nodes: flow.nodes.filter(Boolean)
}, _lodash2.default.pick(flow, 'version', 'catchAll', 'startNode', 'links', 'skillData', 'timeoutNode'));
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
return flows.filter(Boolean);
})();
}
saveFlows(flows) {
var _this2 = this;
return _asyncToGenerator(function* () {
if (!flows.find(function ({ flow }) {
return flow === 'main.flow.json';
})) {
throw new Error(`[Flow] Expected flows list to contain 'main.flow.json'`);
}
const flowsToSave = yield _bluebird2.default.mapSeries(flows, function (flow) {
return _this2._prepareSaveFlow(flow);
});
const flowsSavePromises = _lodash2.default.flatten(flowsToSave.map(function ({ flowPath, uiPath, flowContent, uiContent }) {
return [_this2.ghostManager.upsertFile(_this2.flowsDir, flowPath, JSON.stringify(flowContent, null, 2)), _this2.ghostManager.upsertFile(_this2.flowsDir, uiPath, JSON.stringify(uiContent, null, 2))];
}));
const pathsToOmit = _lodash2.default.flatten(flowsToSave.map(function (flow) {
return [flow.flowPath, flow.uiPath];
}));
const flowFiles = yield _this2.ghostManager.directoryListing(_this2.flowsDir, '.json', pathsToOmit);
const flowsDeletePromises = flowFiles.map(function (filePath) {
return _this2.ghostManager.deleteFile(_this2.flowsDir, filePath);
});
yield _bluebird2.default.all(flowsSavePromises.concat(flowsDeletePromises));
_this2.emit('flowsChanged');
})();
}
_prepareSaveFlow(flow) {
var _this3 = this;
return _asyncToGenerator(function* () {
flow = _extends({}, flow, { version: '0.1' });
const schemaError = (0, _validator.validateFlowSchema)(flow);
if (schemaError) {
throw new Error(schemaError);
}
// What goes in the ui.json file
const uiContent = {
nodes: flow.nodes.map(function (node) {
return { id: node.id, position: _lodash2.default.pick(node, 'x', 'y') };
}),
links: flow.links
// What goes in the .flow.json file
};const flowContent = _extends({}, _lodash2.default.pick(flow, 'version', 'catchAll', 'startNode', 'skillData', 'timeoutNode'), {
nodes: flow.nodes.map(function (node) {
return _lodash2.default.omit(node, 'x', 'y', 'lastModified');
})
});
const flowPath = flow.location;
return { flowPath, uiPath: _this3._uiPath(flowPath), flowContent, uiContent };
})();
}
_uiPath(flowPath) {
return flowPath.replace(/\.flow\.json/i, '.ui.json');
}
}
exports.default = FlowProvider;
//# sourceMappingURL=provider.js.map