Skip to content
This repository was archived by the owner on Sep 26, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions lib/utils/loadModule.js

This file was deleted.

39 changes: 2 additions & 37 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
{
"name": "avada",
"version": "1.5.0-beta.1",
"description": "A nodejs web framework basedon koa.",
"main": "lib/index.js",
"scripts": {
"lint": "eslint lib",
"test": "echo pass!",
"ci": "npm run lint && npm run test"
},
"dependencies": {
"@koa/cors": "^3.1.0",
"assert": "^2.0.0",
"co-busboy": "^1.4.1",
"debug": "^4.3.1",
"ejs": "^3.1.5",
"inflection": "^1.12.0",
"koa": "^2.13.0",
"koa-bodyparser": "^4.3.0",
"koa-compress": "^5.0.1",
"koa-conditional-get": "^3.0.0",
"koa-csrf": "^3.0.8",
"koa-etag": "^4.0.0",
"koa-favicon": "^2.1.0",
"koa-response-time": "^2.1.0",
"koa-session": "^6.1.0",
"koa-static": "^5.0.0",
"minimatch": "^3.0.4",
"mz": "^2.7.0",
"path-to-regexp": "^6.2.0",
"ramda": "^0.27.1"
},
"devDependencies": {
"eslint": "^7.14.0",
"eslint-config-bce": "^7.0.0"
},
"publishConfig": {
"registry": "https://registry.npmjs.org"
},
"description": "A nodejs web framework",
"private": true,
"repository": "git@github.com:bencode/avada.git",
"author": "bencode <bencode@163.com>",
"license": "MIT"
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions packages/avada/lib/components/container/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = function ControllerComponent(app) {
app.Container = new Map();
};

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs');
const pathUtil = require('path');
const loadModule = require('../../utils/loadModule');
const { tryLoadModule } = require('../../utils/module');
const scanAppModules = require('../../utils/scanAppModules');
const ControllerContainer = require('./ControllerContainer');


Expand All @@ -10,7 +10,7 @@ module.exports = function ControllerComponent(app, settings) {
const controllerRoot = config.controllerRoot || pathUtil.join(appRoot, 'controllers');

const container = new ControllerContainer();
app.controller = container.add.bind(container);
app.Controller = container;

setupControllers(container, { controllerRoot });

Expand All @@ -20,12 +20,10 @@ module.exports = function ControllerComponent(app, settings) {


function setupControllers(controller, { controllerRoot }) {
const rHidden = /^\..+/;
const list = fs.readdirSync(controllerRoot)
.filter(name => !rHidden.test(name));
const list = scanAppModules(controllerRoot);
for (const file of list) {
const path = pathUtil.join(controllerRoot, file);
const mod = loadModule(path);
const mod = tryLoadModule(path);
if (mod) {
const name = pathUtil.basename(file, pathUtil.extname(file));
controller.add(name, mod);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ module.exports = function createErrorHandler({ env }) {
return next().catch(e => {
const status = e.status || 500;
ctx.app.emit('error', e, ctx);
global.console.error(e);
const message = getMessage(env, e);
ctx.status = status;
if (ctx.is('application/json') ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module.exports = class Router {
* - query {Object}
*/
route(path, request) {
debug('try route %s', path);
if (this.routes.length === 0) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
const pathUtil = require('path');
const debug = require('debug')('avada:router');
const loadModule = require('../../utils/loadModule');
const { tryLoadModule } = require('../../utils/module');
const pathToRegexp = require('../../utils/pathToRegexp');
const parse = require('./parse');
const AppRouter = require('./Router');


module.exports = function RouterComponent(app, settings) {
const router = new AppRouter();
app.router = router.add.bind(router);
app.Router = router;

const appRoot = settings.applicationRoot;
const config = settings.router || {};
const configRoot = config.configPath || pathUtil.join(appRoot, 'router');

const fn = loadModule(configRoot);
const { middlewares, routes } = parse(fn);

setupMiddlewares(app, middlewares);
setupRules(router, routes);
const fn = tryLoadModule(configRoot, { checkExists: false });
if (typeof fn === 'function') {
const { middlewares, routes } = parse(fn);
setupMiddlewares(app, middlewares);
setupRules(router, routes);
} else {
global.console.error('router file not exits');
}

app.use(createRouter(router), { level: 2 });
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const fs = require('fs');
const pathUtil = require('path');
const loadModule = require('../../utils/loadModule');
const scanAppModules = require('../../utils/scanAppModules');
const { tryLoadModule } = require('../../utils/module');
const ServiceContainer = require('./ServiceContainer');


module.exports = function ServiceComponent(app, settings) {
const container = new ServiceContainer(app);
app.service = container.add.bind(container);
app.Service = container;

const appRoot = settings.applicationRoot;
const config = settings.service || {};
Expand All @@ -22,16 +22,13 @@ module.exports = function ServiceComponent(app, settings) {


function setupServices(container, { serviceRoot }) {
const rHidden = /^\..+/;
const list = fs.readdirSync(serviceRoot)
.filter(name => !rHidden.test(name));
const list = scanAppModules(serviceRoot);
for (const file of list) {
const name = pathUtil.basename(file, pathUtil.extname(file));
const path = pathUtil.join(serviceRoot, file);
const mod = loadModule(path);
const service = mod && mod.default ? mod.default : mod;
const service = tryLoadModule(path);
if (service && typeof service === 'function') {
container.add(name, mod);
container.add(name, service);
}
}
}
12 changes: 12 additions & 0 deletions packages/avada/lib/components/verify/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const chalk = require('chalk');

module.exports = function VerifyComponent(app) {
const { routes } = app.Router;
for (const route of routes) {
const { rule } = route;
if (!app.Controller.has(rule.module, rule.action)) {
global.console.error(chalk.red(`action not exists: ${rule.module}#${rule.action}`));
global.console.error('route detail %o', route);
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ const ViewContainer = require('./ViewContainer');
module.exports = function ViewComponent(app, settings) {
const env = settings.env;
const container = new ViewContainer({ env });
app.View = container;

app.engine = container.engine.bind(container);
app.view = container.add.bind(container);
app.context.render = async function(name, data) {
this.body = await container.render(name, data);
};

const config = settings.view || {};
const viewRoot = config.viewRoot || pathUtil.join(settings.appRoot, 'views');
const appRoot = settings.applicationRoot;
const viewRoot = config.viewRoot || pathUtil.join(appRoot, 'views');
installDefaultEngine(container, { env, config });
setupViews(container, { env, viewRoot });
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const { v4: uuid } = require('uuid');
const debug = require('debug')('avada:web');
const util = require('./util');


module.exports = function WebComponent(app, settings) {
const config = settings.web || {};
if (config.keys) {
initKeys(app, config.keys);
}
initKeys(app, config.keys);

require('./params')(app);

Expand All @@ -21,6 +20,10 @@ module.exports = function WebComponent(app, settings) {
// private

function initKeys(app, keys) {
if (!keys) {
keys = uuid();
global.console.warn('app.keys missing, auto gen: %s', keys);
}
keys = typeof keys === 'string' ? [keys] : keys;
app.keys = keys;
}
Expand Down
36 changes: 33 additions & 3 deletions lib/index.js → packages/avada/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ const debug = require('debug')('avada:boot');


const Components = [
'core', 'web', 'router', 'controller', 'service', 'view'
'core', 'web', 'container',
'router', 'controller', 'service', 'view',
'verify'
];


module.exports = function(config) {
config = normalizeConfig(config);
const app = new Koa();
let started = false;
let stopped = false;

const list = [];
for (const name of Components) {
Expand All @@ -20,7 +25,13 @@ module.exports = function(config) {
}

app.start = async(opts = {}) => {
if (started) {
debug('already started, ignore');
return null;
}

debug('app.start');
started = true;
for (const item of list) {
if (typeof item.start === 'function') {
debug('start component: %s', item.name);
Expand All @@ -31,13 +42,24 @@ module.exports = function(config) {
const { listen = true } = opts;
if (listen) {
const port = (config.server || {}).port || 3000;
const server = app.listen(port);
global.console.log(`server listen at: ${port}`);
const server = app.listen(port, () => {
global.console.log(`server listen at: ${port}`);
});
return server;
}
return null;
};

app.stop = async() => {
if (!started) {
throw new Error('app not started');
}
if (stopped) {
debug('app stopped, ignore');
return;
}
stopped = true;

debug('app.stop');
for (const item of list.reverse()) {
if (typeof item.stop === 'function') {
Expand Down Expand Up @@ -68,3 +90,11 @@ function makeArray(list) {
return (list === undefined || list === null) ? [] :
Array.isArray(list) ? list : [list];
}

function normalizeConfig(config) {
return {
env: process.env.NODE_ENV || 'development',
applicationRoot: process.cwd(),
...config
};
}
27 changes: 27 additions & 0 deletions packages/avada/lib/utils/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const fs = require('fs');

function tryLoadModule(path, opts = { checkExists: true }) {
if (checkModule(path, opts.checkExists)) {
return loadModule(path);
}
return null;
}

function checkModule(path, checkExists) {
if (checkExists && !fs.existsSync(path)) {
return false;
}
try {
require.resolve(path);
return true;
} catch (e) {
return false;
}
}

function loadModule(path) {
const mod = require(path);
return ('default' in mod) ? mod.default : mod;
}

module.exports = { tryLoadModule, checkModule, loadModule };
31 changes: 31 additions & 0 deletions packages/avada/lib/utils/scanAppModules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('fs');
const pathUtil = require('path');

module.exports = function scanAppModules(dir) {
if (!fs.existsSync(dir)) {
return [];
}
const list = fs.readdirSync(dir);
return list.filter(name => isAppModule(name, dir));
};

function isAppModule(name, dir) {
const rHidden = /^\./;
// ignore hidden file/dir
if (rHidden.test(name)) {
return false;
}

// valid js identify
const rName = /^[a-zA-Z]\w*$/;
const path = pathUtil.join(dir, name);
const stats = fs.statSync(path);
if (stats.isDirectory()) {
return rName.test(name);
}
if (stats.isFile()) {
const basename = pathUtil.basename(name, pathUtil.extname(name));
return rName.test(basename);
}
return false;
}
Loading