ultimate-express 1.2.21 → 1.2.22
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/package.json +2 -1
- package/src/index.js +12 -1
- package/src/router.js +39 -40
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultimate-express",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.22",
|
|
4
4
|
"description": "The Ultimate Express. Fastest http server with full Express compatibility, based on uWebSockets.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"express-handlebars": "^8.0.1",
|
|
74
74
|
"express-rate-limit": "^7.4.0",
|
|
75
75
|
"express-session": "^1.18.0",
|
|
76
|
+
"express-subdomain": "^1.0.6",
|
|
76
77
|
"method-override": "^3.0.0",
|
|
77
78
|
"multer": "^1.4.5-lts.1",
|
|
78
79
|
"mustache-express": "^1.3.2",
|
package/src/index.js
CHANGED
|
@@ -26,8 +26,19 @@ try {
|
|
|
26
26
|
uWS._cfg('999999990007');
|
|
27
27
|
} catch (error) {}
|
|
28
28
|
|
|
29
|
+
// converts router to a function and makes it callable
|
|
29
30
|
Application.Router = function(options) {
|
|
30
|
-
|
|
31
|
+
const router = new Router(options);
|
|
32
|
+
const fn = function(req, res, next) {
|
|
33
|
+
router._routeRequest(req, res, 0).then(routed => {
|
|
34
|
+
if(!routed) {
|
|
35
|
+
next();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
Object.assign(fn, router);
|
|
40
|
+
Object.setPrototypeOf(fn, Object.getPrototypeOf(router));
|
|
41
|
+
return fn;
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
Application.request = Request.prototype;
|
package/src/router.js
CHANGED
|
@@ -31,12 +31,11 @@ const methods = [
|
|
|
31
31
|
const supportedUwsMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD', 'CONNECT', 'TRACE'];
|
|
32
32
|
|
|
33
33
|
module.exports = class Router extends EventEmitter {
|
|
34
|
-
#paramCallbacks = new Map();
|
|
35
|
-
#mountpathCache = new Map();
|
|
36
|
-
#paramFunction;
|
|
37
34
|
constructor(settings = {}) {
|
|
38
35
|
super();
|
|
39
36
|
|
|
37
|
+
this._paramCallbacks = new Map();
|
|
38
|
+
this._mountpathCache = new Map();
|
|
40
39
|
this._routes = [];
|
|
41
40
|
this.errorRoute = undefined;
|
|
42
41
|
this.mountpath = '/';
|
|
@@ -61,7 +60,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
61
60
|
|
|
62
61
|
for(let method of methods) {
|
|
63
62
|
this[method] = (path, ...callbacks) => {
|
|
64
|
-
this
|
|
63
|
+
this.createRoute(method.toUpperCase(), path, this, ...callbacks);
|
|
65
64
|
};
|
|
66
65
|
};
|
|
67
66
|
}
|
|
@@ -76,25 +75,25 @@ module.exports = class Router extends EventEmitter {
|
|
|
76
75
|
return res;
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
|
-
return this
|
|
78
|
+
return this.createRoute('GET', path, this, ...callbacks);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
del(path, ...callbacks) {
|
|
83
82
|
deprecated('app.del', 'app.delete');
|
|
84
|
-
return this
|
|
83
|
+
return this.createRoute('DELETE', path, this, ...callbacks);
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
getFullMountpath(req) {
|
|
88
87
|
let fullStack = req._stack.join("");
|
|
89
|
-
let fullMountpath = this
|
|
88
|
+
let fullMountpath = this._mountpathCache.get(fullStack);
|
|
90
89
|
if(!fullMountpath) {
|
|
91
90
|
fullMountpath = patternToRegex(fullStack, true);
|
|
92
|
-
this
|
|
91
|
+
this._mountpathCache.set(fullStack, fullMountpath);
|
|
93
92
|
}
|
|
94
93
|
return fullMountpath;
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
|
|
96
|
+
_pathMatches(route, req) {
|
|
98
97
|
let path = req._opPath;
|
|
99
98
|
let pattern = route.pattern;
|
|
100
99
|
|
|
@@ -115,7 +114,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
115
114
|
return pattern.test(path);
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
|
|
117
|
+
createRoute(method, path, parent = this, ...callbacks) {
|
|
119
118
|
callbacks = callbacks.flat();
|
|
120
119
|
const paths = Array.isArray(path) ? path : [path];
|
|
121
120
|
const routes = [];
|
|
@@ -140,9 +139,9 @@ module.exports = class Router extends EventEmitter {
|
|
|
140
139
|
// normal routes optimization
|
|
141
140
|
if(canBeOptimized(route.path) && route.pattern !== '/*' && !this.parent && this.get('case sensitive routing') && this.uwsApp) {
|
|
142
141
|
if(supportedUwsMethods.includes(method)) {
|
|
143
|
-
const optimizedPath = this
|
|
142
|
+
const optimizedPath = this._optimizeRoute(route, this._routes);
|
|
144
143
|
if(optimizedPath) {
|
|
145
|
-
this
|
|
144
|
+
this._registerUwsRoute(route, optimizedPath);
|
|
146
145
|
}
|
|
147
146
|
}
|
|
148
147
|
}
|
|
@@ -157,7 +156,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
157
156
|
for(let callback of callbacks) {
|
|
158
157
|
if(callback instanceof Router) {
|
|
159
158
|
// get optimized path to router
|
|
160
|
-
let optimizedPathToRouter = this
|
|
159
|
+
let optimizedPathToRouter = this._optimizeRoute(route, this._routes);
|
|
161
160
|
if(!optimizedPathToRouter) {
|
|
162
161
|
break;
|
|
163
162
|
}
|
|
@@ -170,7 +169,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
170
169
|
}
|
|
171
170
|
for(let cbroute of callback._routes) {
|
|
172
171
|
if(!needsConversionToRegex(cbroute.path) && cbroute.path !== '/*' && supportedUwsMethods.includes(cbroute.method)) {
|
|
173
|
-
let optimizedRouterPath = this
|
|
172
|
+
let optimizedRouterPath = this._optimizeRoute(cbroute, callback._routes);
|
|
174
173
|
if(optimizedRouterPath) {
|
|
175
174
|
optimizedRouterPath = optimizedRouterPath.slice(0, -1);
|
|
176
175
|
const optimizedPath = [...optimizedPathToRouter, {
|
|
@@ -182,7 +181,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
182
181
|
}
|
|
183
182
|
]
|
|
184
183
|
}, ...optimizedRouterPath];
|
|
185
|
-
this
|
|
184
|
+
this._registerUwsRoute({
|
|
186
185
|
...cbroute,
|
|
187
186
|
path: route.path + cbroute.path,
|
|
188
187
|
pattern: route.path + cbroute.path,
|
|
@@ -208,7 +207,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
208
207
|
|
|
209
208
|
// if route is a simple string, its possible to pre-calculate its path
|
|
210
209
|
// and then create a native uWS route for it, which is much faster
|
|
211
|
-
|
|
210
|
+
_optimizeRoute(route, routes) {
|
|
212
211
|
const optimizedPath = [];
|
|
213
212
|
|
|
214
213
|
for(let i = 0; i < routes.length; i++) {
|
|
@@ -255,7 +254,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
255
254
|
return { request, response };
|
|
256
255
|
}
|
|
257
256
|
|
|
258
|
-
|
|
257
|
+
_registerUwsRoute(route, optimizedPath) {
|
|
259
258
|
let method = route.method.toLowerCase();
|
|
260
259
|
if(method === 'all') {
|
|
261
260
|
method = 'any';
|
|
@@ -294,7 +293,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
294
293
|
}
|
|
295
294
|
}
|
|
296
295
|
|
|
297
|
-
|
|
296
|
+
_handleError(err, request, response) {
|
|
298
297
|
let errorRoute = this.errorRoute, parent = this.parent;
|
|
299
298
|
while(!errorRoute && parent) {
|
|
300
299
|
errorRoute = parent.errorRoute;
|
|
@@ -317,7 +316,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
317
316
|
this._sendErrorPage(request, response, err, true);
|
|
318
317
|
}
|
|
319
318
|
|
|
320
|
-
|
|
319
|
+
_extractParams(pattern, path) {
|
|
321
320
|
let match = pattern.exec(path);
|
|
322
321
|
const obj = match?.groups ?? {};
|
|
323
322
|
for(let i = 1; i < match.length; i++) {
|
|
@@ -326,7 +325,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
326
325
|
return obj;
|
|
327
326
|
}
|
|
328
327
|
|
|
329
|
-
|
|
328
|
+
_preprocessRequest(req, res, route) {
|
|
330
329
|
req.route = route;
|
|
331
330
|
if(route.optimizedParams) {
|
|
332
331
|
req.params = req.optimizedParams;
|
|
@@ -335,7 +334,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
335
334
|
if(req._stack.length > 0) {
|
|
336
335
|
path = path.replace(this.getFullMountpath(req), '');
|
|
337
336
|
}
|
|
338
|
-
req.params = this
|
|
337
|
+
req.params = this._extractParams(route.pattern, path);
|
|
339
338
|
if(req._paramStack.length > 0) {
|
|
340
339
|
for(let params of req._paramStack) {
|
|
341
340
|
req.params = {...params, ...req.params};
|
|
@@ -350,12 +349,12 @@ module.exports = class Router extends EventEmitter {
|
|
|
350
349
|
}
|
|
351
350
|
}
|
|
352
351
|
|
|
353
|
-
if(this
|
|
352
|
+
if(this._paramCallbacks.size > 0) {
|
|
354
353
|
return new Promise(async resolve => {
|
|
355
354
|
for(let param in req.params) {
|
|
356
|
-
if(this
|
|
355
|
+
if(this._paramCallbacks.has(param) && !req._gotParams.has(param)) {
|
|
357
356
|
req._gotParams.add(param);
|
|
358
|
-
const pcs = this
|
|
357
|
+
const pcs = this._paramCallbacks.get(param);
|
|
359
358
|
for(let i = 0; i < pcs.length; i++) {
|
|
360
359
|
const fn = pcs[i];
|
|
361
360
|
await new Promise(resolveRoute => {
|
|
@@ -364,7 +363,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
364
363
|
if(thingamabob === 'route') {
|
|
365
364
|
return resolve('route');
|
|
366
365
|
} else {
|
|
367
|
-
this
|
|
366
|
+
this._handleError(thingamabob, req, res);
|
|
368
367
|
return resolve(false);
|
|
369
368
|
}
|
|
370
369
|
}
|
|
@@ -386,20 +385,20 @@ module.exports = class Router extends EventEmitter {
|
|
|
386
385
|
param(name, fn) {
|
|
387
386
|
if(typeof name === 'function') {
|
|
388
387
|
deprecated('app.param(callback)', 'app.param(name, callback)', true);
|
|
389
|
-
this
|
|
388
|
+
this._paramFunction = name;
|
|
390
389
|
} else {
|
|
391
|
-
if(this
|
|
392
|
-
if(!this
|
|
393
|
-
this
|
|
390
|
+
if(this._paramFunction) {
|
|
391
|
+
if(!this._paramCallbacks.has(name)) {
|
|
392
|
+
this._paramCallbacks.set(name, []);
|
|
394
393
|
}
|
|
395
|
-
this
|
|
394
|
+
this._paramCallbacks.get(name).push(this._paramFunction(name, fn));
|
|
396
395
|
} else {
|
|
397
396
|
let names = Array.isArray(name) ? name : [name];
|
|
398
397
|
for(let name of names) {
|
|
399
|
-
if(!this
|
|
400
|
-
this
|
|
398
|
+
if(!this._paramCallbacks.has(name)) {
|
|
399
|
+
this._paramCallbacks.set(name, []);
|
|
401
400
|
}
|
|
402
|
-
this
|
|
401
|
+
this._paramCallbacks.get(name).push(fn);
|
|
403
402
|
}
|
|
404
403
|
}
|
|
405
404
|
}
|
|
@@ -407,7 +406,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
407
406
|
|
|
408
407
|
async _routeRequest(req, res, startIndex = 0, routes = this._routes, skipCheck = false, skipUntil) {
|
|
409
408
|
return new Promise(async (resolve) => {
|
|
410
|
-
let routeIndex = skipCheck ? startIndex : findIndexStartingFrom(routes, r => (r.all || r.method === req.method || (r.gettable && req.method === 'HEAD')) && this
|
|
409
|
+
let routeIndex = skipCheck ? startIndex : findIndexStartingFrom(routes, r => (r.all || r.method === req.method || (r.gettable && req.method === 'HEAD')) && this._pathMatches(r, req), startIndex);
|
|
411
410
|
const route = routes[routeIndex];
|
|
412
411
|
if(!route) {
|
|
413
412
|
if(!skipCheck) {
|
|
@@ -418,7 +417,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
418
417
|
return resolve(this._routeRequest(req, res, 0, this._routes, false, skipUntil));
|
|
419
418
|
}
|
|
420
419
|
let callbackindex = 0;
|
|
421
|
-
let continueRoute = await this
|
|
420
|
+
let continueRoute = await this._preprocessRequest(req, res, route);
|
|
422
421
|
if(route.use) {
|
|
423
422
|
req._stack.push(route.path);
|
|
424
423
|
req._opPath =
|
|
@@ -443,7 +442,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
443
442
|
}
|
|
444
443
|
return resolve(this._routeRequest(req, res, routeIndex + 1, routes, skipCheck, skipUntil));
|
|
445
444
|
} else {
|
|
446
|
-
this
|
|
445
|
+
this._handleError(thingamabob, req, res);
|
|
447
446
|
return resolve(true);
|
|
448
447
|
}
|
|
449
448
|
}
|
|
@@ -474,7 +473,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
474
473
|
});
|
|
475
474
|
}
|
|
476
475
|
} catch(err) {
|
|
477
|
-
this
|
|
476
|
+
this._handleError(err, req, res);
|
|
478
477
|
return resolve(true);
|
|
479
478
|
}
|
|
480
479
|
}
|
|
@@ -509,18 +508,18 @@ module.exports = class Router extends EventEmitter {
|
|
|
509
508
|
callback.emit('mount', this);
|
|
510
509
|
}
|
|
511
510
|
}
|
|
512
|
-
this
|
|
511
|
+
this.createRoute('USE', path, this, ...callbacks);
|
|
513
512
|
}
|
|
514
513
|
|
|
515
514
|
route(path) {
|
|
516
515
|
let fns = {};
|
|
517
516
|
for(let method of methods) {
|
|
518
517
|
fns[method] = (...callbacks) => {
|
|
519
|
-
return this
|
|
518
|
+
return this.createRoute(method.toUpperCase(), path, fns, ...callbacks);
|
|
520
519
|
};
|
|
521
520
|
}
|
|
522
521
|
fns.get = (...callbacks) => {
|
|
523
|
-
return this
|
|
522
|
+
return this.createRoute('GET', path, fns, ...callbacks);
|
|
524
523
|
};
|
|
525
524
|
return fns;
|
|
526
525
|
}
|