101 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| const path = require('path');
 | |
| require('dotenv').config({ path: path.resolve(__dirname, '../../.env') });
 | |
| 
 | |
| const _ = require('lodash');
 | |
| const Rx = require('rx');
 | |
| const loopback = require('loopback');
 | |
| const boot = require('loopback-boot');
 | |
| const createDebugger = require('debug');
 | |
| const morgan = require('morgan');
 | |
| const Sentry = require('@sentry/node');
 | |
| 
 | |
| const { sentry } = require('../../config/secrets');
 | |
| const { setupPassport } = require('./component-passport');
 | |
| 
 | |
| const log = createDebugger('fcc:server');
 | |
| const reqLogFormat = ':date[iso] :status :method :response-time ms - :url';
 | |
| 
 | |
| // force logger to always output
 | |
| // this may be brittle
 | |
| log.enabled = true;
 | |
| 
 | |
| if (sentry.dns === 'dsn_from_sentry_dashboard') {
 | |
|   log('Sentry reporting disabled unless DSN is provided.');
 | |
| } else {
 | |
|   Sentry.init({
 | |
|     dsn: sentry.dns
 | |
|   });
 | |
|   log('Sentry initialized');
 | |
| }
 | |
| 
 | |
| Rx.config.longStackSupport = process.env.NODE_DEBUG !== 'production';
 | |
| const app = loopback();
 | |
| 
 | |
| app.set('state namespace', '__fcc__');
 | |
| app.set('port', process.env.PORT || 3000);
 | |
| app.set('views', path.join(__dirname, 'views'));
 | |
| app.set('view engine', 'jade');
 | |
| app.use(loopback.token());
 | |
| app.use(
 | |
|   morgan(reqLogFormat, { stream: { write: msg => log(_.split(msg, '\n')[0]) } })
 | |
| );
 | |
| app.disable('x-powered-by');
 | |
| 
 | |
| const createLogOnce = () => {
 | |
|   let called = false;
 | |
|   return str => {
 | |
|     if (called) {
 | |
|       return null;
 | |
|     }
 | |
|     called = true;
 | |
|     return log(str);
 | |
|   };
 | |
| };
 | |
| const logOnce = createLogOnce();
 | |
| 
 | |
| boot(app, __dirname, err => {
 | |
|   if (err) {
 | |
|     // rethrowing the error here because any error thrown in the boot stage
 | |
|     // is silent
 | |
|     logOnce('The below error was thrown in the boot stage');
 | |
|     throw err;
 | |
|   }
 | |
| });
 | |
| 
 | |
| setupPassport(app);
 | |
| 
 | |
| const { db } = app.datasources;
 | |
| db.on('connected', _.once(() => log('db connected')));
 | |
| app.start = _.once(function() {
 | |
|   const server = app.listen(app.get('port'), function() {
 | |
|     app.emit('started');
 | |
|     log(
 | |
|       'freeCodeCamp server listening on port %d in %s',
 | |
|       app.get('port'),
 | |
|       app.get('env')
 | |
|     );
 | |
|     log(`connecting to db at ${db.settings.url}`);
 | |
|   });
 | |
| 
 | |
|   process.on('SIGINT', () => {
 | |
|     log('Shutting down server');
 | |
|     server.close(() => {
 | |
|       log('Server is closed');
 | |
|     });
 | |
|     log('closing db connection');
 | |
|     db.disconnect().then(() => {
 | |
|       log('DB connection closed');
 | |
|       // exit process
 | |
|       // this may close kept alive sockets
 | |
|       // eslint-disable-next-line no-process-exit
 | |
|       process.exit(0);
 | |
|     });
 | |
|   });
 | |
| });
 | |
| 
 | |
| module.exports = app;
 | |
| 
 | |
| if (require.main === module) {
 | |
|   app.start();
 | |
| }
 |