@nestjs/platform-fastify 12.0.0-alpha.2 → 12.0.0-alpha.4

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 backend applications, giving rise to awesome projects like <a href="https://angular.io/" target="_blank">Angular</a>, <a href="https://github.com/facebook/react" target="_blank">React</a>, and <a href="https://github.com/vuejs/vue" 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>
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): FastifyReply<RouteGenericInterface, RawServerDefault, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>;
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 = safeDecodeURI(pathname).path;
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
- const decodedUrl = safeDecodeURI(url).path;
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.2",
3
+ "version": "12.0.0-alpha.4",
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.7.4",
31
+ "fastify": "5.8.5",
32
32
  "fastify-plugin": "5.1.0",
33
- "find-my-way": "9.4.0",
33
+ "find-my-way": "9.6.0",
34
34
  "light-my-request": "6.6.0",
35
- "path-to-regexp": "8.3.0",
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": "011bff66014e24e82b25f7acf9302b9efb70b02b"
53
+ "gitHead": "415e4d33707e74998d8456be7bd305cedb6508e3"
54
54
  }