@nestjs/platform-fastify 12.0.0-alpha.2 → 12.0.0-alpha.3
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
|
@@ -29,7 +29,7 @@ Nest is a framework for building efficient, scalable <a href="https://nodejs.org
|
|
|
29
29
|
|
|
30
30
|
## Philosophy
|
|
31
31
|
|
|
32
|
-
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and
|
|
32
|
+
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front-end and back-end applications, giving rise to awesome projects like <a href="https://angular.dev/" target="_blank">Angular</a>, <a href="https://react.dev/" target="_blank">React</a>, and <a href="https://vuejs.org/" target="_blank">Vue</a>, which improve developer productivity and enable the construction of fast, testable, and extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers, and tools for Node, none of them effectively solve the main problem - the architecture.</p>
|
|
33
33
|
<p>Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, and loosely coupled and easily maintainable applications. The architecture is heavily inspired by Angular.</p>
|
|
34
34
|
|
|
35
35
|
## Getting started
|
|
@@ -95,6 +95,7 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
|
|
95
95
|
<td align="center" valign="middle"><a href="https://crawljobs.com" target="_blank"><img src="https://nestjs.com/img/logos/crawljobs-logo.svg" width="130" valign="middle" /></a></td>
|
|
96
96
|
</tr><tr>
|
|
97
97
|
<td align="center" valign="middle"><a href="https://pandektes.com" target="_blank"><img src="https://nestjs.com/img/logos/pandektes-logo.png" width="65" valign="middle" /></a></td>
|
|
98
|
+
<td align="center" valign="middle"><a href="https://www.fintechcrafts.com/" target="_blank"><img src="https://nestjs.com/img/logos/fintechcrafts-logo.svg" width="65" valign="middle" /></a></td>
|
|
98
99
|
</tr>
|
|
99
100
|
</table>
|
|
100
101
|
|
|
@@ -81,7 +81,7 @@ export declare class FastifyAdapter<TServer extends RawServerBase = RawServerDef
|
|
|
81
81
|
end(response: TReply, message?: string): void;
|
|
82
82
|
render(response: TReply & {
|
|
83
83
|
view: Function;
|
|
84
|
-
}, view: string, options: any):
|
|
84
|
+
}, view: string, options: any): any;
|
|
85
85
|
redirect(response: TReply, statusCode: number, url: string): FastifyReply<RouteGenericInterface, TServer, TRawRequest, TRawResponse, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>;
|
|
86
86
|
setErrorHandler(handler: Parameters<TInstance['setErrorHandler']>[0]): FastifyInstance<TServer, TRawRequest, TRawResponse, FastifyBaseLogger, import("fastify").FastifyTypeProvider>;
|
|
87
87
|
setNotFoundHandler(handler: Function): FastifyInstance<TServer, TRawRequest, TRawResponse, FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>;
|
|
@@ -123,5 +123,8 @@ export declare class FastifyAdapter<TServer extends RawServerBase = RawServerDef
|
|
|
123
123
|
private registerMiddie;
|
|
124
124
|
private getRequestOriginalUrl;
|
|
125
125
|
private injectRouteOptions;
|
|
126
|
+
private sanitizeUrl;
|
|
127
|
+
private removeDuplicateSlashes;
|
|
128
|
+
private trimLastSlash;
|
|
126
129
|
}
|
|
127
130
|
export {};
|
|
@@ -403,7 +403,7 @@ export class FastifyAdapter extends AbstractHttpAdapter {
|
|
|
403
403
|
let pathname = queryParamsIndex >= 0
|
|
404
404
|
? req.originalUrl.slice(0, queryParamsIndex)
|
|
405
405
|
: req.originalUrl;
|
|
406
|
-
pathname =
|
|
406
|
+
pathname = this.sanitizeUrl(pathname);
|
|
407
407
|
if (!re.exec(pathname + '/') && normalizedPath) {
|
|
408
408
|
return next();
|
|
409
409
|
}
|
|
@@ -517,4 +517,34 @@ export class FastifyAdapter extends AbstractHttpAdapter {
|
|
|
517
517
|
}
|
|
518
518
|
return this.instance.route(routeToInject);
|
|
519
519
|
}
|
|
520
|
+
sanitizeUrl(url) {
|
|
521
|
+
const initialConfig = this.instance.initialConfig;
|
|
522
|
+
const routerOptions = initialConfig.routerOptions;
|
|
523
|
+
if (routerOptions.ignoreDuplicateSlashes ||
|
|
524
|
+
initialConfig.ignoreDuplicateSlashes) {
|
|
525
|
+
url = this.removeDuplicateSlashes(url);
|
|
526
|
+
}
|
|
527
|
+
if (routerOptions.ignoreTrailingSlash ||
|
|
528
|
+
initialConfig.ignoreTrailingSlash) {
|
|
529
|
+
url = this.trimLastSlash(url);
|
|
530
|
+
}
|
|
531
|
+
if (routerOptions.caseSensitive === false ||
|
|
532
|
+
initialConfig.caseSensitive === false) {
|
|
533
|
+
url = url.toLowerCase();
|
|
534
|
+
}
|
|
535
|
+
return safeDecodeURI(url, routerOptions.useSemicolonDelimiter ||
|
|
536
|
+
initialConfig.useSemicolonDelimiter).path;
|
|
537
|
+
}
|
|
538
|
+
removeDuplicateSlashes(path) {
|
|
539
|
+
const REMOVE_DUPLICATE_SLASHES_REGEXP = /\/\/+/g;
|
|
540
|
+
return path.indexOf('//') !== -1
|
|
541
|
+
? path.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, '/')
|
|
542
|
+
: path;
|
|
543
|
+
}
|
|
544
|
+
trimLastSlash(path) {
|
|
545
|
+
if (path.length > 1 && path.charCodeAt(path.length - 1) === 47) {
|
|
546
|
+
return path.slice(0, -1);
|
|
547
|
+
}
|
|
548
|
+
return path;
|
|
549
|
+
}
|
|
520
550
|
}
|
|
@@ -3,17 +3,20 @@ import urlSanitizer from 'find-my-way/lib/url-sanitizer.js';
|
|
|
3
3
|
import { pathToRegexp } from 'path-to-regexp';
|
|
4
4
|
import reusify from 'reusify';
|
|
5
5
|
const { safeDecodeURI } = urlSanitizer;
|
|
6
|
+
function bindLast(fn, last) {
|
|
7
|
+
return (...args) => fn(...args, last);
|
|
8
|
+
}
|
|
6
9
|
/**
|
|
7
10
|
* A clone of `@fastify/middie` engine https://github.com/fastify/middie
|
|
8
11
|
* with an extra vulnerability fix. Path is now decoded before matching to
|
|
9
12
|
* avoid bypassing middleware with encoded characters.
|
|
10
13
|
*/
|
|
11
|
-
function middie(complete) {
|
|
14
|
+
function middie(complete, initialConfig) {
|
|
12
15
|
const middlewares = [];
|
|
13
16
|
const pool = reusify(Holder);
|
|
14
17
|
return {
|
|
15
18
|
use,
|
|
16
|
-
run,
|
|
19
|
+
run: bindLast(run, initialConfig),
|
|
17
20
|
};
|
|
18
21
|
function use(url, f) {
|
|
19
22
|
if (f === undefined) {
|
|
@@ -37,7 +40,7 @@ function middie(complete) {
|
|
|
37
40
|
}
|
|
38
41
|
return this;
|
|
39
42
|
}
|
|
40
|
-
function run(req, res, ctx) {
|
|
43
|
+
function run(req, res, ctx, initialConfig) {
|
|
41
44
|
if (!middlewares.length) {
|
|
42
45
|
complete(null, req, res, ctx);
|
|
43
46
|
return;
|
|
@@ -48,6 +51,7 @@ function middie(complete) {
|
|
|
48
51
|
holder.res = res;
|
|
49
52
|
holder.url = sanitizeUrl(req.url);
|
|
50
53
|
holder.context = ctx;
|
|
54
|
+
holder.initialConfig = initialConfig;
|
|
51
55
|
holder.done();
|
|
52
56
|
}
|
|
53
57
|
function Holder() {
|
|
@@ -55,6 +59,7 @@ function middie(complete) {
|
|
|
55
59
|
this.res = null;
|
|
56
60
|
this.url = null;
|
|
57
61
|
this.context = null;
|
|
62
|
+
this.initialConfig = null;
|
|
58
63
|
this.i = 0;
|
|
59
64
|
const that = this;
|
|
60
65
|
this.done = function (err) {
|
|
@@ -76,7 +81,21 @@ function middie(complete) {
|
|
|
76
81
|
const { fn, regexp } = middlewares[i];
|
|
77
82
|
if (regexp) {
|
|
78
83
|
// Decode URL before matching to avoid bypassing middleware
|
|
79
|
-
|
|
84
|
+
let sanitizedUrl = url;
|
|
85
|
+
if (that.initialConfig.ignoreDuplicateSlashes ||
|
|
86
|
+
that.initialConfig.routerOptions?.ignoreDuplicateSlashes) {
|
|
87
|
+
sanitizedUrl = removeDuplicateSlashes(sanitizedUrl);
|
|
88
|
+
}
|
|
89
|
+
if (that.initialConfig.ignoreTrailingSlash ||
|
|
90
|
+
that.initialConfig.routerOptions?.ignoreTrailingSlash) {
|
|
91
|
+
sanitizedUrl = trimLastSlash(sanitizedUrl);
|
|
92
|
+
}
|
|
93
|
+
if (that.initialConfig.caseSensitive === false ||
|
|
94
|
+
that.initialConfig.routerOptions?.caseSensitive === false) {
|
|
95
|
+
sanitizedUrl = sanitizedUrl.toLowerCase();
|
|
96
|
+
}
|
|
97
|
+
const decodedUrl = safeDecodeURI(sanitizedUrl, that.initialConfig?.routerOptions?.useSemicolonDelimiter ||
|
|
98
|
+
that.initialConfig?.useSemicolonDelimiter).path;
|
|
80
99
|
const result = regexp.exec(decodedUrl);
|
|
81
100
|
if (result) {
|
|
82
101
|
req.url = req.url.replace(result[0], '');
|
|
@@ -97,11 +116,24 @@ function middie(complete) {
|
|
|
97
116
|
that.req = null;
|
|
98
117
|
that.res = null;
|
|
99
118
|
that.context = null;
|
|
119
|
+
that.initialConfig = null;
|
|
100
120
|
that.i = 0;
|
|
101
121
|
pool.release(that);
|
|
102
122
|
}
|
|
103
123
|
}
|
|
104
124
|
}
|
|
125
|
+
function removeDuplicateSlashes(path) {
|
|
126
|
+
const REMOVE_DUPLICATE_SLASHES_REGEXP = /\/\/+/g;
|
|
127
|
+
return path.indexOf('//') !== -1
|
|
128
|
+
? path.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, '/')
|
|
129
|
+
: path;
|
|
130
|
+
}
|
|
131
|
+
function trimLastSlash(path) {
|
|
132
|
+
if (path.length > 1 && path.charCodeAt(path.length - 1) === 47) {
|
|
133
|
+
return path.slice(0, -1);
|
|
134
|
+
}
|
|
135
|
+
return path;
|
|
136
|
+
}
|
|
105
137
|
function sanitizeUrl(url) {
|
|
106
138
|
for (let i = 0, len = url.length; i < len; i++) {
|
|
107
139
|
const charCode = url.charCodeAt(i);
|
|
@@ -142,7 +174,7 @@ function fastifyMiddie(fastify, options, next) {
|
|
|
142
174
|
fastify.decorate('use', use);
|
|
143
175
|
fastify[kMiddlewares] = [];
|
|
144
176
|
fastify[kMiddieHasMiddlewares] = false;
|
|
145
|
-
fastify[kMiddie] = middie(onMiddieEnd);
|
|
177
|
+
fastify[kMiddie] = middie(onMiddieEnd, fastify.initialConfig);
|
|
146
178
|
const hook = options.hook || 'onRequest';
|
|
147
179
|
if (!supportedHooks.includes(hook)) {
|
|
148
180
|
next(new Error(`The hook "${hook}" is not supported by fastify-middie`));
|
|
@@ -196,7 +228,7 @@ function fastifyMiddie(fastify, options, next) {
|
|
|
196
228
|
function onRegister(instance) {
|
|
197
229
|
const middlewares = instance[kMiddlewares].slice();
|
|
198
230
|
instance[kMiddlewares] = [];
|
|
199
|
-
instance[kMiddie] = middie(onMiddieEnd);
|
|
231
|
+
instance[kMiddie] = middie(onMiddieEnd, instance.initialConfig);
|
|
200
232
|
instance[kMiddieHasMiddlewares] = false;
|
|
201
233
|
instance.decorate('use', use);
|
|
202
234
|
for (const middleware of middlewares) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/platform-fastify",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.3",
|
|
4
4
|
"description": "Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
|
|
5
5
|
"author": "Kamil Mysliwiec",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"@fastify/cors": "11.2.0",
|
|
29
29
|
"@fastify/formbody": "8.0.2",
|
|
30
30
|
"fast-querystring": "1.1.2",
|
|
31
|
-
"fastify": "5.
|
|
31
|
+
"fastify": "5.8.5",
|
|
32
32
|
"fastify-plugin": "5.1.0",
|
|
33
|
-
"find-my-way": "9.
|
|
33
|
+
"find-my-way": "9.6.0",
|
|
34
34
|
"light-my-request": "6.6.0",
|
|
35
|
-
"path-to-regexp": "8.
|
|
35
|
+
"path-to-regexp": "8.4.2",
|
|
36
36
|
"reusify": "1.1.0",
|
|
37
37
|
"tslib": "2.8.1"
|
|
38
38
|
},
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"optional": true
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "1c9d5482a65a446ede8dd1195bfa1cbbc16e0857"
|
|
54
54
|
}
|