ultimate-express 2.0.12 → 2.0.14

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-express",
3
- "version": "2.0.12",
3
+ "version": "2.0.14",
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.0.2",
50
+ "cookie": "^1.1.1",
51
51
  "cookie-signature": "^1.2.2",
52
52
  "encodeurl": "^2.0.0",
53
53
  "etag": "^1.8.1",
@@ -62,30 +62,30 @@
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.55.0",
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
70
  "better-sse": "^0.14.1",
71
- "body-parser": "^2.2.0",
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.1",
78
- "eventsource": "^4.0.0",
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.3",
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.0",
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": "^1.4.5-lts.2",
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.60",
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.0",
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"
@@ -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/response.js CHANGED
@@ -197,8 +197,9 @@ module.exports = class Response extends Writable {
197
197
  } else if (!ok) {
198
198
  this._res.ab = chunk;
199
199
  this._res.abOffset = lastOffset;
200
+ let handlerUsed = false;
200
201
  this._res.onWritable((offset) => {
201
- if (this.finished) return true;
202
+ if (this.finished || handlerUsed) return true;
202
203
  const [ok, done] = this._res.tryEnd(this._res.ab.slice(offset - this._res.abOffset), this.totalSize);
203
204
  if (done) {
204
205
  this.finished = true;
@@ -206,6 +207,7 @@ module.exports = class Response extends Writable {
206
207
  }
207
208
  if (ok) {
208
209
  this.writingChunk = false;
210
+ handlerUsed = true;
209
211
  callback(null);
210
212
  }
211
213
  return ok;
package/src/router.js CHANGED
@@ -92,10 +92,10 @@ module.exports = class Router extends EventEmitter {
92
92
  }
93
93
 
94
94
  getFullMountpath(req) {
95
- let fullStack = req._stack.join("");
96
- if(!fullStack){
95
+ if(!req._stack.length) {
97
96
  return EMPTY_REGEX;
98
97
  }
98
+ const fullStack = req._stack.join("");
99
99
  let fullMountpath = this._mountpathCache.get(fullStack);
100
100
  if(!fullMountpath) {
101
101
  fullMountpath = patternToRegex(fullStack, true);
@@ -112,7 +112,7 @@ module.exports = class Router extends EventEmitter {
112
112
  path = path.slice(0, -1);
113
113
  }
114
114
 
115
- if (typeof pattern === 'string') {
115
+ if(typeof pattern === 'string') {
116
116
  if(pattern === '/*') {
117
117
  return true;
118
118
  }
@@ -125,7 +125,7 @@ module.exports = class Router extends EventEmitter {
125
125
  }
126
126
  return pattern === path;
127
127
  }
128
- if (pattern === EMPTY_REGEX){
128
+ if(pattern === EMPTY_REGEX) {
129
129
  return true;
130
130
  }
131
131
  return pattern.test(path);
@@ -365,12 +365,15 @@ module.exports = class Router extends EventEmitter {
365
365
  path = path.slice(0, -1);
366
366
  }
367
367
  let match = pattern.exec(path);
368
- if( match?.groups ){
369
- return match.groups;
370
- }
371
368
  const obj = new NullObject();
372
- for(let i = 1; i < match.length; i++) {
373
- obj[i - 1] = match[i];
369
+ if(match?.groups) {
370
+ for(let name in match.groups) {
371
+ if(name.startsWith('_wc')) {
372
+ obj[name.slice(3)] = match.groups[name];
373
+ } else {
374
+ obj[name] = match.groups[name];
375
+ }
376
+ }
374
377
  }
375
378
  return obj;
376
379
  }
@@ -382,7 +385,10 @@ module.exports = class Router extends EventEmitter {
382
385
  } else if(route.complex) {
383
386
  let path = req._originalPath;
384
387
  if(req._stack.length > 0) {
385
- path = path.replace(this.getFullMountpath(req), '');
388
+ const fullMountpath = this.getFullMountpath(req);
389
+ if(fullMountpath !== EMPTY_REGEX) {
390
+ path = path.replace(fullMountpath, '');
391
+ }
386
392
  }
387
393
  req.params = {...this._extractParams(route.pattern, path)};
388
394
  if(req._paramStack.length > 0) {
@@ -540,7 +546,7 @@ module.exports = class Router extends EventEmitter {
540
546
  req._opPath += '/';
541
547
  }
542
548
  const routed = await callback._routeRequest(req, res, 0);
543
- if (req._error) {
549
+ if(req._error) {
544
550
  req._errorKey = route.routeKey;
545
551
  }
546
552
  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
- function express(settings?: Settings): e.Express & {readonly uwsApp: uWS.TemplatedApp};
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('*', '(.*)') // Convert * to .*
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
- if(pattern === '/*') {
71
- return false;
72
- }
73
-
71
+
74
72
  return pattern.includes('*') ||
75
73
  pattern.includes('?') ||
76
74
  pattern.includes('+') ||