-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
115 lines (107 loc) · 3.54 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"use strict";
const compose = require("koa-compose");
const RouterPlusClass = require("./router");
const debug = require('debug')('think-router-plus');
const methods = require('methods');
const defaultOptions = {
defaultModule: 'home',
defaultController: 'index',
defaultAction: 'index',
enableDefaultRouter: true,
optimizeHomepageRouter: true,
denyModules: [],
};
function nextController (controller, action, module) {
return (ctx, next) => {
ctx.module = module || defaultOptions.defaultModule;
ctx.controller = controller || defaultOptions.defaultController;
ctx.action = action || defaultOptions.defaultAction;
debug(`RouterParser: path=${ctx.path}, controller=${ctx.controller}, action=${ctx.action}, module=${ctx.module}}`);
return next();
};
}
function parseController (pathname, controllersALL) {
let controller = '';
for (const name of Object.keys(controllersALL)) {
if (name.indexOf('/') === -1) {
break;
}
if (name === pathname || pathname.indexOf(`${name}/`) === 0) {
controller = name;
pathname = pathname.slice(name.length + 1);
break;
}
}
return { controller, pathname };
}
const defaultRouter = (ctx, next, app, opts) => {
const isMultiModule = app.modules.length;
if ((isMultiModule && !ctx.module) || !ctx.controller || !ctx.action) {
let pathname = ctx.path || "";
if (opts.optimizeHomepageRouter && (pathname === '' || pathname === '/')) {
const module = isMultiModule ? opts.defaultModule : '';
const controllerStr = opts.defaultController;
const actionStr = opts.defaultAction;
return nextController(controllerStr, actionStr, module)(ctx, next);
}
pathname = pathname.replace(/^\/|\/$/g, '').replace(/\/{2,}/g, '/');
let m = '';
let controllers = app.controllers;
if (app.modules.length) {
const pos = pathname.indexOf('/');
m = pos === -1 ? pathname : pathname.slice(0, pos);
if (app.modules.indexOf(m) > -1 && m !== 'common' && opts.denyModules.indexOf(m) === -1) {
pathname = pos === -1 ? '' : pathname.slice(pos + 1);
}
else {
m = opts.defaultModule;
}
controllers = controllers[m] || {};
}
let controller = '';
const parseControllerResult = parseController(pathname, controllers);
controller = parseControllerResult.controller;
pathname = parseControllerResult.pathname;
let action = '';
const pathnameArr = pathname.split('/');
if (controller) {
action = pathnameArr[0];
}
else {
controller = pathnameArr[0];
action = pathnameArr[1];
}
return nextController(controller, action, m)(ctx, next);
}
return next();
}
function ThinkRouterPlus (options, app) {
const opts = Object.assign({}, defaultOptions, options);
const routerOpts = Object.assign({}, opts.router);
const allowedOpts = Object.assign({}, opts.allowed);
const router = new RouterPlusClass(routerOpts);
app.routers.forEach((fn) => {
fn(router, app);
});
if (opts.enableDefaultRouter) {
router.all('*', (ctx, next) => {
return defaultRouter(ctx, next, app, opts);
});
}
return (ctx, next) => {
if (ctx.method && methods.includes(ctx.method.toLowerCase())) {
return compose([
router.routes(),
router.allowedMethods(allowedOpts),
(ctx2, next2) => {
ctx2.param(ctx2.params);
return next2();
}
])(ctx, next);
} else {
return defaultRouter(ctx, next, app, opts);
}
};
}
exports.nextController = nextController;
exports.router = ThinkRouterPlus;