lux-framework
Version:
Build scalable, Node.js-powered REST APIs with almost no code.
138 lines (119 loc) • 2.93 kB
JavaScript
// @flow
import { LUX_CONSOLE } from '../../constants';
import Database from '../database';
import Logger from '../logger';
import Router from '../router';
import Server from '../server';
import { build, createLoader, closestChild } from '../loader';
import { freezeProps, deepFreezeProps } from '../freezeable';
import ControllerMissingError from '../../errors/controller-missing-error';
import normalizePort from './utils/normalize-port';
import createController from './utils/create-controller';
import createSerializer from './utils/create-serializer';
import type Application, { Application$opts } from './index'; // eslint-disable-line no-unused-vars, max-len
/**
* @private
*/
export default async function initialize<T: Application>(app: T, {
path,
port,
logging,
database,
server: serverConfig
}: Application$opts): Promise<T> {
const load = createLoader(path);
const routes = load('routes');
const models = load('models');
const logger = new Logger(logging);
const normalizedPort = normalizePort(port);
const store = await new Database({
path,
models,
logger,
config: database,
checkMigrations: true
});
const serializers = build(
load('serializers'),
(key, value, parent) => createSerializer(value, {
key,
store,
parent
})
);
models.forEach(model => {
Reflect.defineProperty(model, 'serializer', {
value: closestChild(serializers, model.resourceName),
writable: false,
enumerable: false,
configurable: false
});
});
const controllers = build(
load('controllers'),
(key, value, parent) => createController(value, {
key,
store,
parent,
serializers
})
);
controllers.forEach(controller => {
Reflect.defineProperty(controller, 'controllers', {
value: controllers,
writable: true,
enumerable: false,
configurable: false
});
});
const ApplicationController = controllers.get('application');
if (!ApplicationController) {
throw new ControllerMissingError('application');
}
const router = new Router({
routes,
controllers,
controller: ApplicationController
});
const server = new Server({
router,
logger,
...serverConfig
});
if (!LUX_CONSOLE) {
server.instance.listen(normalizedPort).once('listening', () => {
if (typeof process.send === 'function') {
process.send('ready');
} else {
process.emit('ready');
}
});
}
Object.assign(app, {
logger,
models,
controllers,
serializers
});
deepFreezeProps(app, true,
'logger',
'models',
'controllers',
'serializers'
);
Object.assign(app, {
path,
store,
router,
server,
port: normalizedPort
});
freezeProps(app, false,
'path',
'port',
'store',
'router',
'server'
);
return Object.freeze(app);
}