require('require-yaml'); const cookieParser = require('cookie-parser'); const loopback = require('loopback'); const boot = require('loopback-boot'); const DataSource = require('loopback-datasource-juggler').DataSource; const fs = require('fs-extra'); const i18n = require('i18n'); const path = require('path'); let _resolveConnector = DataSource._resolveConnector; DataSource._resolveConnector = function(...args) { let name = args[0]; let testPath = `${__dirname}/connectors/${name}.js`; if (fs.existsSync(testPath)) { return { connector: require(testPath), error: null }; } return _resolveConnector.apply(this, args); }; let app = loopback(); module.exports = app; // Configuration let rootDir = __dirname; let lbDir = path.resolve(`${rootDir}/..`); let appDir = path.resolve(`${__dirname}/../..`); let localeDir = `${lbDir}/locale`; let viewDir = `${lbDir}/client`; let buildDir = `${appDir}/dist`; let servicesDir = `${appDir}/modules`; let modulesPath = `${appDir}/modules.yml`; // TODO: It should be stored at some config file app.set('api key', 'salix'); app.set('url auth', '/auth'); app.set('applications', require('./application.json')); app.use(cookieParser()); // Internationalization if (fs.existsSync(localeDir)) { i18n.configure({ directory: localeDir, defaultLocale: 'es' }); app.use(i18n.init); } // View if (fs.existsSync(viewDir)) { app.set('view engine', 'ejs'); app.set('views', viewDir); app.use(loopback.static(viewDir)); } app.getWpAssets = entryPoint => { const wpAssets = require(`${buildDir}/webpack-assets.json`); let jsFiles = []; let regex = new RegExp(`(^|~)${entryPoint}($|~)`); for (let asset in wpAssets) { if (regex.test(asset)) jsFiles.push(wpAssets[asset].js); } return jsFiles; }; // Initialization app.disconnect = async function() { let promises = []; for (let ds in app.dataSources) promises.push(app.dataSources[ds].disconnect()); return await Promise.all(promises); }; app.start = function(port) { function onListen() { let baseUrl = app.get('url').replace(/\/$/, ''); let explorerPath = app.get('loopback-component-explorer').mountPath; console.log(`Browse your REST API at: %s`, `${baseUrl}${explorerPath}`); app.emit('started'); } let args = port ? [port, onListen] : [onListen]; return app.listen(...args); }; let config = require('./config.json'); for (let key in config) app.set(key, config[key]); let modelConfigFiles = [ `${__dirname}/model-config.json` ]; let modelSources = [ `loopback/common/models`, `loopback/server/models`, `${__dirname}/../common/models` ]; let mixinDirs = [ `loopback/common/mixins`, `loopback/server/mixins`, `${__dirname}/../common/mixins` ]; let bootDirs = [ `${__dirname}/boot` ]; addPath(`${appDir}/back`); let services = require(modulesPath); for (let service of services) addPath(`${servicesDir}/${service}/back`); function addPath(path) { modelConfigFiles.push(`${path}/model-config.json`); modelSources.push(`${path}/models`); mixinDirs.push(`${path}/mixins`); bootDirs.push(`${path}/boot`); } let models = {}; for (file of modelConfigFiles) { if (fs.existsSync(file)) { let fileModels = require(file); for (let key in fileModels) { if (models[key]) console.warn(`Redeclaration of '${key}' at ${file}`); } Object.assign(models, fileModels); } } let bootOptions = { appRootDir: __dirname, appConfigRootDir: rootDir, modelsRootDir: rootDir, models: models, modelSources: modelSources, mixinDirs: mixinDirs, bootDirs: bootDirs }; if (fs.existsSync(`/etc/salix`)) bootOptions.dsRootDir = `/etc/salix`; boot(app, bootOptions, function(err) { if (err) throw err; if (require.main === module) app.start(); });