botpress
Version:
The world's first CMS for bots. Easily create, manage and extend chatbots.
195 lines (153 loc) • 6.97 kB
JavaScript
;
var _express = require('express');
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _ms = require('ms');
var _ms2 = _interopRequireDefault(_ms);
var _util = require('../util');
var _util2 = _interopRequireDefault(_util);
var _yn = require('yn');
var _yn2 = _interopRequireDefault(_yn);
var _tamper = require('tamper');
var _tamper2 = _interopRequireDefault(_tamper);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(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 Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
module.exports = bp => {
const serveModule = (app, module) => {
const name = module.name;
const shortName = _util2.default.getModuleShortname(module.name);
if (module.settings.menuIcon === 'custom') {
const iconRequestPath = `/img/modules/${name}.png`;
const iconPath = _path2.default.join(module.root, 'icon.png');
app.get(iconRequestPath, (req, res) => {
try {
res.contentType('image/png');
res.sendFile(iconPath);
} catch (err) {
bp.logger.warn(`Could not serve module icon [${name}] at: ${iconPath}`);
}
});
}
const liteDir = _path2.default.join(module.root, module.settings.liteDir || 'bin/lite');
app.get([`/js/modules/${shortName}`, // The full module view
`/js/modules/${name}.js`, // <<-- DEPRECATED: Will be removed shortly. Only use shortNames
`/js/modules/${shortName}/:subview` // Lite view
], (req, res) => {
const settingsKey = module.settings.webBundle;
const bundlePath = req.params && req.params.subview ? _path2.default.join(liteDir, req.params.subview + '.bundle.js') // Render lite view
: _path2.default.join(module.root, settingsKey || 'bin/web.bundle.js');
try {
const content = _fs2.default.readFileSync(bundlePath);
res.contentType('text/javascript');
res.send(content);
} catch (err) {
bp.logger.warn(`Could not serve module [${name}] at: ${bundlePath}`);
res.sendStatus(404);
}
});
};
const serveCustomTheme = app => {
let customTheme = '';
if (bp.licensing.getFeatures().whitelabel === true) {
const themeLocation = _path2.default.join(bp.projectLocation, 'theme.css');
if (_fs2.default.existsSync(themeLocation)) {
customTheme = _fs2.default.readFileSync(themeLocation);
}
}
app.use('/style/custom-theme.css', (req, res) => {
res.contentType('text/css');
res.send(customTheme);
});
};
const serveMedia = app => {
app.get('/media/:filename', (() => {
var _ref = _asyncToGenerator(function* (req, res) {
const contents = yield bp.mediaManager.readFile(req.params.filename);
if (!contents) {
return res.sendStatus(404);
}
const type = _path2.default.extname(req.params.filename);
// files are never overwritten because of the unique ID
// so we can set the header to cache the asset for 1 year
return res.set({ 'Cache-Control': 'max-age=31556926' }).type(type).send(contents);
});
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
};
const install = (() => {
var _ref2 = _asyncToGenerator(function* (app) {
for (const name in bp._loadedModules) {
const module = bp._loadedModules[name];
serveModule(app, module);
}
app.use((0, _tamper2.default)(function (req, res) {
const contentType = res.getHeaders()['content-type'];
if (!contentType || !contentType.includes('text/html')) {
return;
}
return function (body) {
return body.replace(/\$\$BP_BASE_URL\$\$/g, '');
};
}));
app.use('/js/env.js', (() => {
var _ref3 = _asyncToGenerator(function* (req, res) {
const { tokenExpiry, enabled: authEnabled, useCloud } = bp.botfile.login;
const { enabled: ghostEnabled } = bp.botfile.ghostContent;
const optOutStats = !!bp.botfile.optOutStats;
const appName = bp.botfile.appName || 'Botpress';
const isUsingCloud = !!useCloud && (yield bp.cloud.isPaired());
const pairingInfo = { botId: '', endpoint: '', teamId: '', env: bp.botfile.env };
if (isUsingCloud) {
Object.assign(pairingInfo, (yield bp.cloud.getPairingInfo()));
delete pairingInfo.token;
}
const { isFirstRun, version } = bp;
res.contentType('text/javascript');
res.send(`(function(window) {
window.NODE_ENV = "${process.env.NODE_ENV || 'development'}";
window.BOTPRESS_ENV = "${bp.botfile.env}";
window.BP_BASE_PATH = "";
window.BOTPRESS_CLOUD_ENABLED = ${isUsingCloud};
window.BOTPRESS_CLOUD_SETTINGS = ${JSON.stringify(pairingInfo)};
window.DEV_MODE = ${_util2.default.isDeveloping};
window.AUTH_ENABLED = ${!!authEnabled};
window.AUTH_TOKEN_DURATION = ${(0, _ms2.default)(tokenExpiry)};
window.OPT_OUT_STATS = ${optOutStats};
window.SHOW_GUIDED_TOUR = ${isFirstRun};
window.BOTPRESS_VERSION = "${version}";
window.APP_NAME = "${appName}";
window.GHOST_ENABLED = ${!!ghostEnabled};
window.BOTPRESS_FLOW_EDITOR_DISABLED = ${(0, _yn2.default)(process.env.BOTPRESS_FLOW_EDITOR_DISABLED)};
})(typeof window != 'undefined' ? window : {})`);
});
return function (_x4, _x5) {
return _ref3.apply(this, arguments);
};
})());
serveCustomTheme(app);
serveMedia(app);
app.use((0, _express.static)(_path2.default.join(bp.projectLocation, 'static')));
app.use((0, _express.static)(_path2.default.join(bp.botpressPath, './lib/web')));
app.get('*', function (req, res, next) {
// If browser requests HTML and request isn't an API request
if (/html/i.test(req.headers.accept) && !/^\/api\//i.test(req.url)) {
if (req.url && /^\/lite\//i.test(req.url)) {
return res.sendFile(_path2.default.join(bp.botpressPath, './lib/web/lite/index.html'));
}
return res.sendFile(_path2.default.join(bp.botpressPath, './lib/web/index.html'));
}
next();
});
return true;
});
return function install(_x3) {
return _ref2.apply(this, arguments);
};
})();
return { install };
};
//# sourceMappingURL=static.js.map