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 +3 -1
- package/package.json +12 -13
- package/src/declarative.js +12 -5
- package/src/response.js +21 -12
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
|
-
[](https://nodejs.org)
|
|
12
12
|
[](https://npmjs.com/package/ultimate-express)
|
|
13
13
|
[](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": "
|
|
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": ">=
|
|
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": "^
|
|
65
|
-
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.
|
|
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": "^
|
|
71
|
+
"body-parser": "^2.2.0",
|
|
72
72
|
"compression": "^1.8.0",
|
|
73
|
-
"cookie-parser": "^1.4.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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": "^
|
|
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"
|
package/src/declarative.js
CHANGED
|
@@ -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] =
|
|
197
|
+
sameHeader[1] = value;
|
|
192
198
|
} else {
|
|
193
|
-
headers.push([
|
|
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']
|
|
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
|
-
|
|
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
|
|
593
|
-
|
|
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
|
-
|
|
614
|
-
|
|
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()];
|