ultimate-express 2.0.13 → 2.0.15
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 +13 -13
- package/src/declarative.js +1 -1
- package/src/request.js +7 -2
- package/src/response.js +3 -2
- package/src/router.js +20 -11
- package/src/types.d.ts +8 -1
- package/src/utils.js +3 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultimate-express",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.15",
|
|
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": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"accepts": "^1.3.8",
|
|
48
48
|
"acorn": "^8.15.0",
|
|
49
49
|
"bytes": "^3.1.2",
|
|
50
|
-
"cookie": "^1.
|
|
50
|
+
"cookie": "^1.1.1",
|
|
51
51
|
"cookie-signature": "^1.2.2",
|
|
52
52
|
"encodeurl": "^2.0.0",
|
|
53
53
|
"etag": "^1.8.1",
|
|
@@ -57,35 +57,35 @@
|
|
|
57
57
|
"mime-types": "^2.1.35",
|
|
58
58
|
"ms": "^2.1.3",
|
|
59
59
|
"proxy-addr": "^2.0.7",
|
|
60
|
-
"qs": "^6.14.
|
|
60
|
+
"qs": "^6.14.1",
|
|
61
61
|
"range-parser": "^1.2.1",
|
|
62
62
|
"statuses": "^2.0.2",
|
|
63
63
|
"tseep": "^1.3.1",
|
|
64
64
|
"type-is": "^2.0.1",
|
|
65
|
-
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.
|
|
65
|
+
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.56.0",
|
|
66
66
|
"vary": "^1.1.2"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@codechecks/client": "^0.1.12",
|
|
70
|
-
"better-sse": "^0.
|
|
71
|
-
"body-parser": "^2.2.
|
|
70
|
+
"better-sse": "^0.16.1",
|
|
71
|
+
"body-parser": "^2.2.1",
|
|
72
72
|
"compression": "^1.8.1",
|
|
73
73
|
"cookie-parser": "^1.4.7",
|
|
74
74
|
"cookie-session": "^2.1.1",
|
|
75
75
|
"cors": "^2.8.5",
|
|
76
76
|
"ejs": "^3.1.10",
|
|
77
|
-
"errorhandler": "^1.5.
|
|
78
|
-
"eventsource": "^4.
|
|
77
|
+
"errorhandler": "^1.5.2",
|
|
78
|
+
"eventsource": "^4.1.0",
|
|
79
79
|
"exit-hook": "^2.2.1",
|
|
80
80
|
"express": "latest-4",
|
|
81
81
|
"express-art-template": "^1.0.1",
|
|
82
82
|
"express-async-errors": "^3.1.1",
|
|
83
83
|
"express-dot-engine": "^1.0.8",
|
|
84
84
|
"express-fileupload": "^1.5.2",
|
|
85
|
-
"express-handlebars": "^8.0.
|
|
85
|
+
"express-handlebars": "^8.0.4",
|
|
86
86
|
"express-http-proxy": "^2.1.2",
|
|
87
87
|
"express-mongo-sanitize": "^2.2.0",
|
|
88
|
-
"express-rate-limit": "^8.1
|
|
88
|
+
"express-rate-limit": "^8.2.1",
|
|
89
89
|
"express-session": "^1.18.2",
|
|
90
90
|
"express-subdomain": "^1.0.6",
|
|
91
91
|
"graphql-http": "^1.22.4",
|
|
@@ -93,17 +93,17 @@
|
|
|
93
93
|
"http-proxy-middleware": "^3.0.5",
|
|
94
94
|
"method-override": "^3.0.0",
|
|
95
95
|
"morgan": "^1.10.1",
|
|
96
|
-
"multer": "^
|
|
96
|
+
"multer": "^2.0.2",
|
|
97
97
|
"mustache-express": "^1.3.2",
|
|
98
98
|
"nyc": "^17.1.0",
|
|
99
99
|
"pako": "^2.1.0",
|
|
100
100
|
"passport": "^0.7.0",
|
|
101
101
|
"passport-local": "^1.0.0",
|
|
102
|
-
"pkg-pr-new": "^0.0.
|
|
102
|
+
"pkg-pr-new": "^0.0.62",
|
|
103
103
|
"pug": "^3.0.3",
|
|
104
104
|
"response-time": "^2.3.4",
|
|
105
105
|
"serve-index": "^1.9.1",
|
|
106
|
-
"serve-static": "^2.2.
|
|
106
|
+
"serve-static": "^2.2.1",
|
|
107
107
|
"swagger-ui-express": "^5.0.1",
|
|
108
108
|
"swig": "^1.4.2",
|
|
109
109
|
"vhost": "^3.0.2"
|
package/src/declarative.js
CHANGED
|
@@ -31,7 +31,7 @@ module.exports = function compileDeclarative(cb, app) {
|
|
|
31
31
|
|
|
32
32
|
const tokens = [...acorn.tokenizer(code, { ecmaVersion: "latest" })];
|
|
33
33
|
|
|
34
|
-
if(tokens.some(token => ['throw', 'new', 'await', 'return'].includes(token.value))) {
|
|
34
|
+
if(tokens.some(token => ['throw', 'new', 'await', 'return', 'try', 'catch', 'finally', 'if', 'else', 'switch', 'case', 'default', 'for', 'while', 'do', 'var', 'let', 'const'].includes(token.value))) {
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
|
package/src/request.js
CHANGED
|
@@ -40,6 +40,11 @@ module.exports = class Request extends Readable {
|
|
|
40
40
|
#needsData = false;
|
|
41
41
|
#doneReadingData = false;
|
|
42
42
|
#bufferedData = null;
|
|
43
|
+
body;
|
|
44
|
+
res;
|
|
45
|
+
optimizedParams;
|
|
46
|
+
_error;
|
|
47
|
+
noEtag;
|
|
43
48
|
constructor(req, res, app) {
|
|
44
49
|
super();
|
|
45
50
|
this._res = res;
|
|
@@ -143,7 +148,7 @@ module.exports = class Request extends Readable {
|
|
|
143
148
|
}
|
|
144
149
|
|
|
145
150
|
set baseUrl(x) {
|
|
146
|
-
|
|
151
|
+
this._originalPath = x;
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
get #host() {
|
|
@@ -222,7 +227,7 @@ module.exports = class Request extends Readable {
|
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
set query(query) {
|
|
225
|
-
|
|
230
|
+
this.#cachedQuery = query;
|
|
226
231
|
}
|
|
227
232
|
get query() {
|
|
228
233
|
if(this.#cachedQuery) {
|
package/src/response.js
CHANGED
|
@@ -38,7 +38,7 @@ const etag = require("etag");
|
|
|
38
38
|
const outgoingMessage = new http.OutgoingMessage();
|
|
39
39
|
const symbols = Object.getOwnPropertySymbols(outgoingMessage);
|
|
40
40
|
const kOutHeaders = symbols.find(s => s.toString() === 'Symbol(kOutHeaders)');
|
|
41
|
-
const HIGH_WATERMARK =
|
|
41
|
+
const HIGH_WATERMARK = 128 * 1024;
|
|
42
42
|
|
|
43
43
|
class Socket extends EventEmitter {
|
|
44
44
|
constructor(response) {
|
|
@@ -73,6 +73,7 @@ module.exports = class Response extends Writable {
|
|
|
73
73
|
#pendingChunks = [];
|
|
74
74
|
#lastWriteChunkTime = 0;
|
|
75
75
|
#writeTimeout = null;
|
|
76
|
+
req;
|
|
76
77
|
constructor(res, req, app) {
|
|
77
78
|
super();
|
|
78
79
|
this._req = req;
|
|
@@ -854,7 +855,7 @@ module.exports = class Response extends Writable {
|
|
|
854
855
|
vary(field) {
|
|
855
856
|
// checks for back-compat
|
|
856
857
|
if (!field || (Array.isArray(field) && !field.length)) {
|
|
857
|
-
|
|
858
|
+
deprecated('res.vary(): Provide a field name');
|
|
858
859
|
return this;
|
|
859
860
|
}
|
|
860
861
|
vary(this, field);
|
package/src/router.js
CHANGED
|
@@ -40,6 +40,9 @@ const supportedUwsMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS',
|
|
|
40
40
|
const regExParam = /:(\w+)/g;
|
|
41
41
|
|
|
42
42
|
module.exports = class Router extends EventEmitter {
|
|
43
|
+
parent;
|
|
44
|
+
listenCalled;
|
|
45
|
+
uwsApp;
|
|
43
46
|
constructor(settings = {}) {
|
|
44
47
|
super();
|
|
45
48
|
|
|
@@ -92,10 +95,10 @@ module.exports = class Router extends EventEmitter {
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
getFullMountpath(req) {
|
|
95
|
-
|
|
96
|
-
if(!fullStack){
|
|
98
|
+
if(!req._stack.length) {
|
|
97
99
|
return EMPTY_REGEX;
|
|
98
100
|
}
|
|
101
|
+
const fullStack = req._stack.join("");
|
|
99
102
|
let fullMountpath = this._mountpathCache.get(fullStack);
|
|
100
103
|
if(!fullMountpath) {
|
|
101
104
|
fullMountpath = patternToRegex(fullStack, true);
|
|
@@ -112,7 +115,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
112
115
|
path = path.slice(0, -1);
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
if
|
|
118
|
+
if(typeof pattern === 'string') {
|
|
116
119
|
if(pattern === '/*') {
|
|
117
120
|
return true;
|
|
118
121
|
}
|
|
@@ -125,7 +128,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
125
128
|
}
|
|
126
129
|
return pattern === path;
|
|
127
130
|
}
|
|
128
|
-
if
|
|
131
|
+
if(pattern === EMPTY_REGEX) {
|
|
129
132
|
return true;
|
|
130
133
|
}
|
|
131
134
|
return pattern.test(path);
|
|
@@ -365,12 +368,15 @@ module.exports = class Router extends EventEmitter {
|
|
|
365
368
|
path = path.slice(0, -1);
|
|
366
369
|
}
|
|
367
370
|
let match = pattern.exec(path);
|
|
368
|
-
if( match?.groups ){
|
|
369
|
-
return match.groups;
|
|
370
|
-
}
|
|
371
371
|
const obj = new NullObject();
|
|
372
|
-
|
|
373
|
-
|
|
372
|
+
if(match?.groups) {
|
|
373
|
+
for(let name in match.groups) {
|
|
374
|
+
if(name.startsWith('_wc')) {
|
|
375
|
+
obj[name.slice(3)] = match.groups[name];
|
|
376
|
+
} else {
|
|
377
|
+
obj[name] = match.groups[name];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
374
380
|
}
|
|
375
381
|
return obj;
|
|
376
382
|
}
|
|
@@ -382,7 +388,10 @@ module.exports = class Router extends EventEmitter {
|
|
|
382
388
|
} else if(route.complex) {
|
|
383
389
|
let path = req._originalPath;
|
|
384
390
|
if(req._stack.length > 0) {
|
|
385
|
-
|
|
391
|
+
const fullMountpath = this.getFullMountpath(req);
|
|
392
|
+
if(fullMountpath !== EMPTY_REGEX) {
|
|
393
|
+
path = path.replace(fullMountpath, '');
|
|
394
|
+
}
|
|
386
395
|
}
|
|
387
396
|
req.params = {...this._extractParams(route.pattern, path)};
|
|
388
397
|
if(req._paramStack.length > 0) {
|
|
@@ -540,7 +549,7 @@ module.exports = class Router extends EventEmitter {
|
|
|
540
549
|
req._opPath += '/';
|
|
541
550
|
}
|
|
542
551
|
const routed = await callback._routeRequest(req, res, 0);
|
|
543
|
-
if
|
|
552
|
+
if(req._error) {
|
|
544
553
|
req._errorKey = route.routeKey;
|
|
545
554
|
}
|
|
546
555
|
if(routed) return resolve(true);
|
package/src/types.d.ts
CHANGED
|
@@ -45,7 +45,14 @@ declare module "ultimate-express" {
|
|
|
45
45
|
export import Send = e.Send;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
type UltimateExpress = Omit<e.Express, 'listen'> & {
|
|
49
|
+
readonly uwsApp: uWS.TemplatedApp;
|
|
50
|
+
listen(port: number, callback?: (token: any) => void): uWS.TemplatedApp;
|
|
51
|
+
listen(host: string, port: number, callback?: (token: any) => void): uWS.TemplatedApp;
|
|
52
|
+
listen(callback: (token: any) => void): uWS.TemplatedApp;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function express(settings?: Settings): UltimateExpress;
|
|
49
56
|
|
|
50
57
|
export = express;
|
|
51
58
|
}
|
package/src/utils.js
CHANGED
|
@@ -51,10 +51,11 @@ function patternToRegex(pattern, isPrefix = false) {
|
|
|
51
51
|
return EMPTY_REGEX;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
let wildcardIndex = 0;
|
|
54
55
|
let regexPattern = pattern
|
|
55
56
|
.replaceAll('.', '\\.')
|
|
56
57
|
.replaceAll('-', '\\-')
|
|
57
|
-
.replaceAll('*', '
|
|
58
|
+
.replaceAll(/(\*|\(.*?\))/g, (match) => `(?<_wc${wildcardIndex++}>${match.startsWith('(') ? match.slice(1, -1) : match.replaceAll('*', '.*')})`) // Convert * to .* and stuff in parentheses to capture group
|
|
58
59
|
.replace(/\/:(\w+)(\(.+?\))?\??/g, (match, param, regex) => {
|
|
59
60
|
const optional = match.endsWith('?');
|
|
60
61
|
return `\\/${optional ? '?' : ''}(?<${param}>${regex ? regex + '($|\\/)' : '[^/]+'})${optional ? '?' : ''}`;
|
|
@@ -67,10 +68,7 @@ function needsConversionToRegex(pattern) {
|
|
|
67
68
|
if(pattern instanceof RegExp) {
|
|
68
69
|
return false;
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
|
|
71
|
+
|
|
74
72
|
return pattern.includes('*') ||
|
|
75
73
|
pattern.includes('?') ||
|
|
76
74
|
pattern.includes('+') ||
|