@tsed/platform-fastify 8.5.0-beta.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/.swcrc +21 -0
- package/lib/esm/components/PlatformFastify.js +283 -0
- package/lib/esm/components/PlatformFastify.js.map +1 -0
- package/lib/esm/index.js +9 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/interfaces/PlatformFastifySettings.js +2 -0
- package/lib/esm/interfaces/PlatformFastifySettings.js.map +1 -0
- package/lib/esm/interfaces/interfaces.js +2 -0
- package/lib/esm/interfaces/interfaces.js.map +1 -0
- package/lib/esm/services/PlatformFastifyRequest.js +34 -0
- package/lib/esm/services/PlatformFastifyRequest.js.map +1 -0
- package/lib/esm/services/PlatformFastifyResponse.js +76 -0
- package/lib/esm/services/PlatformFastifyResponse.js.map +1 -0
- package/lib/types/components/PlatformFastify.d.ts +63 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/interfaces/PlatformFastifySettings.d.ts +4 -0
- package/lib/types/interfaces/interfaces.d.ts +22 -0
- package/lib/types/services/PlatformFastifyRequest.d.ts +41 -0
- package/lib/types/services/PlatformFastifyResponse.d.ts +56 -0
- package/package.json +118 -0
- package/readme.md +67 -0
- package/src/components/PlatformFastify.spec.ts +34 -0
- package/src/components/PlatformFastify.ts +361 -0
- package/src/index.ts +8 -0
- package/src/interfaces/PlatformFastifySettings.ts +5 -0
- package/src/interfaces/interfaces.ts +26 -0
- package/src/services/PlatformFastifyRequest.spec.ts +54 -0
- package/src/services/PlatformFastifyRequest.ts +61 -0
- package/src/services/PlatformFastifyResponse.spec.ts +114 -0
- package/src/services/PlatformFastifyResponse.ts +100 -0
- package/vitest.config.mts +21 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import "@fastify/accepts";
|
|
2
|
+
|
|
3
|
+
import type {IncomingMessage} from "node:http";
|
|
4
|
+
|
|
5
|
+
import {type PlatformContext, PlatformRequest} from "@tsed/platform-http";
|
|
6
|
+
import type {FastifyRequest} from "fastify";
|
|
7
|
+
|
|
8
|
+
declare module "fastify" {
|
|
9
|
+
export interface FastifyRequest {
|
|
10
|
+
$ctx: PlatformContext;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare module "http" {
|
|
15
|
+
export interface IncomingMessage {
|
|
16
|
+
$ctx: PlatformContext;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare global {
|
|
21
|
+
namespace TsED {
|
|
22
|
+
export interface Request extends FastifyRequest {}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @platform
|
|
28
|
+
* @fastify
|
|
29
|
+
*/
|
|
30
|
+
export class PlatformFastifyRequest extends PlatformRequest<FastifyRequest> {
|
|
31
|
+
get host(): string {
|
|
32
|
+
return this.raw.hostname;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get secure(): boolean {
|
|
36
|
+
return this.protocol === "https";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns the HTTP request header specified by field. The match is case-insensitive.
|
|
41
|
+
*
|
|
42
|
+
* ```typescript
|
|
43
|
+
* request.get('Content-Type') // => "text/plain"
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @param name
|
|
47
|
+
*/
|
|
48
|
+
get(name: string) {
|
|
49
|
+
return this.raw.raw.headers[name.toLowerCase()];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getReq(): IncomingMessage {
|
|
53
|
+
return this.raw.raw;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
accepts(mime?: string | string[]) {
|
|
57
|
+
const accepts = this.raw.accepts().type([].concat(mime as any));
|
|
58
|
+
|
|
59
|
+
return (accepts ? accepts : false) as any;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
2
|
+
|
|
3
|
+
import {PlatformFastifyResponse} from "./PlatformFastifyResponse.js";
|
|
4
|
+
|
|
5
|
+
function createResponse() {
|
|
6
|
+
const response = PlatformTest.createResponse();
|
|
7
|
+
response.code = response.status;
|
|
8
|
+
response.type = response.contentType;
|
|
9
|
+
response.header = response.set;
|
|
10
|
+
|
|
11
|
+
const ctx = PlatformTest.createRequestContext({
|
|
12
|
+
event: {
|
|
13
|
+
response
|
|
14
|
+
},
|
|
15
|
+
ResponseKlass: PlatformFastifyResponse
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return {res: response, response: ctx.response};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("PlatformFastifyResponse", () => {
|
|
22
|
+
beforeEach(() => PlatformTest.create());
|
|
23
|
+
afterEach(() => PlatformTest.reset());
|
|
24
|
+
|
|
25
|
+
it("should create a PlatformResponse instance", () => {
|
|
26
|
+
const {res, response} = createResponse();
|
|
27
|
+
|
|
28
|
+
expect(response.raw).toEqual(res);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("getRes()", () => {
|
|
32
|
+
it("return res", async () => {
|
|
33
|
+
const {res, response} = createResponse();
|
|
34
|
+
res.raw = {};
|
|
35
|
+
|
|
36
|
+
const result = await response.getRes();
|
|
37
|
+
|
|
38
|
+
expect(result).toEqual(res.raw);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("statusCode", () => {
|
|
42
|
+
it("return statusCode", () => {
|
|
43
|
+
const {response} = createResponse();
|
|
44
|
+
|
|
45
|
+
response.status(302);
|
|
46
|
+
|
|
47
|
+
expect(response.statusCode).toEqual(302);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe("contentType()", () => {
|
|
51
|
+
it("should set contentType", () => {
|
|
52
|
+
const {res, response} = createResponse();
|
|
53
|
+
|
|
54
|
+
response.contentType("text/html");
|
|
55
|
+
|
|
56
|
+
expect(res.headers).toEqual({"content-type": "text/html", "x-request-id": "id"});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("body()", () => {
|
|
60
|
+
it("should set body", () => {
|
|
61
|
+
const {res, response} = createResponse();
|
|
62
|
+
|
|
63
|
+
response.body("body");
|
|
64
|
+
|
|
65
|
+
expect(res.data).toEqual("body");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe("stream()", () => {
|
|
70
|
+
it("should set body", () => {
|
|
71
|
+
const {res, response} = createResponse();
|
|
72
|
+
|
|
73
|
+
response.stream("body");
|
|
74
|
+
|
|
75
|
+
expect(res.data).toEqual("body");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe("location", () => {
|
|
79
|
+
it("should set header location", () => {
|
|
80
|
+
const {res, response} = createResponse();
|
|
81
|
+
|
|
82
|
+
response.location("https://location");
|
|
83
|
+
|
|
84
|
+
expect(res.headers).toEqual({
|
|
85
|
+
location: "https://location",
|
|
86
|
+
"x-request-id": "id"
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should go back based on Referrer", async () => {
|
|
91
|
+
const {res, response} = createResponse();
|
|
92
|
+
|
|
93
|
+
response.request.raw.headers["referrer"] = "https://location/back";
|
|
94
|
+
|
|
95
|
+
await response.location("back");
|
|
96
|
+
|
|
97
|
+
expect(res.headers).toEqual({
|
|
98
|
+
location: "https://location/back",
|
|
99
|
+
"x-request-id": "id"
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("should go back based on default path", async () => {
|
|
104
|
+
const {res, response} = createResponse();
|
|
105
|
+
|
|
106
|
+
await response.location("back");
|
|
107
|
+
|
|
108
|
+
expect(res.headers).toEqual({
|
|
109
|
+
location: "/",
|
|
110
|
+
"x-request-id": "id"
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type {ServerResponse} from "node:http";
|
|
2
|
+
|
|
3
|
+
import {type PlatformContext, PlatformResponse} from "@tsed/platform-http";
|
|
4
|
+
import contentDisposition from "content-disposition";
|
|
5
|
+
import type {FastifyReply} from "fastify";
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
namespace TsED {
|
|
9
|
+
export interface Response extends FastifyReply {
|
|
10
|
+
locals: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @platform
|
|
17
|
+
* @fastify
|
|
18
|
+
*/
|
|
19
|
+
export class PlatformFastifyResponse extends PlatformResponse<TsED.Response> {
|
|
20
|
+
constructor(readonly $ctx: PlatformContext) {
|
|
21
|
+
super($ctx);
|
|
22
|
+
this.raw.locals = {};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// set raw(raw: FastifyReply) {
|
|
26
|
+
// this.$ctx.event.response = raw;
|
|
27
|
+
// }
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Return the Node.js response object
|
|
31
|
+
*/
|
|
32
|
+
getRes(): ServerResponse {
|
|
33
|
+
return this.raw.raw;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Sets the HTTP status for the response.
|
|
38
|
+
*
|
|
39
|
+
* @param status
|
|
40
|
+
*/
|
|
41
|
+
status(status: number) {
|
|
42
|
+
this.raw.code(status);
|
|
43
|
+
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Set `Content-Type` response header with `type` through `mime.lookup()`
|
|
49
|
+
* when it does not contain "/", or set the Content-Type to `type` otherwise.
|
|
50
|
+
*
|
|
51
|
+
* Examples:
|
|
52
|
+
*
|
|
53
|
+
* res.type('.html');
|
|
54
|
+
* res.type('html');
|
|
55
|
+
* res.type('json');
|
|
56
|
+
* res.type('application/json');
|
|
57
|
+
* res.type('png');
|
|
58
|
+
*/
|
|
59
|
+
contentType(contentType: string) {
|
|
60
|
+
this.raw.type(contentType);
|
|
61
|
+
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Returns the HTTP response header specified by field. The match is case-insensitive.
|
|
67
|
+
*
|
|
68
|
+
* ```typescript
|
|
69
|
+
* response.get('Content-Type') // => "text/plain"
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @param name
|
|
73
|
+
*/
|
|
74
|
+
get(name: string) {
|
|
75
|
+
return this.raw.getHeader(name);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
attachment(filename: string) {
|
|
79
|
+
this.setHeader("Content-Disposition", contentDisposition(filename));
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
setHeader(key: string, item: any) {
|
|
84
|
+
this.raw.header(key, this.formatHeader(key, item));
|
|
85
|
+
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
stream(data: any) {
|
|
90
|
+
this.raw.send(data);
|
|
91
|
+
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
json(data: any) {
|
|
96
|
+
this.raw.send(data);
|
|
97
|
+
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import {presets} from "@tsed/vitest/presets";
|
|
3
|
+
import {defineConfig} from "vitest/config";
|
|
4
|
+
|
|
5
|
+
export default defineConfig(
|
|
6
|
+
{
|
|
7
|
+
...presets,
|
|
8
|
+
test: {
|
|
9
|
+
...presets.test,
|
|
10
|
+
coverage: {
|
|
11
|
+
...presets.test.coverage,
|
|
12
|
+
thresholds: {
|
|
13
|
+
statements: 0,
|
|
14
|
+
branches: 0,
|
|
15
|
+
functions: 0,
|
|
16
|
+
lines: 0
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
);
|