@nestjs/platform-fastify 12.1.0 → 12.1.2
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.
|
@@ -122,8 +122,8 @@ export declare class FastifyAdapter<TServer extends RawServerBase = RawServerDef
|
|
|
122
122
|
inject(opts: InjectOptions | string): Promise<LightMyRequestResponse>;
|
|
123
123
|
close(): Promise<void>;
|
|
124
124
|
initHttpServer(options?: NestApplicationOptions): void;
|
|
125
|
-
useStaticAssets(options: FastifyStaticOptions):
|
|
126
|
-
setViewEngine(options: FastifyViewOptions | string):
|
|
125
|
+
useStaticAssets(options: FastifyStaticOptions): any;
|
|
126
|
+
setViewEngine(options: FastifyViewOptions | string): any;
|
|
127
127
|
isHeadersSent(response: TReply): boolean;
|
|
128
128
|
getHeader(response: any, name: string): any;
|
|
129
129
|
setHeader(response: TReply, name: string, value: string): FastifyReply<RouteGenericInterface, TServer, TRawRequest, TRawResponse, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>;
|
|
@@ -8,6 +8,7 @@ import middie from '@fastify/middie';
|
|
|
8
8
|
import { loadPackage, tryLoadPackage, isNil, isString, isUndefined, } from '@nestjs/common/internal';
|
|
9
9
|
import { AbstractHttpAdapter } from '@nestjs/core';
|
|
10
10
|
import { LegacyRouteConverter } from '@nestjs/core/internal';
|
|
11
|
+
import { getMediaTypeVersion } from './utils/get-media-type-version.util.js';
|
|
11
12
|
const { kRouteContext } = fastifySymbols;
|
|
12
13
|
// Fastify uses `fast-querystring` internally to quickly parse URL query strings.
|
|
13
14
|
import { parse as querystringParse } from 'fast-querystring';
|
|
@@ -22,6 +23,12 @@ function isFastifyMultipartPlugin(plugin) {
|
|
|
22
23
|
(fn[Symbol.for('plugin-meta')]?.name === '@fastify/multipart' ||
|
|
23
24
|
fn.name === 'fastifyMultipart'));
|
|
24
25
|
}
|
|
26
|
+
// Covers "application/json" and the "+json" structured syntax suffix (RFC 6839),
|
|
27
|
+
// e.g. "application/problem+json", with or without parameters.
|
|
28
|
+
function isJsonContentType(contentType) {
|
|
29
|
+
const mediaType = contentType.split(';')[0].trim().toLowerCase();
|
|
30
|
+
return (mediaType.startsWith('application/json') || mediaType.endsWith('+json'));
|
|
31
|
+
}
|
|
25
32
|
/**
|
|
26
33
|
* @publicApi
|
|
27
34
|
*/
|
|
@@ -79,13 +86,12 @@ export class FastifyAdapter extends AbstractHttpAdapter {
|
|
|
79
86
|
// Media Type (Accept Header) Versioning Handler
|
|
80
87
|
if (this.versioningOptions?.type === VersioningType.MEDIA_TYPE) {
|
|
81
88
|
const MEDIA_TYPE_HEADER = 'Accept';
|
|
82
|
-
const acceptHeaderValue =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return isUndefined(acceptHeaderVersionParameter)
|
|
89
|
+
const acceptHeaderValue = req.headers?.[MEDIA_TYPE_HEADER] ||
|
|
90
|
+
req.headers?.[MEDIA_TYPE_HEADER.toLowerCase()];
|
|
91
|
+
const headerVersion = getMediaTypeVersion(acceptHeaderValue, this.versioningOptions.key);
|
|
92
|
+
return isUndefined(headerVersion)
|
|
87
93
|
? VERSION_NEUTRAL // No version was supplied
|
|
88
|
-
:
|
|
94
|
+
: headerVersion;
|
|
89
95
|
}
|
|
90
96
|
// Header Versioning Handler
|
|
91
97
|
else if (this.versioningOptions?.type === VersioningType.HEADER) {
|
|
@@ -280,8 +286,9 @@ export class FastifyAdapter extends AbstractHttpAdapter {
|
|
|
280
286
|
}
|
|
281
287
|
body = body.getStream();
|
|
282
288
|
}
|
|
283
|
-
|
|
284
|
-
|
|
289
|
+
const responseContentType = fastifyReply.getHeader('Content-Type');
|
|
290
|
+
if (typeof responseContentType === 'string' &&
|
|
291
|
+
!isJsonContentType(responseContentType) &&
|
|
285
292
|
body?.statusCode >= HttpStatus.BAD_REQUEST) {
|
|
286
293
|
Logger.warn("Content-Type doesn't match Reply body, you might need a custom ExceptionFilter for non-JSON responses", FastifyAdapter.name);
|
|
287
294
|
fastifyReply.header('Content-Type', 'application/json');
|
|
@@ -392,15 +399,20 @@ export class FastifyAdapter extends AbstractHttpAdapter {
|
|
|
392
399
|
this.trackOpenConnections();
|
|
393
400
|
}
|
|
394
401
|
}
|
|
395
|
-
|
|
396
|
-
|
|
402
|
+
// `register()` accepts a promise of a plugin, so the import is handed over
|
|
403
|
+
// unawaited on purpose. `NestApplication.useStaticAssets()` discards what
|
|
404
|
+
// this returns, so awaiting here would enqueue the plugin after the caller
|
|
405
|
+
// has already moved on to `listen()`.
|
|
406
|
+
useStaticAssets(options) {
|
|
407
|
+
return this.register(loadPackage('@fastify/static', 'FastifyAdapter.useStaticAssets()', () => import('@fastify/static')), options);
|
|
397
408
|
}
|
|
398
|
-
|
|
409
|
+
// Handed over unawaited for the same reason as `useStaticAssets()` above.
|
|
410
|
+
setViewEngine(options) {
|
|
399
411
|
if (isString(options)) {
|
|
400
412
|
new Logger('FastifyAdapter').error("setViewEngine() doesn't support a string argument.");
|
|
401
413
|
process.exit(1);
|
|
402
414
|
}
|
|
403
|
-
return this.register(
|
|
415
|
+
return this.register(loadPackage('@fastify/view', 'FastifyAdapter.setViewEngine()', () => import('@fastify/view')), options);
|
|
404
416
|
}
|
|
405
417
|
isHeadersSent(response) {
|
|
406
418
|
return response.sent;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the version carried by an `Accept` header for media type versioning,
|
|
3
|
+
* e.g. `2` for `application/json;v=2` with the `v=` key.
|
|
4
|
+
*
|
|
5
|
+
* The version parameter may follow other parameters and may belong to any
|
|
6
|
+
* media range of a list (`text/html, application/json;v=2`); the first match
|
|
7
|
+
* wins. Returns `undefined` when no parameter starts with the key.
|
|
8
|
+
*
|
|
9
|
+
* Duplicated in each platform package so that a platform package never
|
|
10
|
+
* depends on a newer `@nestjs/core` than the one installed.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getMediaTypeVersion(acceptHeader: string | string[] | undefined, key: string): string | undefined;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the version carried by an `Accept` header for media type versioning,
|
|
3
|
+
* e.g. `2` for `application/json;v=2` with the `v=` key.
|
|
4
|
+
*
|
|
5
|
+
* The version parameter may follow other parameters and may belong to any
|
|
6
|
+
* media range of a list (`text/html, application/json;v=2`); the first match
|
|
7
|
+
* wins. Returns `undefined` when no parameter starts with the key.
|
|
8
|
+
*
|
|
9
|
+
* Duplicated in each platform package so that a platform package never
|
|
10
|
+
* depends on a newer `@nestjs/core` than the one installed.
|
|
11
|
+
*/
|
|
12
|
+
export function getMediaTypeVersion(acceptHeader, key) {
|
|
13
|
+
const mediaRanges = []
|
|
14
|
+
.concat(acceptHeader ?? [])
|
|
15
|
+
.flatMap(value => value.split(','));
|
|
16
|
+
for (const mediaRange of mediaRanges) {
|
|
17
|
+
const [, ...parameters] = mediaRange.split(';');
|
|
18
|
+
for (const parameter of parameters) {
|
|
19
|
+
const trimmedParameter = parameter.trim();
|
|
20
|
+
if (trimmedParameter.startsWith(key)) {
|
|
21
|
+
return trimmedParameter.slice(key.length);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/platform-fastify",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.2",
|
|
4
4
|
"description": "Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
|
|
5
5
|
"author": "Kamil Mysliwiec",
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"optional": true
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "8ab60aa1b2927fbe0e23135ffc65d610c623236a"
|
|
58
58
|
}
|