UNPKG

@beelab/toolbox

Version:
168 lines (138 loc) 5.44 kB
require('dotenv').config(); const fs = require('fs'); const { createApp, createServer } = require('yion'); const bodyParser = require('yion-body-parser'); const Container = require('../Common/Service/Container'); module.exports = (options = { cache: true, websocket: false, pwa: false, query: false, localQuery: false, api: false, apiPrefix: 'api', cors: null, publicDir: 'public', auth: { clientId: 'demo' }, httpServerPlugins: [], }) => { const basePath = process.cwd(); const publicDir = options.publicDir ? options.publicDir : 'public'; const { NODE_PORT = 8080, NODE_ENV = 'dev', LOCALE = 'en', ALLOW_ANONYMOUS = true, API_URL, WEBSOCKET_URL } = process.env; const { version, name } = require(`${basePath}/package.json`); const cache = { 'Cache-Control': 'public, max-age=' + (86400 * 30), 'ETag': Date.now() }; Container.addParameters({ info: { name, version, env: NODE_ENV, locale: LOCALE, allowAnonymous: ALLOW_ANONYMOUS, apiUrl: API_URL, websocketUrl: WEBSOCKET_URL, auth: options.auth, } }); const app = createApp(); if (options.query) { const Query = require('../Common/Service/Query'); app.use((req, res, next) => { if (!Container.has('Requester')) { const { DB_HOST, DB_NAME, DB_CACHE = false } = process.env; Container.set('Requester', new Query(DB_HOST, DB_NAME, !!DB_CACHE)); } next(); }); } if (options.localQuery) { const LocalQuery = require('../Common/Service/LocalQuery'); app.use((req, res, next) => { if (!Container.has('Requester')) { const { DB_CACHE = false } = process.env; Container.set('Requester', new LocalQuery(options.localQuery, !!DB_CACHE)); } next(); }); } if (options.cors) { app.use((req, res, next) => { res.set('Access-Control-Allow-Origin', options.cors); res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization'); res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); if (req.method === 'OPTIONS') { return res.send(); } next(); }); } if (options.cache) { Container.set('cache', cache); app.use((req, res, next) => { if (req.headers['if-none-match'] && req.headers['if-none-match'] == cache['ETag']) { return res.status(304).send(); } next(); }); } if (options.pwa) { app.use((req, res, next) => { res.set('Service-Worker-Allowed', '/'); next(); }); app.get('/sw.js', (req, res) => { res.set('Content-Type', 'application/javascript'); return res.send(` importScripts('/scripts/sw.js'); if (initServiceWorker) { initServiceWorker(self, "${name}-${version}"); } `); }); } app.link('/modules', `${basePath}/node_modules`, options.cache ? cache : {}); app.link('/dist', basePath + '/dist', options.cache ? cache : {}); app.link('/styles', `${basePath}/${publicDir}/styles`, options.cache ? cache : {}); app.link('/static', `${basePath}/${publicDir}/static`, options.cache ? cache : {}); app.link('/scripts', `${basePath}/${publicDir}/scripts`, options.cache ? cache : {}); app.link('/images', `${basePath}/${publicDir}/images`, options.cache ? cache : {}); app.link('/fonts', `${basePath}/${publicDir}/fonts`, options.cache ? cache : {}); app.link('/assets', `${basePath}/${publicDir}/assets`, options.cache ? cache : {}); app.get('/info', (req, res) => { res.json(Container.parameters('info')); }); let api = null; if (options.api) { const apiPrefix = options.apiPrefix !== undefined ? options.apiPrefix : '/api'; const tamiaApi = require.main.require('@tamia-web/tamia'); const docPlugin = require.main.require('@tamia-web/doc-plugin'); api = tamiaApi(options.api, { plugins: [docPlugin(apiPrefix)] }); app.use((req, res, next) => { const pattern = new RegExp(`^${apiPrefix}`); if (pattern.test(req.url)) { req.original.url = req.original.url.replace(apiPrefix, ''); req.original.body = req.body; req.original.params = req.params; req.original.query = req.query; api.request(req.original, res.original, next); } else { next(); } }); } app.get('/', (req, res) => { const path = `${basePath}/${publicDir}/index.html`; try { fs.statSync(path); res.sendFile(path, 'index.html', 'text/html', false); } catch (e) { res.status(404).send(e); } }); const httpServer = createServer(app, [bodyParser].concat(options.httpServerPlugins || [])); httpServer.listen(NODE_PORT); httpServer.on('listening', () => console.log(`🌏 Server start on port ${NODE_PORT}`)); return { httpServer, app, api }; };