@novice1/routing 1.0.11 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/router.js CHANGED
@@ -1,316 +1,315 @@
1
- var ExpressRouter = require("express").Router;
2
- var flatten = require('array-flatten');
3
- var methods = require("methods");
4
- var debug = require('debug')('novice1:router');
5
-
6
- // custom
7
- var Layer = require("./layer");
8
- var Route = require("./route");
9
-
10
- // custom methods
11
- var editLayersMethods = require('./router/editLayersMethods');
12
- var authMethods = require('./router/authMethods');
13
- var validatorsMethods = require('./router/validatorsMethods');
14
- var metaMethods = require('./router/metaMethods');
15
-
16
- // utils
17
- var toArray = require('./utils/toArray');
18
-
19
- /**
20
- * @classdesc Initialize a new `Router` with the given `options`.
21
- * @class
22
- * @augments ExpressRouter express/lib/router
23
- */
24
- function Router() {
25
- var router = ExpressRouter.apply(this, Array.from(arguments));
26
- overrideRouterMethods(router);
27
- addProperties(router);
28
- return router;
29
- }
30
-
31
- /** @inheritdoc */
32
- function route(path) {
33
- // add metadata in route
34
- var meta = {};
35
-
36
- // if path argument is an object with property 'path'
37
- if (path && typeof path === "object" && path.path) {
38
- Object.keys(path).forEach(p => {
39
- switch (p) {
40
- case "path":
41
- break;
42
- case "auth":
43
- meta[p] = Boolean(path[p]);
44
- break;
45
- case "name":
46
- case "description":
47
- meta[p] = path[p];
48
- if (typeof meta[p] !== "string") {
49
- meta[p] = JSON.stringify(meta[p]);
50
- }
51
- break;
52
- case "parameters":
53
- case "responses":
54
- if (path[p] && typeof path[p] === 'object')
55
- meta[p] = path[p];
56
- break;
57
- case "tags":
58
- if (!meta.tags) {
59
- meta[p] = [];
60
- }
61
- toArray(path[p], "string").forEach(s => {
62
- meta[p].push(s);
63
- });
64
- break;
65
- case "afterAuth":
66
- case "preValidators":
67
- case "preValidators":
68
- case "preValidation":
69
- if (!meta.preValidators) {
70
- meta.preValidators = [];
71
- }
72
- toArray(path[p], "function").forEach(s => {
73
- meta.preValidators.push(s);
74
- });
75
- if(!meta.preValidators.length) {
76
- delete meta.preValidators;
77
- }
78
- break;
79
- default:
80
- // meta[p] = path[p];
81
- break;
82
- }
83
- });
84
-
85
- path = path.path;
86
- }
87
-
88
- // initialize route
89
- var route = new Route(path);
90
- route.meta = meta;
91
-
92
- // initialize layer
93
- var layer = new Layer(
94
- path,
95
- {
96
- sensitive: this.caseSensitive,
97
- strict: this.strict,
98
- end: true
99
- },
100
- route.dispatch.bind(route)
101
- );
102
-
103
- layer.route = route;
104
-
105
- this.stack.push(layer);
106
-
107
- /**
108
- * @todo code should be to work like '.route(...).get(...)'
109
- // if there are:
110
- // - 'auth' handlers
111
- // - 'validators' handlers
112
- [
113
- {
114
- prop: '_auth',
115
- action: 'setAuth',
116
- prop2: '_ifNoAuth',
117
- action2: 'setAuthIfNone'
118
- },
119
- {
120
- prop: '_validators',
121
- action: 'setValidators',
122
- prop2: '_ifNoValidators',
123
- action2: 'setValidatorsIfNone'
124
- }
125
- ].forEach((v) => {
126
- var executeAction = function (p, a) {
127
- var handles = this[p].concat([]);
128
- // add layer options
129
- handles.unshift({
130
- sensitive: this.caseSensitive,
131
- strict: this.strict,
132
- end: true
133
- });
134
- route[a].apply(route, handles);
135
- };
136
- if (this[v.prop].length) {
137
- executeAction(v.prop, v.action);
138
- } else if (v.prop2 && this[v.prop2].length) {
139
- executeAction(v.prop2, v.action2);
140
- }
141
- });
142
- */
143
-
144
- return route;
145
- }
146
-
147
- /** @inheritdoc */
148
- function use(fn) {
149
- var offset = 0;
150
- var path = '/';
151
-
152
- // default path to '/'
153
- // disambiguate router.use([fn])
154
- if (typeof fn !== 'function') {
155
- var arg = fn;
156
-
157
- while (Array.isArray(arg) && arg.length !== 0) {
158
- arg = arg[0];
159
- }
160
-
161
- // first arg is the path
162
- if (typeof arg !== 'function') {
163
- offset = 1;
164
- path = fn;
165
- }
166
- }
167
-
168
- var callbacks = flatten(Array.prototype.slice.call(arguments, offset));
169
-
170
- if (callbacks.length === 0) {
171
- throw new TypeError('Router.use() requires a middleware function')
172
- }
173
-
174
- for (var i = 0; i < callbacks.length; i++) {
175
- var fn = callbacks[i];
176
-
177
- if (typeof fn !== 'function') {
178
- throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
179
- }
180
-
181
- // add the middleware
182
- debug('use %o %s', path, fn.name || '<anonymous>')
183
-
184
- var layer = new Layer(path, {
185
- sensitive: this.caseSensitive,
186
- strict: false,
187
- end: false
188
- }, fn);
189
-
190
- layer.route = undefined;
191
-
192
- this.stack.push(layer);
193
- }
194
-
195
- return this;
196
- };
197
-
198
- /**
199
- * @description Override methods of a router.
200
- * @param {*} router
201
- */
202
- function overrideRouterMethods(router) {
203
- // override express Router's 'route' method
204
- router.route = route;
205
- router.use = use;
206
-
207
- // override methods
208
- methods.concat('all').forEach(function(method){
209
- router[method] = function(path){
210
- var route = this.route(path)
211
- route[method].apply(route, Array.prototype.slice.call(arguments, 1));
212
-
213
- [
214
- // auth
215
- {
216
- prop: '_auth',
217
- action: 'setAuth',
218
- prop2: '_ifNoAuth' // @todo make use of it ?
219
- },
220
- // before validators / after auth
221
- {
222
- metaProp: 'preValidators',
223
- action: 'setPreValidators'
224
- },
225
- // validators
226
- {
227
- prop: '_validators',
228
- action: 'setValidators',
229
- prop2: '_ifNoValidators' // @todo make use of it ?
230
- }
231
- ].forEach((v) => {
232
- var executeAction = (container, p, a) => {
233
- var handles = container[p].concat([]);
234
- // add layer options
235
- handles.unshift({
236
- sensitive: this.caseSensitive,
237
- strict: this.strict,
238
- end: true
239
- });
240
- route[a].apply(route, handles);
241
- };
242
- if (v.metaProp && route.meta[v.metaProp] &&route.meta[v.metaProp].length) {
243
- executeAction(route.meta, v.metaProp, v.action);
244
- delete route.meta[v.metaProp];
245
- } else if (v.prop && this[v.prop].length) {
246
- executeAction(this, v.prop, v.action);
247
- }
248
- });
249
-
250
- return this;
251
- };
252
- });
253
- }
254
-
255
- /**
256
- * @description Add properties to a router.
257
- * @param {*} router
258
- */
259
- function addProperties(router) {
260
- // add '_auth' property to store handlers
261
- Object.defineProperty(router, '_auth', {
262
- value: [],
263
- writable: true
264
- });
265
- // add '_validators' property to store handlers
266
- Object.defineProperty(router, '_validators', {
267
- value: [],
268
- writable: true
269
- });
270
- // add '_ifNoAuth' property boolean
271
- Object.defineProperty(router, '_ifNoAuth', {
272
- value: false,
273
- writable: true
274
- });
275
- // add '_ifNoValidators' property boolean
276
- Object.defineProperty(router, '_ifNoValidators', {
277
- value: false,
278
- writable: true
279
- });
280
-
281
- // add 'setAuthHandlers' method (stores handlers into '_auth')
282
- Object.defineProperty(router, 'setAuthHandlers', {
283
- value: authMethods.setAuthHandlers,
284
- writable: true
285
- });
286
- // add 'setAuthHandlersIfNone' method (stores handlers into '_auth')
287
- Object.defineProperty(router, 'setAuthHandlersIfNone', {
288
- value: authMethods.setAuthHandlersIfNone,
289
- writable: true
290
- });
291
-
292
- // add 'setValidators' method (stores handlers into '_validators')
293
- Object.defineProperty(router, 'setValidators', {
294
- value: validatorsMethods.setValidators,
295
- writable: true
296
- });
297
- // add 'setValidatorsIfNone' method (stores handlers into '_validators')
298
- Object.defineProperty(router, 'setValidatorsIfNone', {
299
- value: validatorsMethods.setValidatorsIfNone,
300
- writable: true
301
- });
302
-
303
- // add 'editLayers' method
304
- Object.defineProperty(router, 'editLayers', {
305
- value: editLayersMethods.editLayers,
306
- writable: true
307
- });
308
-
309
- // add 'getMeta' method
310
- Object.defineProperty(router, 'getMeta', {
311
- value: metaMethods.getMeta,
312
- writable: true
313
- });
314
- }
315
-
1
+ var ExpressRouter = require("express").Router;
2
+ var { flatten } = require('array-flatten');
3
+ var methods = require("methods");
4
+ var debug = require('debug')('novice1:router');
5
+
6
+ // custom
7
+ var Layer = require("./layer");
8
+ var Route = require("./route");
9
+
10
+ // custom methods
11
+ var editLayersMethods = require('./router/editLayersMethods');
12
+ var authMethods = require('./router/authMethods');
13
+ var validatorsMethods = require('./router/validatorsMethods');
14
+ var metaMethods = require('./router/metaMethods');
15
+
16
+ // utils
17
+ var toArray = require('./utils/toArray');
18
+
19
+ /**
20
+ * @classdesc Initialize a new `Router` with the given `options`.
21
+ * @class
22
+ * @augments ExpressRouter express/lib/router
23
+ */
24
+ function Router() {
25
+ var router = ExpressRouter.apply(this, Array.from(arguments));
26
+ overrideRouterMethods(router);
27
+ addProperties(router);
28
+ return router;
29
+ }
30
+
31
+ /** @inheritdoc */
32
+ function route(path) {
33
+ // add metadata in route
34
+ var meta = {};
35
+
36
+ // if path argument is an object with property 'path'
37
+ if (path && typeof path === "object" && !Array.isArray(path) && path.path) {
38
+ Object.keys(path).forEach(p => {
39
+ switch (p) {
40
+ case "path":
41
+ break;
42
+ case "auth":
43
+ meta[p] = Boolean(path[p]);
44
+ break;
45
+ case "name":
46
+ case "description":
47
+ meta[p] = path[p];
48
+ if (typeof meta[p] !== "string") {
49
+ meta[p] = JSON.stringify(meta[p]);
50
+ }
51
+ break;
52
+ case "parameters":
53
+ case "responses":
54
+ if (path[p] && typeof path[p] === 'object')
55
+ meta[p] = path[p];
56
+ break;
57
+ case "tags":
58
+ if (!meta.tags) {
59
+ meta[p] = [];
60
+ }
61
+ toArray(path[p], "string").forEach(s => {
62
+ meta[p].push(s);
63
+ });
64
+ break;
65
+ case "afterAuth":
66
+ case "preValidators":
67
+ case "preValidation":
68
+ if (!meta.preValidators) {
69
+ meta.preValidators = [];
70
+ }
71
+ toArray(path[p], "function").forEach(s => {
72
+ meta.preValidators.push(s);
73
+ });
74
+ if(!meta.preValidators.length) {
75
+ delete meta.preValidators;
76
+ }
77
+ break;
78
+ default:
79
+ // meta[p] = path[p];
80
+ break;
81
+ }
82
+ });
83
+
84
+ path = path.path;
85
+ }
86
+
87
+ // initialize route
88
+ var route = new Route(path);
89
+ route.meta = meta;
90
+
91
+ // initialize layer
92
+ var layer = new Layer(
93
+ path,
94
+ {
95
+ sensitive: this.caseSensitive,
96
+ strict: this.strict,
97
+ end: true
98
+ },
99
+ route.dispatch.bind(route)
100
+ );
101
+
102
+ layer.route = route;
103
+
104
+ this.stack.push(layer);
105
+
106
+ /**
107
+ * @todo code should be to work like '.route(...).get(...)'
108
+ // if there are:
109
+ // - 'auth' handlers
110
+ // - 'validators' handlers
111
+ [
112
+ {
113
+ prop: '_auth',
114
+ action: 'setAuth',
115
+ prop2: '_ifNoAuth',
116
+ action2: 'setAuthIfNone'
117
+ },
118
+ {
119
+ prop: '_validators',
120
+ action: 'setValidators',
121
+ prop2: '_ifNoValidators',
122
+ action2: 'setValidatorsIfNone'
123
+ }
124
+ ].forEach((v) => {
125
+ var executeAction = function (p, a) {
126
+ var handles = this[p].concat([]);
127
+ // add layer options
128
+ handles.unshift({
129
+ sensitive: this.caseSensitive,
130
+ strict: this.strict,
131
+ end: true
132
+ });
133
+ route[a].apply(route, handles);
134
+ };
135
+ if (this[v.prop].length) {
136
+ executeAction(v.prop, v.action);
137
+ } else if (v.prop2 && this[v.prop2].length) {
138
+ executeAction(v.prop2, v.action2);
139
+ }
140
+ });
141
+ */
142
+
143
+ return route;
144
+ }
145
+
146
+ /** @inheritdoc */
147
+ function use(fn) {
148
+ var offset = 0;
149
+ var path = '/';
150
+
151
+ // default path to '/'
152
+ // disambiguate router.use([fn])
153
+ if (typeof fn !== 'function') {
154
+ var arg = fn;
155
+
156
+ while (Array.isArray(arg) && arg.length !== 0) {
157
+ arg = arg[0];
158
+ }
159
+
160
+ // first arg is the path
161
+ if (typeof arg !== 'function') {
162
+ offset = 1;
163
+ path = fn;
164
+ }
165
+ }
166
+
167
+ var callbacks = flatten(Array.prototype.slice.call(arguments, offset));
168
+
169
+ if (callbacks.length === 0) {
170
+ throw new TypeError('Router.use() requires a middleware function')
171
+ }
172
+
173
+ for (var i = 0; i < callbacks.length; i++) {
174
+ var fn = callbacks[i];
175
+
176
+ if (typeof fn !== 'function') {
177
+ throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
178
+ }
179
+
180
+ // add the middleware
181
+ debug('use %o %s', path, fn.name || '<anonymous>')
182
+
183
+ var layer = new Layer(path, {
184
+ sensitive: this.caseSensitive,
185
+ strict: false,
186
+ end: false
187
+ }, fn);
188
+
189
+ layer.route = undefined;
190
+
191
+ this.stack.push(layer);
192
+ }
193
+
194
+ return this;
195
+ };
196
+
197
+ /**
198
+ * @description Override methods of a router.
199
+ * @param {*} router
200
+ */
201
+ function overrideRouterMethods(router) {
202
+ // override express Router's 'route' method
203
+ router.route = route;
204
+ router.use = use;
205
+
206
+ // override methods
207
+ methods.concat('all').forEach(function(method){
208
+ router[method] = function(path){
209
+ var route = this.route(path)
210
+ route[method].apply(route, Array.prototype.slice.call(arguments, 1));
211
+
212
+ [
213
+ // auth
214
+ {
215
+ prop: '_auth',
216
+ action: 'setAuth',
217
+ prop2: '_ifNoAuth' // @todo make use of it ?
218
+ },
219
+ // before validators / after auth
220
+ {
221
+ metaProp: 'preValidators',
222
+ action: 'setPreValidators'
223
+ },
224
+ // validators
225
+ {
226
+ prop: '_validators',
227
+ action: 'setValidators',
228
+ prop2: '_ifNoValidators' // @todo make use of it ?
229
+ }
230
+ ].forEach((v) => {
231
+ var executeAction = (container, p, a) => {
232
+ var handles = container[p].concat([]);
233
+ // add layer options
234
+ handles.unshift({
235
+ sensitive: this.caseSensitive,
236
+ strict: this.strict,
237
+ end: true
238
+ });
239
+ route[a].apply(route, handles);
240
+ };
241
+ if (v.metaProp && route.meta[v.metaProp] &&route.meta[v.metaProp].length) {
242
+ executeAction(route.meta, v.metaProp, v.action);
243
+ delete route.meta[v.metaProp];
244
+ } else if (v.prop && this[v.prop].length) {
245
+ executeAction(this, v.prop, v.action);
246
+ }
247
+ });
248
+
249
+ return this;
250
+ };
251
+ });
252
+ }
253
+
254
+ /**
255
+ * @description Add properties to a router.
256
+ * @param {*} router
257
+ */
258
+ function addProperties(router) {
259
+ // add '_auth' property to store handlers
260
+ Object.defineProperty(router, '_auth', {
261
+ value: [],
262
+ writable: true
263
+ });
264
+ // add '_validators' property to store handlers
265
+ Object.defineProperty(router, '_validators', {
266
+ value: [],
267
+ writable: true
268
+ });
269
+ // add '_ifNoAuth' property boolean
270
+ Object.defineProperty(router, '_ifNoAuth', {
271
+ value: false,
272
+ writable: true
273
+ });
274
+ // add '_ifNoValidators' property boolean
275
+ Object.defineProperty(router, '_ifNoValidators', {
276
+ value: false,
277
+ writable: true
278
+ });
279
+
280
+ // add 'setAuthHandlers' method (stores handlers into '_auth')
281
+ Object.defineProperty(router, 'setAuthHandlers', {
282
+ value: authMethods.setAuthHandlers,
283
+ writable: true
284
+ });
285
+ // add 'setAuthHandlersIfNone' method (stores handlers into '_auth')
286
+ Object.defineProperty(router, 'setAuthHandlersIfNone', {
287
+ value: authMethods.setAuthHandlersIfNone,
288
+ writable: true
289
+ });
290
+
291
+ // add 'setValidators' method (stores handlers into '_validators')
292
+ Object.defineProperty(router, 'setValidators', {
293
+ value: validatorsMethods.setValidators,
294
+ writable: true
295
+ });
296
+ // add 'setValidatorsIfNone' method (stores handlers into '_validators')
297
+ Object.defineProperty(router, 'setValidatorsIfNone', {
298
+ value: validatorsMethods.setValidatorsIfNone,
299
+ writable: true
300
+ });
301
+
302
+ // add 'editLayers' method
303
+ Object.defineProperty(router, 'editLayers', {
304
+ value: editLayersMethods.editLayers,
305
+ writable: true
306
+ });
307
+
308
+ // add 'getMeta' method
309
+ Object.defineProperty(router, 'getMeta', {
310
+ value: metaMethods.getMeta,
311
+ writable: true
312
+ });
313
+ }
314
+
316
315
  module.exports = Router;