ultimate-express 1.4.10 → 2.0.1

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/README.md CHANGED
@@ -8,10 +8,12 @@ To make sure µExpress matches behavior of Express in all cases, we run all test
8
8
 
9
9
  `npm install ultimate-express` -> replace `express` with `ultimate-express` -> done[*](https://github.com/dimdenGD/ultimate-express?tab=readme-ov-file#differences-from-express)
10
10
 
11
- [![Node.js >= 16.0.0](https://img.shields.io/badge/Node.js-%3E=16.0.0-green)](https://nodejs.org)
11
+ [![Node.js >= 20.0.0](https://img.shields.io/badge/Node.js-%3E=20.0.0-green)](https://nodejs.org)
12
12
  [![npm](https://img.shields.io/npm/v/ultimate-express?label=last+version)](https://npmjs.com/package/ultimate-express)
13
13
  [![Patreon](https://img.shields.io/badge/donate-Patreon-orange)](https://patreon.com/dimdendev)
14
14
 
15
+ > Use `npm install ultimate-express@node-v18` to install last version that supported Node.js v18.
16
+
15
17
  ## Difference from similar projects
16
18
 
17
19
  Similar projects based on uWebSockets:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-express",
3
- "version": "1.4.10",
3
+ "version": "2.0.1",
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": {
@@ -11,7 +11,7 @@
11
11
  "cover:report": "nyc report --reporter=html"
12
12
  },
13
13
  "engines": {
14
- "node": ">=18"
14
+ "node": ">=20"
15
15
  },
16
16
  "files": [
17
17
  "src",
@@ -61,48 +61,47 @@
61
61
  "range-parser": "^1.2.1",
62
62
  "statuses": "^2.0.1",
63
63
  "tseep": "^1.3.1",
64
- "type-is": "^1.6.18",
65
- "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.51.0",
64
+ "type-is": "^2.0.1",
65
+ "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.52.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": "^1.20.3",
71
+ "body-parser": "^2.2.0",
72
72
  "compression": "^1.8.0",
73
- "cookie-parser": "^1.4.6",
73
+ "cookie-parser": "^1.4.7",
74
74
  "cookie-session": "^2.1.0",
75
75
  "cors": "^2.8.5",
76
76
  "ejs": "^3.1.10",
77
77
  "errorhandler": "^1.5.1",
78
- "eventsource": "^3.0.6",
78
+ "eventsource": "^3.0.7",
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.1",
85
- "express-handlebars": "^8.0.2",
85
+ "express-handlebars": "^8.0.3",
86
86
  "express-mongo-sanitize": "^2.2.0",
87
87
  "express-rate-limit": "^7.5.0",
88
- "express-session": "^1.18.0",
88
+ "express-session": "^1.18.1",
89
89
  "express-subdomain": "^1.0.6",
90
- "formdata-node": "^6.0.3",
91
90
  "graphql-http": "^1.22.4",
92
91
  "helmet": "^8.1.0",
93
92
  "method-override": "^3.0.0",
94
93
  "morgan": "^1.10.0",
95
- "multer": "^1.4.5-lts.1",
94
+ "multer": "^1.4.5-lts.2",
96
95
  "mustache-express": "^1.3.2",
97
96
  "nyc": "^17.1.0",
98
97
  "pako": "^2.1.0",
99
98
  "passport": "^0.7.0",
100
99
  "passport-local": "^1.0.0",
101
- "pkg-pr-new": "^0.0.29",
100
+ "pkg-pr-new": "^0.0.43",
102
101
  "pug": "^3.0.3",
103
102
  "response-time": "^2.3.3",
104
103
  "serve-index": "^1.9.1",
105
- "serve-static": "^1.16.2",
104
+ "serve-static": "^2.2.0",
106
105
  "swagger-ui-express": "^5.0.1",
107
106
  "swig": "^1.4.2",
108
107
  "vhost": "^3.0.2"
@@ -187,10 +187,16 @@ module.exports = function compileDeclarative(cb, app) {
187
187
  return false;
188
188
  }
189
189
  const sameHeader = headers.find(header => header[0].toLowerCase() === call.arguments[0].value.toLowerCase());
190
+ let [header, value] = [call.arguments[0].value, call.arguments[1].value];
191
+ if(call.obj.propertyName !== 'setHeader') {
192
+ if(value.includes('text/') && !value.includes('; charset=')) {
193
+ value += '; charset=utf-8';
194
+ }
195
+ }
190
196
  if(sameHeader) {
191
- sameHeader[1] = call.arguments[1].value;
197
+ sameHeader[1] = value;
192
198
  } else {
193
- headers.push([call.arguments[0].value, call.arguments[1].value]);
199
+ headers.push([header, value]);
194
200
  }
195
201
  } else if(call.obj.propertyName === 'append') {
196
202
  if(call.arguments[0].type !== 'Literal' || call.arguments[1].type !== 'Literal') {
@@ -211,6 +217,10 @@ module.exports = function compileDeclarative(cb, app) {
211
217
  const index = headers.findIndex(header => header[0].toLowerCase() === 'content-type');
212
218
  if(index === -1) {
213
219
  headers.push(['content-type', 'text/html; charset=utf-8']);
220
+ } else {
221
+ if(headers[index][1].includes('text/') && !headers[index][1].includes('; charset=')) {
222
+ headers[index][1] += '; charset=utf-8';
223
+ }
214
224
  }
215
225
  }
216
226
  const arg = call.arguments[0];
@@ -355,9 +365,6 @@ module.exports = function compileDeclarative(cb, app) {
355
365
  if(header[0].toLowerCase() === 'content-length') {
356
366
  return false;
357
367
  }
358
- if(header[0].toLowerCase() === 'content-type' && header[1].includes('text/') && !header[1].includes(';')) {
359
- header[1] += '; charset=utf-8';
360
- }
361
368
  decRes = decRes.writeHeader(header[0], header[1]);
362
369
  }
363
370
 
package/src/response.js CHANGED
@@ -350,7 +350,9 @@ module.exports = class Response extends Writable {
350
350
  this.headers['content-type'] += '; charset=utf-8';
351
351
  }
352
352
  } else {
353
- this.headers['content-type'] = 'application/octet-stream';
353
+ if(!this.headers['content-type']) {
354
+ this.headers['content-type'] = 'application/octet-stream';
355
+ }
354
356
  }
355
357
  return this.end(body);
356
358
  }
@@ -585,23 +587,17 @@ module.exports = class Response extends Writable {
585
587
  this.attachment(name);
586
588
  this.sendFile(path, opts, done);
587
589
  }
588
- set(field, value) {
590
+ setHeader(field, value) {
589
591
  if(this.headersSent) {
590
592
  throw new Error('Cannot set headers after they are sent to the client');
591
593
  }
592
- if(typeof field === 'object') {
593
- for(const header in field) {
594
- this.set(header, field[header]);
595
- }
594
+ if(typeof field !== 'string') {
595
+ throw new TypeError('Header name must be a valid HTTP token');
596
596
  } else {
597
597
  field = field.toLowerCase();
598
598
  if(Array.isArray(value)) {
599
599
  this.headers[field] = value;
600
600
  return this;
601
- } else if(field === 'content-type') {
602
- if(!value.includes('charset=') && (value.startsWith('text/') || value === 'application/json' || value === 'application/javascript')) {
603
- value += '; charset=utf-8';
604
- }
605
601
  }
606
602
  this.headers[field] = String(value);
607
603
  }
@@ -610,8 +606,21 @@ module.exports = class Response extends Writable {
610
606
  header(field, value) {
611
607
  return this.set(field, value);
612
608
  }
613
- setHeader(field, value) {
614
- return this.set(field, value);
609
+ set(field, value) {
610
+ if(typeof field === 'object') {
611
+ for(const header in field) {
612
+ this.setHeader(header, field[header]);
613
+ }
614
+ } else {
615
+ field = field.toLowerCase();
616
+ if(field === 'content-type') {
617
+ if(!value.includes('charset=') && (value.startsWith('text/') || value === 'application/json' || value === 'application/javascript')) {
618
+ value += '; charset=utf-8';
619
+ }
620
+ }
621
+ this.setHeader(field, value);
622
+ }
623
+ return this;
615
624
  }
616
625
  get(field) {
617
626
  return this.headers[field.toLowerCase()];