forked from go-ike/ike-router
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
185 lines (160 loc) · 5.36 KB
/
index.js
File metadata and controls
185 lines (160 loc) · 5.36 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
const Express = require('express');
class IkeRouter {
/**
* Instantiates the main properties
* Creates the clasess' controllers path, router instance and
* a resource map
*/
constructor() {
this.controllerPath = './controllers/';
this.router = Express.Router();
this.resources = [];
}
/**
* Creates a get route
* @param {String} path The URL path
* @param {String} shorthand The shorthand controller#method notation
* @param {Object} options Routing options
*/
get(path, shorthand, options) {
options = this._parseOptions(shorthand, options);
this.router.get(path, this._callAction(options));
}
/**
* Creates a post route
* @param {String} path The URL path
* @param {String} shorthand The shorthand controller#method notation
* @param {Object} options Routing options
*/
post(path, shorthand, options) {
options = this._parseOptions(shorthand, options);
this.router.post(path, this._callAction(options));
}
/**
* Creates a put route
* @param {String} path The URL path
* @param {String} shorthand The shorthand controller#method notation
* @param {Object} options Routing options
*/
put(path, shorthand, options) {
options = this._parseOptions(shorthand, options);
this.router.put(path, this._callAction(options));
}
/**
* Creates a delete route
* @param {String} path The URL path
* @param {String} shorthand The shorthand controller#method notation
* @param {Object} options Routing options
*/
delete(path, shorthand, options) {
options = this._parseOptions(shorthand, options);
this.router.delete(path, this._callAction(options));
}
/**
* Creates a routing resource
* @param {String} resourceName The name of the resource
* @param {String} controller The name of the controller, if different from the resource
*/
resource(resourceName, controller) {
let resourceRouter = Express.Router();
if(!controller) controller = resourceName;
this.resources.push(resourceName);
resourceRouter.get('/',
this._callAction({ controller: controller, method: 'index' }));
resourceRouter.get('/new',
this._callAction({ controller: controller, method: 'new' }));
resourceRouter.post('/',
this._callAction({ controller: controller, method: 'create' }));
resourceRouter.get('/:id',
this._callAction({ controller: controller, method: 'show' }));
resourceRouter.get('/:id/edit',
this._callAction({ controller: controller, method: 'edit' }));
resourceRouter.put('/:id',
this._callAction({ controller: controller, method: 'update' }));
resourceRouter.delete('/:id',
this._callAction({ controller: controller, method: 'destroy' }));
this.router.use('/'+resourceName, resourceRouter);
}
/**
* Mounts a middleware function to all routes
* @param {Function} middleware The express-compliant middleware
*/
mountMiddleware(middleware) {
this.router.use(middleware)
}
/**
* Returns the express.Router() instance to be used by express
* @return {express.Router()}
*/
draw() {
return this.router;
}
pathToResource(path, action, parameters) {
if(typeof action === 'object') {
parameters = action;
action = undefined;
}
if(this.resources.indexOf(path) == -1) // Error if resource has not been defined
throw new Error('RESOURCE_DOESNT_EXIST');
if(action === undefined || (action === 'index' && parameters == undefined))
return '/'+path;
else if((action === undefined && parameters && parameters.id) || (action === 'show' && parameters.id))
return '/'+path+'/'+parameters.id;
else if(action === 'new')
return '/'+path+'/new';
else if(action === 'edit' && parameters && parameters.id)
return '/'+path+'/'+parameters.id+'/edit';
}
/**
* Sets the routers' controllers path
* @param {String} path The path to find the controllers
*/
setControllerPath(path) {
this.controllerPath = path;
}
/* private */
/**
* Parse the shorthand and route options into a standard object,
* to be used by the routes.
* @param {String} shorthand The shorthand controller#method notation
* @param {Object} options Routing options
* @return {Object}
*/
_parseOptions(shorthand, options = {}) {
if(typeof shorthand === 'object') options = shorthand;
else {
let shorthandOptions = shorthand.split('#');
options.controller = shorthandOptions[0];
options.method = shorthandOptions[1];
}
if(!options.middleware)
options.middleware = []
if(!Array.isArray(options.middleware))
options.middleware = [options.middleware]
return options;
}
/**
* Calls the method of the controller, on the context of the instance,
* passing express' req and res params
* @param {Object} options Routing options
* @return {Function}
*/
_callAction(options) {
const controller = new(require(this.controllerPath + options.controller + '.controller.js'))();
const method = controller[options.method];
const call = (req, res) => { method.call(controller, req, res) }
return [...options.middleware, call];
}
}
/**
* SINGLETON BEHAVIOUR
* Instead of returning the class, a single instance is returned.
* This preserves the state of the routes, and make pathTo()
* available even outside the main routing file in the host app.
*/
const instance = new IkeRouter();
function singleton(controllerPath) {
if(controllerPath) instance.setControllerPath(controllerPath);
return instance;
}
module.exports = singleton;