@biggora/claude-plugins 1.2.2 → 1.3.0
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 +2 -0
- package/package.json +1 -1
- package/registry/registry.json +15 -0
- package/specs/coding.md +6 -0
- package/src/commands/skills/add.js +63 -7
- package/src/commands/skills/list.js +23 -52
- package/src/commands/skills/remove.js +26 -27
- package/src/commands/skills/resolve.js +155 -0
- package/src/commands/skills/update.js +58 -74
- package/src/skills/nest-best-practices/SKILL.md +251 -0
- package/src/skills/nest-best-practices/references/best-practices-request-lifecycle.md +158 -0
- package/src/skills/nest-best-practices/references/cli-monorepo.md +106 -0
- package/src/skills/nest-best-practices/references/cli-overview.md +157 -0
- package/src/skills/nest-best-practices/references/core-controllers.md +165 -0
- package/src/skills/nest-best-practices/references/core-dependency-injection.md +179 -0
- package/src/skills/nest-best-practices/references/core-middleware.md +139 -0
- package/src/skills/nest-best-practices/references/core-modules.md +138 -0
- package/src/skills/nest-best-practices/references/core-providers.md +188 -0
- package/src/skills/nest-best-practices/references/faq-raw-body-hybrid.md +122 -0
- package/src/skills/nest-best-practices/references/fundamentals-circular-dependency.md +89 -0
- package/src/skills/nest-best-practices/references/fundamentals-custom-decorators.md +107 -0
- package/src/skills/nest-best-practices/references/fundamentals-dynamic-modules.md +125 -0
- package/src/skills/nest-best-practices/references/fundamentals-exception-filters.md +202 -0
- package/src/skills/nest-best-practices/references/fundamentals-execution-context.md +107 -0
- package/src/skills/nest-best-practices/references/fundamentals-guards.md +136 -0
- package/src/skills/nest-best-practices/references/fundamentals-interceptors.md +187 -0
- package/src/skills/nest-best-practices/references/fundamentals-lazy-loading.md +89 -0
- package/src/skills/nest-best-practices/references/fundamentals-lifecycle-events.md +87 -0
- package/src/skills/nest-best-practices/references/fundamentals-module-reference.md +107 -0
- package/src/skills/nest-best-practices/references/fundamentals-pipes.md +197 -0
- package/src/skills/nest-best-practices/references/fundamentals-provider-scopes.md +92 -0
- package/src/skills/nest-best-practices/references/fundamentals-testing.md +142 -0
- package/src/skills/nest-best-practices/references/graphql-overview.md +233 -0
- package/src/skills/nest-best-practices/references/graphql-resolvers-mutations.md +199 -0
- package/src/skills/nest-best-practices/references/graphql-scalars-unions-enums.md +180 -0
- package/src/skills/nest-best-practices/references/graphql-subscriptions.md +228 -0
- package/src/skills/nest-best-practices/references/microservices-grpc.md +175 -0
- package/src/skills/nest-best-practices/references/microservices-overview.md +221 -0
- package/src/skills/nest-best-practices/references/microservices-transports.md +119 -0
- package/src/skills/nest-best-practices/references/openapi-swagger.md +207 -0
- package/src/skills/nest-best-practices/references/recipes-authentication.md +97 -0
- package/src/skills/nest-best-practices/references/recipes-cqrs.md +176 -0
- package/src/skills/nest-best-practices/references/recipes-crud-generator.md +87 -0
- package/src/skills/nest-best-practices/references/recipes-documentation.md +93 -0
- package/src/skills/nest-best-practices/references/recipes-mongoose.md +153 -0
- package/src/skills/nest-best-practices/references/recipes-prisma.md +98 -0
- package/src/skills/nest-best-practices/references/recipes-terminus.md +148 -0
- package/src/skills/nest-best-practices/references/recipes-typeorm.md +122 -0
- package/src/skills/nest-best-practices/references/security-authorization.md +196 -0
- package/src/skills/nest-best-practices/references/security-cors-helmet-rate-limiting.md +204 -0
- package/src/skills/nest-best-practices/references/security-encryption-hashing.md +93 -0
- package/src/skills/nest-best-practices/references/techniques-caching.md +142 -0
- package/src/skills/nest-best-practices/references/techniques-compression-streaming-sse.md +194 -0
- package/src/skills/nest-best-practices/references/techniques-configuration.md +132 -0
- package/src/skills/nest-best-practices/references/techniques-database.md +153 -0
- package/src/skills/nest-best-practices/references/techniques-events.md +163 -0
- package/src/skills/nest-best-practices/references/techniques-fastify.md +137 -0
- package/src/skills/nest-best-practices/references/techniques-file-upload.md +140 -0
- package/src/skills/nest-best-practices/references/techniques-http-module.md +176 -0
- package/src/skills/nest-best-practices/references/techniques-logging.md +146 -0
- package/src/skills/nest-best-practices/references/techniques-mvc-serve-static.md +132 -0
- package/src/skills/nest-best-practices/references/techniques-queues.md +162 -0
- package/src/skills/nest-best-practices/references/techniques-serialization.md +158 -0
- package/src/skills/nest-best-practices/references/techniques-sessions-cookies.md +167 -0
- package/src/skills/nest-best-practices/references/techniques-task-scheduling.md +166 -0
- package/src/skills/nest-best-practices/references/techniques-validation.md +126 -0
- package/src/skills/nest-best-practices/references/techniques-versioning.md +153 -0
- package/src/skills/nest-best-practices/references/websockets-advanced.md +96 -0
- package/src/skills/nest-best-practices/references/websockets-gateways.md +215 -0
- package/src/skills/typescript-expert/SKILL.md +145 -0
- package/src/skills/typescript-expert/commands/typescript-fix.md +65 -0
- package/src/skills/typescript-expert/references/advanced-conditional-types.md +190 -0
- package/src/skills/typescript-expert/references/advanced-decorators.md +243 -0
- package/src/skills/typescript-expert/references/advanced-mapped-types.md +223 -0
- package/src/skills/typescript-expert/references/advanced-template-literals.md +209 -0
- package/src/skills/typescript-expert/references/advanced-type-guards.md +308 -0
- package/src/skills/typescript-expert/references/best-practices-patterns.md +313 -0
- package/src/skills/typescript-expert/references/best-practices-performance.md +185 -0
- package/src/skills/typescript-expert/references/best-practices-tsconfig.md +242 -0
- package/src/skills/typescript-expert/references/core-generics.md +246 -0
- package/src/skills/typescript-expert/references/core-interfaces-types.md +231 -0
- package/src/skills/typescript-expert/references/core-type-system.md +261 -0
- package/src/skills/typescript-expert/references/core-utility-types.md +235 -0
- package/src/skills/typescript-expert/references/features-ts5x.md +370 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recipes-documentation
|
|
3
|
+
description: OpenAPI/Swagger documentation setup in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API Documentation
|
|
7
|
+
|
|
8
|
+
NestJS provides integration with Swagger/OpenAPI for automatic API documentation generation.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --save @nestjs/swagger
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Basic Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
|
20
|
+
|
|
21
|
+
async function bootstrap() {
|
|
22
|
+
const app = await NestFactory.create(AppModule);
|
|
23
|
+
|
|
24
|
+
const config = new DocumentBuilder()
|
|
25
|
+
.setTitle('Cats example')
|
|
26
|
+
.setDescription('The cats API description')
|
|
27
|
+
.setVersion('1.0')
|
|
28
|
+
.addTag('cats')
|
|
29
|
+
.build();
|
|
30
|
+
const document = SwaggerModule.createDocument(app, config);
|
|
31
|
+
SwaggerModule.setup('api', app, document);
|
|
32
|
+
|
|
33
|
+
await app.listen(3000);
|
|
34
|
+
}
|
|
35
|
+
bootstrap();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## DTO Decorators
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
42
|
+
|
|
43
|
+
export class CreateCatDto {
|
|
44
|
+
@ApiProperty()
|
|
45
|
+
name: string;
|
|
46
|
+
|
|
47
|
+
@ApiProperty()
|
|
48
|
+
age: number;
|
|
49
|
+
|
|
50
|
+
@ApiProperty()
|
|
51
|
+
breed: string;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Controller Decorators
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
|
59
|
+
|
|
60
|
+
@ApiTags('cats')
|
|
61
|
+
@Controller('cats')
|
|
62
|
+
export class CatsController {
|
|
63
|
+
@Post()
|
|
64
|
+
@ApiOperation({ summary: 'Create a new cat' })
|
|
65
|
+
@ApiResponse({ status: 201, description: 'The cat has been successfully created.' })
|
|
66
|
+
@ApiResponse({ status: 403, description: 'Forbidden.' })
|
|
67
|
+
create(@Body() createCatDto: CreateCatDto) {
|
|
68
|
+
return this.catsService.create(createCatDto);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Security
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const config = new DocumentBuilder()
|
|
77
|
+
.addBearerAuth()
|
|
78
|
+
.build();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Key Points
|
|
82
|
+
|
|
83
|
+
- Use `@nestjs/swagger` for OpenAPI integration
|
|
84
|
+
- Decorate DTOs with `@ApiProperty()`
|
|
85
|
+
- Use `@ApiTags()` to group endpoints
|
|
86
|
+
- Add `@ApiOperation()` and `@ApiResponse()` for documentation
|
|
87
|
+
- Configure security schemes for authentication
|
|
88
|
+
- Access docs at `/api` endpoint
|
|
89
|
+
|
|
90
|
+
<!--
|
|
91
|
+
Source references:
|
|
92
|
+
- https://docs.nestjs.com/openapi/introduction
|
|
93
|
+
-->
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mongoose
|
|
3
|
+
description: MongoDB integration with Mongoose ODM
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mongoose (MongoDB)
|
|
7
|
+
|
|
8
|
+
Mongoose is the most popular MongoDB object modeling tool for Node.js.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm i @nestjs/mongoose mongoose
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
@Module({
|
|
20
|
+
imports: [
|
|
21
|
+
MongooseModule.forRoot('mongodb://localhost/nest'),
|
|
22
|
+
// Or with options
|
|
23
|
+
MongooseModule.forRoot('mongodb://localhost/nest', {
|
|
24
|
+
connectionName: 'cats',
|
|
25
|
+
}),
|
|
26
|
+
],
|
|
27
|
+
})
|
|
28
|
+
export class AppModule {}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Schema Definition
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
|
35
|
+
import { HydratedDocument } from 'mongoose';
|
|
36
|
+
|
|
37
|
+
export type CatDocument = HydratedDocument<Cat>;
|
|
38
|
+
|
|
39
|
+
@Schema()
|
|
40
|
+
export class Cat {
|
|
41
|
+
@Prop()
|
|
42
|
+
name: string;
|
|
43
|
+
|
|
44
|
+
@Prop({ required: true })
|
|
45
|
+
age: number;
|
|
46
|
+
|
|
47
|
+
@Prop([String])
|
|
48
|
+
tags: string[];
|
|
49
|
+
|
|
50
|
+
@Prop({ default: Date.now })
|
|
51
|
+
createdAt: Date;
|
|
52
|
+
|
|
53
|
+
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
|
|
54
|
+
owner: Owner;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const CatSchema = SchemaFactory.createForClass(Cat);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Register Model
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
@Module({
|
|
64
|
+
imports: [
|
|
65
|
+
MongooseModule.forFeature([
|
|
66
|
+
{ name: Cat.name, schema: CatSchema },
|
|
67
|
+
]),
|
|
68
|
+
],
|
|
69
|
+
})
|
|
70
|
+
export class CatsModule {}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Inject and Use
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
@Injectable()
|
|
77
|
+
export class CatsService {
|
|
78
|
+
constructor(
|
|
79
|
+
@InjectModel(Cat.name) private catModel: Model<CatDocument>,
|
|
80
|
+
) {}
|
|
81
|
+
|
|
82
|
+
async create(createCatDto: CreateCatDto) {
|
|
83
|
+
const created = new this.catModel(createCatDto);
|
|
84
|
+
return created.save();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async findAll(): Promise<Cat[]> {
|
|
88
|
+
return this.catModel.find().exec();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async findOne(id: string) {
|
|
92
|
+
return this.catModel.findById(id).populate('owner').exec();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## @Prop Options
|
|
98
|
+
|
|
99
|
+
| Option | Description |
|
|
100
|
+
|--------|-------------|
|
|
101
|
+
| `required` | Required field |
|
|
102
|
+
| `default` | Default value |
|
|
103
|
+
| `unique` | Unique index |
|
|
104
|
+
| `index` | Create index |
|
|
105
|
+
| `type` | Explicit type (e.g., `mongoose.Schema.Types.ObjectId`) |
|
|
106
|
+
| `ref` | Reference to another model |
|
|
107
|
+
|
|
108
|
+
## Relations (Population)
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
|
|
112
|
+
owner: Owner;
|
|
113
|
+
|
|
114
|
+
// Multiple
|
|
115
|
+
@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
|
|
116
|
+
owners: Owner[];
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
return this.catModel.find().populate('owner').exec();
|
|
121
|
+
return this.catModel.find().populate({ path: 'owner', select: 'name' }).exec();
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Plugins
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
CatSchema.plugin(require('mongoose-autopopulate'));
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Async Configuration
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
MongooseModule.forRootAsync({
|
|
134
|
+
imports: [ConfigModule],
|
|
135
|
+
useFactory: (config: ConfigService) => ({
|
|
136
|
+
uri: config.get('MONGODB_URI'),
|
|
137
|
+
}),
|
|
138
|
+
inject: [ConfigService],
|
|
139
|
+
}),
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Key Points
|
|
143
|
+
|
|
144
|
+
- Use `@Schema()` and `@Prop()` decorators
|
|
145
|
+
- `SchemaFactory.createForClass()` generates schema
|
|
146
|
+
- `@InjectModel()` injects Model
|
|
147
|
+
- Use `populate()` for relations
|
|
148
|
+
- `HydratedDocument<Cat>` for typed documents
|
|
149
|
+
|
|
150
|
+
<!--
|
|
151
|
+
Source references:
|
|
152
|
+
- https://docs.nestjs.com/techniques/mongodb
|
|
153
|
+
-->
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recipes-prisma
|
|
3
|
+
description: Prisma ORM integration in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Prisma Integration
|
|
7
|
+
|
|
8
|
+
Prisma is a next-generation ORM that provides type-safe database access.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --save @prisma/client
|
|
14
|
+
npm install --save-dev prisma
|
|
15
|
+
npx prisma init
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Prisma Service
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
22
|
+
import { PrismaClient } from '@prisma/client';
|
|
23
|
+
|
|
24
|
+
@Injectable()
|
|
25
|
+
export class PrismaService extends PrismaClient implements OnModuleInit {
|
|
26
|
+
async onModuleInit() {
|
|
27
|
+
await this.$connect();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Module Setup
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { Module } from '@nestjs/common';
|
|
36
|
+
import { PrismaService } from './prisma.service';
|
|
37
|
+
|
|
38
|
+
@Module({
|
|
39
|
+
providers: [PrismaService],
|
|
40
|
+
exports: [PrismaService],
|
|
41
|
+
})
|
|
42
|
+
export class PrismaModule {}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Using Prisma Service
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { Injectable } from '@nestjs/common';
|
|
49
|
+
import { PrismaService } from './prisma.service';
|
|
50
|
+
|
|
51
|
+
@Injectable()
|
|
52
|
+
export class UsersService {
|
|
53
|
+
constructor(private prisma: PrismaService) {}
|
|
54
|
+
|
|
55
|
+
async findAll() {
|
|
56
|
+
return this.prisma.user.findMany();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async findOne(id: number) {
|
|
60
|
+
return this.prisma.user.findUnique({
|
|
61
|
+
where: { id },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async create(data: CreateUserDto) {
|
|
66
|
+
return this.prisma.user.create({
|
|
67
|
+
data,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async update(id: number, data: UpdateUserDto) {
|
|
72
|
+
return this.prisma.user.update({
|
|
73
|
+
where: { id },
|
|
74
|
+
data,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async remove(id: number) {
|
|
79
|
+
return this.prisma.user.delete({
|
|
80
|
+
where: { id },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Key Points
|
|
87
|
+
|
|
88
|
+
- Prisma provides type-safe database access
|
|
89
|
+
- Extend `PrismaClient` for service
|
|
90
|
+
- Use `$connect()` in `onModuleInit()`
|
|
91
|
+
- Prisma generates types from schema
|
|
92
|
+
- Use Prisma Studio for database management
|
|
93
|
+
- Supports migrations and seeding
|
|
94
|
+
|
|
95
|
+
<!--
|
|
96
|
+
Source references:
|
|
97
|
+
- https://docs.nestjs.com/recipes/prisma
|
|
98
|
+
-->
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terminus
|
|
3
|
+
description: Health checks and readiness/liveness probes with @nestjs/terminus
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Health Checks (Terminus)
|
|
7
|
+
|
|
8
|
+
Readiness/liveness probes for Kubernetes and orchestration.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @nestjs/terminus
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Basic Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
@Module({
|
|
20
|
+
imports: [TerminusModule],
|
|
21
|
+
})
|
|
22
|
+
export class HealthModule {}
|
|
23
|
+
|
|
24
|
+
@Controller('health')
|
|
25
|
+
export class HealthController {
|
|
26
|
+
constructor(
|
|
27
|
+
private health: HealthCheckService,
|
|
28
|
+
private http: HttpHealthIndicator,
|
|
29
|
+
) {}
|
|
30
|
+
|
|
31
|
+
@Get()
|
|
32
|
+
@HealthCheck()
|
|
33
|
+
check() {
|
|
34
|
+
return this.health.check([
|
|
35
|
+
() => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Health Indicators
|
|
42
|
+
|
|
43
|
+
| Indicator | Purpose |
|
|
44
|
+
|-----------|---------|
|
|
45
|
+
| `HttpHealthIndicator` | HTTP ping |
|
|
46
|
+
| `TypeOrmHealthIndicator` | Database (SELECT 1) |
|
|
47
|
+
| `MongooseHealthIndicator` | MongoDB |
|
|
48
|
+
| `PrismaHealthIndicator` | Prisma |
|
|
49
|
+
| `MemoryHealthIndicator` | Heap/RSS limits |
|
|
50
|
+
| `DiskHealthIndicator` | Disk space |
|
|
51
|
+
| `MicroserviceHealthIndicator` | Microservice |
|
|
52
|
+
| `GRPCHealthIndicator` | gRPC |
|
|
53
|
+
|
|
54
|
+
## TypeORM
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
constructor(
|
|
58
|
+
private health: HealthCheckService,
|
|
59
|
+
private db: TypeOrmHealthIndicator,
|
|
60
|
+
) {}
|
|
61
|
+
|
|
62
|
+
@Get()
|
|
63
|
+
@HealthCheck()
|
|
64
|
+
check() {
|
|
65
|
+
return this.health.check([
|
|
66
|
+
() => this.db.pingCheck('database'),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Multiple databases: inject connections and pass to `pingCheck('name', { connection })`.
|
|
72
|
+
|
|
73
|
+
## Memory
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
return this.health.check([
|
|
77
|
+
() => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024), // 150MB
|
|
78
|
+
() => this.memory.checkRSS('memory_rss', 150 * 1024 * 1024),
|
|
79
|
+
]);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Disk
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
return this.health.check([
|
|
86
|
+
() => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
|
|
87
|
+
() => this.disk.checkStorage('storage', { path: '/', threshold: 250 * 1024 * 1024 * 1024 }),
|
|
88
|
+
]);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## HTTP Response Check
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
() => this.http.responseCheck(
|
|
95
|
+
'my-service',
|
|
96
|
+
'https://my-service.com',
|
|
97
|
+
(res) => res.status === 204,
|
|
98
|
+
),
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Custom Indicator
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
@Injectable()
|
|
105
|
+
export class DogHealthIndicator {
|
|
106
|
+
constructor(private health: HealthIndicatorService) {}
|
|
107
|
+
|
|
108
|
+
async isHealthy(key: string) {
|
|
109
|
+
const indicator = this.health.check(key);
|
|
110
|
+
const isHealthy = /* custom logic */;
|
|
111
|
+
if (!isHealthy) return indicator.down({ reason: '...' });
|
|
112
|
+
return indicator.up();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Response Format
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"status": "ok",
|
|
122
|
+
"info": { "database": { "status": "up" } },
|
|
123
|
+
"error": {},
|
|
124
|
+
"details": { "database": { "status": "up" } }
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Status: `'ok' | 'error' | 'shutting_down'`
|
|
129
|
+
|
|
130
|
+
## Graceful Shutdown
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
TerminusModule.forRoot({
|
|
134
|
+
gracefulShutdownTimeoutMs: 1000,
|
|
135
|
+
}),
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Key Points
|
|
139
|
+
|
|
140
|
+
- Enable shutdown hooks for Terminus lifecycle
|
|
141
|
+
- Use `@HealthCheck()` decorator on endpoints
|
|
142
|
+
- `HttpHealthIndicator` requires `@nestjs/axios`
|
|
143
|
+
- Custom indicators extend `HealthIndicatorService`
|
|
144
|
+
|
|
145
|
+
<!--
|
|
146
|
+
Source references:
|
|
147
|
+
- https://docs.nestjs.com/recipes/terminus
|
|
148
|
+
-->
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recipes-typeorm
|
|
3
|
+
description: TypeORM integration and usage in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TypeORM Integration
|
|
7
|
+
|
|
8
|
+
TypeORM is a popular ORM for TypeScript and JavaScript that works with NestJS.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --save @nestjs/typeorm typeorm mysql2
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Configuration
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
20
|
+
|
|
21
|
+
@Module({
|
|
22
|
+
imports: [
|
|
23
|
+
TypeOrmModule.forRoot({
|
|
24
|
+
type: 'mysql',
|
|
25
|
+
host: 'localhost',
|
|
26
|
+
port: 3306,
|
|
27
|
+
username: 'root',
|
|
28
|
+
password: 'root',
|
|
29
|
+
database: 'test',
|
|
30
|
+
entities: [User],
|
|
31
|
+
synchronize: true,
|
|
32
|
+
}),
|
|
33
|
+
],
|
|
34
|
+
})
|
|
35
|
+
export class AppModule {}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Entity Definition
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
|
|
42
|
+
|
|
43
|
+
@Entity()
|
|
44
|
+
export class User {
|
|
45
|
+
@PrimaryGeneratedColumn()
|
|
46
|
+
id: number;
|
|
47
|
+
|
|
48
|
+
@Column()
|
|
49
|
+
firstName: string;
|
|
50
|
+
|
|
51
|
+
@Column()
|
|
52
|
+
lastName: string;
|
|
53
|
+
|
|
54
|
+
@Column({ default: true })
|
|
55
|
+
isActive: boolean;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Feature Module
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { Module } from '@nestjs/common';
|
|
63
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
64
|
+
import { User } from './user.entity';
|
|
65
|
+
import { UsersService } from './users.service';
|
|
66
|
+
import { UsersController } from './users.controller';
|
|
67
|
+
|
|
68
|
+
@Module({
|
|
69
|
+
imports: [TypeOrmModule.forFeature([User])],
|
|
70
|
+
providers: [UsersService],
|
|
71
|
+
controllers: [UsersController],
|
|
72
|
+
})
|
|
73
|
+
export class UsersModule {}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Repository Injection
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { Injectable } from '@nestjs/common';
|
|
80
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
81
|
+
import { Repository } from 'typeorm';
|
|
82
|
+
import { User } from './user.entity';
|
|
83
|
+
|
|
84
|
+
@Injectable()
|
|
85
|
+
export class UsersService {
|
|
86
|
+
constructor(
|
|
87
|
+
@InjectRepository(User)
|
|
88
|
+
private usersRepository: Repository<User>,
|
|
89
|
+
) {}
|
|
90
|
+
|
|
91
|
+
findAll(): Promise<User[]> {
|
|
92
|
+
return this.usersRepository.find();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
findOne(id: number): Promise<User> {
|
|
96
|
+
return this.usersRepository.findOneBy({ id });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async create(user: User): Promise<User> {
|
|
100
|
+
return this.usersRepository.save(user);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async remove(id: number): Promise<void> {
|
|
104
|
+
await this.usersRepository.delete(id);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Key Points
|
|
110
|
+
|
|
111
|
+
- Use `TypeOrmModule.forRoot()` for configuration
|
|
112
|
+
- Use `TypeOrmModule.forFeature()` in feature modules
|
|
113
|
+
- Inject repositories with `@InjectRepository()`
|
|
114
|
+
- Define entities with decorators
|
|
115
|
+
- Use repository methods for database operations
|
|
116
|
+
- Configure connection in root module
|
|
117
|
+
|
|
118
|
+
<!--
|
|
119
|
+
Source references:
|
|
120
|
+
- https://docs.nestjs.com/techniques/database
|
|
121
|
+
- https://docs.nestjs.com/recipes/sql-typeorm
|
|
122
|
+
-->
|