Skip to content

Commit 1c72b31

Browse files
authored
feat(nestjs): Add fastify support (#14549)
1 parent 42ff876 commit 1c72b31

30 files changed

+1832
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# compiled output
2+
/dist
3+
/node_modules
4+
/build
5+
6+
# Logs
7+
logs
8+
*.log
9+
npm-debug.log*
10+
pnpm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
lerna-debug.log*
14+
15+
# OS
16+
.DS_Store
17+
18+
# Tests
19+
/coverage
20+
/.nyc_output
21+
22+
# IDEs and editors
23+
/.idea
24+
.project
25+
.classpath
26+
.c9/
27+
*.launch
28+
.settings/
29+
*.sublime-workspace
30+
31+
# IDE - VSCode
32+
.vscode/*
33+
!.vscode/settings.json
34+
!.vscode/tasks.json
35+
!.vscode/launch.json
36+
!.vscode/extensions.json
37+
38+
# dotenv environment variable files
39+
.env
40+
.env.development.local
41+
.env.test.local
42+
.env.production.local
43+
.env.local
44+
45+
# temp directory
46+
.temp
47+
.tmp
48+
49+
# Runtime data
50+
pids
51+
*.pid
52+
*.seed
53+
*.pid.lock
54+
55+
# Diagnostic reports (https://nodejs.org/api/report.html)
56+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<p align="center">
2+
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
3+
</p>
4+
5+
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
6+
[circleci-url]: https://circleci.com/gh/nestjs/nest
7+
8+
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
9+
<p align="center">
10+
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
11+
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
12+
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
13+
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
14+
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
15+
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
16+
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
17+
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
18+
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a>
19+
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
20+
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a>
21+
</p>
22+
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
23+
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
24+
25+
## Description
26+
27+
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
28+
29+
## Project setup
30+
31+
```bash
32+
$ yarn install
33+
```
34+
35+
## Compile and run the project
36+
37+
```bash
38+
# development
39+
$ yarn run start
40+
41+
# watch mode
42+
$ yarn run start:dev
43+
44+
# production mode
45+
$ yarn run start:prod
46+
```
47+
48+
## Run tests
49+
50+
```bash
51+
# unit tests
52+
$ yarn run test
53+
54+
# e2e tests
55+
$ yarn run test:e2e
56+
57+
# test coverage
58+
$ yarn run test:cov
59+
```
60+
61+
## Resources
62+
63+
Check out a few resources that may come in handy when working with NestJS:
64+
65+
- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
66+
- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
67+
- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
68+
- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
69+
- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
70+
- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
71+
- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
72+
73+
## Support
74+
75+
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
76+
77+
## Stay in touch
78+
79+
- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
80+
- Website - [https://nestjs.com](https://nestjs.com/)
81+
- Twitter - [@nestframework](https://twitter.com/nestframework)
82+
83+
## License
84+
85+
Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "https://json.schemastore.org/nest-cli",
3+
"collection": "@nestjs/schematics",
4+
"sourceRoot": "src",
5+
"compilerOptions": {
6+
"deleteOutDir": true
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "nestjs-fastify",
3+
"version": "0.0.1",
4+
"private": true,
5+
"scripts": {
6+
"build": "nest build",
7+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
8+
"start": "nest start",
9+
"start:dev": "nest start --watch",
10+
"start:debug": "nest start --debug --watch",
11+
"start:prod": "node dist/main",
12+
"clean": "npx rimraf node_modules pnpm-lock.yaml",
13+
"test": "playwright test",
14+
"test:build": "pnpm install",
15+
"test:assert": "pnpm test"
16+
},
17+
"dependencies": {
18+
"@nestjs/common": "^10.0.0",
19+
"@nestjs/core": "^10.0.0",
20+
"@nestjs/microservices": "^10.0.0",
21+
"@nestjs/schedule": "^4.1.0",
22+
"@nestjs/platform-fastify": "^10.0.0",
23+
"@sentry/nestjs": "latest || *",
24+
"reflect-metadata": "^0.2.0",
25+
"rxjs": "^7.8.1",
26+
"fastify": "^4.28.1"
27+
},
28+
"devDependencies": {
29+
"@playwright/test": "^1.44.1",
30+
"@sentry-internal/test-utils": "link:../../../test-utils",
31+
"@nestjs/cli": "^10.0.0",
32+
"@nestjs/schematics": "^10.0.0",
33+
"@nestjs/testing": "^10.0.0",
34+
"@types/node": "18.15.1",
35+
"@types/supertest": "^6.0.0",
36+
"@typescript-eslint/eslint-plugin": "^6.0.0",
37+
"@typescript-eslint/parser": "^6.0.0",
38+
"eslint": "^8.42.0",
39+
"eslint-config-prettier": "^9.0.0",
40+
"eslint-plugin-prettier": "^5.0.0",
41+
"prettier": "^3.0.0",
42+
"source-map-support": "^0.5.21",
43+
"supertest": "^6.3.3",
44+
"ts-loader": "^9.4.3",
45+
"tsconfig-paths": "^4.2.0",
46+
"typescript": "^5.1.3"
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { getPlaywrightConfig } from '@sentry-internal/test-utils';
2+
3+
const config = getPlaywrightConfig({
4+
startCommand: `pnpm start`,
5+
});
6+
7+
export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { Controller, Get, Param, ParseIntPipe, UseFilters, UseGuards, UseInterceptors } from '@nestjs/common';
2+
import { flush } from '@sentry/nestjs';
3+
import { AppService } from './app.service';
4+
import { AsyncInterceptor } from './async-example.interceptor';
5+
import { ExampleInterceptor1 } from './example-1.interceptor';
6+
import { ExampleInterceptor2 } from './example-2.interceptor';
7+
import { ExampleExceptionGlobalFilter } from './example-global-filter.exception';
8+
import { ExampleExceptionLocalFilter } from './example-local-filter.exception';
9+
import { ExampleLocalFilter } from './example-local.filter';
10+
import { ExampleGuard } from './example.guard';
11+
12+
@Controller()
13+
@UseFilters(ExampleLocalFilter)
14+
export class AppController {
15+
constructor(private readonly appService: AppService) {}
16+
17+
@Get('test-transaction')
18+
testTransaction() {
19+
return this.appService.testTransaction();
20+
}
21+
22+
@Get('test-middleware-instrumentation')
23+
testMiddlewareInstrumentation() {
24+
return this.appService.testSpan();
25+
}
26+
27+
@Get('test-guard-instrumentation')
28+
@UseGuards(ExampleGuard)
29+
testGuardInstrumentation() {
30+
return {};
31+
}
32+
33+
@Get('test-interceptor-instrumentation')
34+
@UseInterceptors(ExampleInterceptor1, ExampleInterceptor2)
35+
testInterceptorInstrumentation() {
36+
return this.appService.testSpan();
37+
}
38+
39+
@Get('test-async-interceptor-instrumentation')
40+
@UseInterceptors(AsyncInterceptor)
41+
testAsyncInterceptorInstrumentation() {
42+
return this.appService.testSpan();
43+
}
44+
45+
@Get('test-pipe-instrumentation/:id')
46+
testPipeInstrumentation(@Param('id', ParseIntPipe) id: number) {
47+
return { value: id };
48+
}
49+
50+
@Get('test-exception/:id')
51+
async testException(@Param('id') id: string) {
52+
return this.appService.testException(id);
53+
}
54+
55+
@Get('test-expected-400-exception/:id')
56+
async testExpected400Exception(@Param('id') id: string) {
57+
return this.appService.testExpected400Exception(id);
58+
}
59+
60+
@Get('test-expected-500-exception/:id')
61+
async testExpected500Exception(@Param('id') id: string) {
62+
return this.appService.testExpected500Exception(id);
63+
}
64+
65+
@Get('test-expected-rpc-exception/:id')
66+
async testExpectedRpcException(@Param('id') id: string) {
67+
return this.appService.testExpectedRpcException(id);
68+
}
69+
70+
@Get('test-span-decorator-async')
71+
async testSpanDecoratorAsync() {
72+
return { result: await this.appService.testSpanDecoratorAsync() };
73+
}
74+
75+
@Get('test-span-decorator-sync')
76+
async testSpanDecoratorSync() {
77+
return { result: await this.appService.testSpanDecoratorSync() };
78+
}
79+
80+
@Get('kill-test-cron/:job')
81+
async killTestCron(@Param('job') job: string) {
82+
this.appService.killTestCron(job);
83+
}
84+
85+
@Get('flush')
86+
async flush() {
87+
await flush();
88+
}
89+
90+
@Get('example-exception-global-filter')
91+
async exampleExceptionGlobalFilter() {
92+
throw new ExampleExceptionGlobalFilter();
93+
}
94+
95+
@Get('example-exception-local-filter')
96+
async exampleExceptionLocalFilter() {
97+
throw new ExampleExceptionLocalFilter();
98+
}
99+
100+
@Get('test-service-use')
101+
testServiceWithUseMethod() {
102+
return this.appService.use();
103+
}
104+
105+
@Get('test-service-transform')
106+
testServiceWithTransform() {
107+
return this.appService.transform();
108+
}
109+
110+
@Get('test-service-intercept')
111+
testServiceWithIntercept() {
112+
return this.appService.intercept();
113+
}
114+
115+
@Get('test-service-canActivate')
116+
testServiceWithCanActivate() {
117+
return this.appService.canActivate();
118+
}
119+
120+
@Get('test-function-name')
121+
testFunctionName() {
122+
return this.appService.getFunctionName();
123+
}
124+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { MiddlewareConsumer, Module } from '@nestjs/common';
2+
import { APP_FILTER } from '@nestjs/core';
3+
import { ScheduleModule } from '@nestjs/schedule';
4+
import { SentryGlobalFilter, SentryModule } from '@sentry/nestjs/setup';
5+
import { AppController } from './app.controller';
6+
import { AppService } from './app.service';
7+
import { ExampleGlobalFilter } from './example-global.filter';
8+
import { ExampleMiddleware } from './example.middleware';
9+
10+
@Module({
11+
imports: [SentryModule.forRoot(), ScheduleModule.forRoot()],
12+
controllers: [AppController],
13+
providers: [
14+
AppService,
15+
{
16+
provide: APP_FILTER,
17+
useClass: SentryGlobalFilter,
18+
},
19+
{
20+
provide: APP_FILTER,
21+
useClass: ExampleGlobalFilter,
22+
},
23+
],
24+
})
25+
export class AppModule {
26+
configure(consumer: MiddlewareConsumer): void {
27+
consumer.apply(ExampleMiddleware).forRoutes('test-middleware-instrumentation');
28+
}
29+
}

0 commit comments

Comments
 (0)