@biggora/claude-plugins 1.2.2 → 1.3.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/README.md +5 -1
- package/package.json +1 -1
- package/registry/registry.json +15 -0
- package/specs/coding.md +11 -0
- package/src/commands/skills/add.js +115 -31
- package/src/commands/skills/list.js +25 -52
- package/src/commands/skills/remove.js +45 -27
- package/src/commands/skills/resolve.js +104 -0
- package/src/commands/skills/update.js +58 -74
- package/src/config.js +5 -0
- 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,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core-modules
|
|
3
|
+
description: NestJS modules for organizing application structure
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Modules
|
|
7
|
+
|
|
8
|
+
Modules are classes annotated with `@Module()` decorator that organize application components. Every Nest application has at least one root module.
|
|
9
|
+
|
|
10
|
+
## Basic Module
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { Module } from '@nestjs/common';
|
|
14
|
+
import { CatsController } from './cats.controller';
|
|
15
|
+
import { CatsService } from './cats.service';
|
|
16
|
+
|
|
17
|
+
@Module({
|
|
18
|
+
controllers: [CatsController],
|
|
19
|
+
providers: [CatsService],
|
|
20
|
+
})
|
|
21
|
+
export class CatsModule {}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Module Properties
|
|
25
|
+
|
|
26
|
+
- `providers` - Services that can be injected
|
|
27
|
+
- `controllers` - Controllers in this module
|
|
28
|
+
- `imports` - Other modules to import
|
|
29
|
+
- `exports` - Providers to make available to other modules
|
|
30
|
+
|
|
31
|
+
## Feature Modules
|
|
32
|
+
|
|
33
|
+
Group related functionality:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
@Module({
|
|
37
|
+
controllers: [CatsController],
|
|
38
|
+
providers: [CatsService],
|
|
39
|
+
})
|
|
40
|
+
export class CatsModule {}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Shared Modules
|
|
44
|
+
|
|
45
|
+
Export providers to share across modules:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
@Module({
|
|
49
|
+
providers: [CatsService],
|
|
50
|
+
exports: [CatsService],
|
|
51
|
+
})
|
|
52
|
+
export class CatsModule {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Global Modules
|
|
56
|
+
|
|
57
|
+
Make providers available everywhere:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { Module, Global } from '@nestjs/common';
|
|
61
|
+
|
|
62
|
+
@Global()
|
|
63
|
+
@Module({
|
|
64
|
+
providers: [CatsService],
|
|
65
|
+
exports: [CatsService],
|
|
66
|
+
})
|
|
67
|
+
export class CatsModule {}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Dynamic Modules
|
|
71
|
+
|
|
72
|
+
Create configurable modules:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
@Module({
|
|
76
|
+
providers: [Connection],
|
|
77
|
+
exports: [Connection],
|
|
78
|
+
})
|
|
79
|
+
export class DatabaseModule {
|
|
80
|
+
static forRoot(entities = [], options?): DynamicModule {
|
|
81
|
+
const providers = createDatabaseProviders(options, entities);
|
|
82
|
+
return {
|
|
83
|
+
module: DatabaseModule,
|
|
84
|
+
providers: providers,
|
|
85
|
+
exports: providers,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Usage:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
@Module({
|
|
95
|
+
imports: [DatabaseModule.forRoot([User])],
|
|
96
|
+
})
|
|
97
|
+
export class AppModule {}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Module Re-exporting
|
|
101
|
+
|
|
102
|
+
Re-export imported modules:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
@Module({
|
|
106
|
+
imports: [CommonModule],
|
|
107
|
+
exports: [CommonModule],
|
|
108
|
+
})
|
|
109
|
+
export class CoreModule {}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Module Dependency Injection
|
|
113
|
+
|
|
114
|
+
Modules can inject providers:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
@Module({
|
|
118
|
+
providers: [CatsService],
|
|
119
|
+
})
|
|
120
|
+
export class CatsModule {
|
|
121
|
+
constructor(private catsService: CatsService) {}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Key Points
|
|
126
|
+
|
|
127
|
+
- Modules encapsulate providers by default
|
|
128
|
+
- Export providers to make them available to other modules
|
|
129
|
+
- Use `@Global()` sparingly - prefer explicit imports
|
|
130
|
+
- Dynamic modules allow runtime configuration
|
|
131
|
+
- Modules are singletons by default
|
|
132
|
+
- Module classes cannot be injected as providers
|
|
133
|
+
|
|
134
|
+
<!--
|
|
135
|
+
Source references:
|
|
136
|
+
- https://docs.nestjs.com/modules
|
|
137
|
+
- https://docs.nestjs.com/fundamentals/dynamic-modules
|
|
138
|
+
-->
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core-providers
|
|
3
|
+
description: NestJS providers and services for dependency injection
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Providers
|
|
7
|
+
|
|
8
|
+
Providers are classes that can be injected as dependencies. Services, repositories, factories, and helpers are all providers.
|
|
9
|
+
|
|
10
|
+
## Basic Service
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { Injectable } from '@nestjs/common';
|
|
14
|
+
|
|
15
|
+
@Injectable()
|
|
16
|
+
export class CatsService {
|
|
17
|
+
private readonly cats: Cat[] = [];
|
|
18
|
+
|
|
19
|
+
create(cat: Cat) {
|
|
20
|
+
this.cats.push(cat);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
findAll(): Cat[] {
|
|
24
|
+
return this.cats;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Dependency Injection
|
|
30
|
+
|
|
31
|
+
Inject services in controllers:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
@Controller('cats')
|
|
35
|
+
export class CatsController {
|
|
36
|
+
constructor(private catsService: CatsService) {}
|
|
37
|
+
|
|
38
|
+
@Get()
|
|
39
|
+
async findAll(): Promise<Cat[]> {
|
|
40
|
+
return this.catsService.findAll();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Provider Registration
|
|
46
|
+
|
|
47
|
+
Register providers in modules:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
@Module({
|
|
51
|
+
controllers: [CatsController],
|
|
52
|
+
providers: [CatsService],
|
|
53
|
+
})
|
|
54
|
+
export class CatsModule {}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Optional Providers
|
|
58
|
+
|
|
59
|
+
Mark dependencies as optional:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { Injectable, Optional, Inject } from '@nestjs/common';
|
|
63
|
+
|
|
64
|
+
@Injectable()
|
|
65
|
+
export class HttpService<T> {
|
|
66
|
+
constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Property-based Injection
|
|
71
|
+
|
|
72
|
+
Inject at property level:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
@Injectable()
|
|
76
|
+
export class HttpService<T> {
|
|
77
|
+
@Inject('HTTP_OPTIONS')
|
|
78
|
+
private readonly httpClient: T;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Custom Providers
|
|
83
|
+
|
|
84
|
+
### Value Providers
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const mockCatsService = {
|
|
88
|
+
findAll: () => ['test'],
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
@Module({
|
|
92
|
+
providers: [
|
|
93
|
+
{
|
|
94
|
+
provide: CatsService,
|
|
95
|
+
useValue: mockCatsService,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
})
|
|
99
|
+
export class AppModule {}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Class Providers
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const configServiceProvider = {
|
|
106
|
+
provide: ConfigService,
|
|
107
|
+
useClass: process.env.NODE_ENV === 'development'
|
|
108
|
+
? DevelopmentConfigService
|
|
109
|
+
: ProductionConfigService,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
@Module({
|
|
113
|
+
providers: [configServiceProvider],
|
|
114
|
+
})
|
|
115
|
+
export class AppModule {}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Factory Providers
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const connectionProvider = {
|
|
122
|
+
provide: 'CONNECTION',
|
|
123
|
+
useFactory: (optionsProvider: OptionsProvider) => {
|
|
124
|
+
const options = optionsProvider.get();
|
|
125
|
+
return new DatabaseConnection(options);
|
|
126
|
+
},
|
|
127
|
+
inject: [OptionsProvider],
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
@Module({
|
|
131
|
+
providers: [connectionProvider, OptionsProvider],
|
|
132
|
+
})
|
|
133
|
+
export class AppModule {}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Alias Providers
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const loggerAliasProvider = {
|
|
140
|
+
provide: 'AliasedLoggerService',
|
|
141
|
+
useExisting: LoggerService,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
@Module({
|
|
145
|
+
providers: [LoggerService, loggerAliasProvider],
|
|
146
|
+
})
|
|
147
|
+
export class AppModule {}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Non-class-based Tokens
|
|
151
|
+
|
|
152
|
+
Use strings or symbols as tokens:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
@Module({
|
|
156
|
+
providers: [
|
|
157
|
+
{
|
|
158
|
+
provide: 'CONNECTION',
|
|
159
|
+
useValue: connection,
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
})
|
|
163
|
+
export class AppModule {}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Inject using `@Inject()`:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
@Injectable()
|
|
170
|
+
export class CatsRepository {
|
|
171
|
+
constructor(@Inject('CONNECTION') connection: Connection) {}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Key Points
|
|
176
|
+
|
|
177
|
+
- Use `@Injectable()` decorator to mark classes as providers
|
|
178
|
+
- Prefer constructor-based injection over property-based
|
|
179
|
+
- Providers are singletons by default
|
|
180
|
+
- Use custom providers for mocks, factories, and aliases
|
|
181
|
+
- Export providers to make them available to other modules
|
|
182
|
+
- Use string tokens for non-class providers
|
|
183
|
+
|
|
184
|
+
<!--
|
|
185
|
+
Source references:
|
|
186
|
+
- https://docs.nestjs.com/providers
|
|
187
|
+
- https://docs.nestjs.com/fundamentals/custom-providers
|
|
188
|
+
-->
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: raw-body-hybrid
|
|
3
|
+
description: Raw request body for webhooks and hybrid HTTP+microservice applications
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Raw Body and Hybrid Applications
|
|
7
|
+
|
|
8
|
+
## Raw Body (Webhook Signature Verification)
|
|
9
|
+
|
|
10
|
+
Required for Stripe, GitHub webhooks, etc. where you need the unparsed body to compute HMAC.
|
|
11
|
+
|
|
12
|
+
### Express
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
|
16
|
+
rawBody: true,
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
|
|
22
|
+
import { Request } from 'express';
|
|
23
|
+
|
|
24
|
+
@Controller('webhooks')
|
|
25
|
+
class WebhooksController {
|
|
26
|
+
@Post('stripe')
|
|
27
|
+
stripe(@Req() req: RawBodyRequest<Request>) {
|
|
28
|
+
const raw = req.rawBody; // Buffer
|
|
29
|
+
const signature = req.headers['stripe-signature'];
|
|
30
|
+
// Verify signature with raw body
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Fastify
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const app = await NestFactory.create<NestFastifyApplication>(
|
|
39
|
+
AppModule,
|
|
40
|
+
new FastifyAdapter(),
|
|
41
|
+
{ rawBody: true },
|
|
42
|
+
);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Additional Parsers
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
app.useBodyParser('text');
|
|
49
|
+
app.useBodyParser('json', { limit: '10mb' });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Hybrid Applications
|
|
53
|
+
|
|
54
|
+
Combine HTTP server with one or more microservice listeners.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const app = await NestFactory.create(AppModule);
|
|
58
|
+
|
|
59
|
+
// Connect microservices
|
|
60
|
+
app.connectMicroservice<MicroserviceOptions>({
|
|
61
|
+
transport: Transport.TCP,
|
|
62
|
+
options: { port: 3001 },
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
app.connectMicroservice<MicroserviceOptions>({
|
|
66
|
+
transport: Transport.REDIS,
|
|
67
|
+
options: { host: 'localhost', port: 6379 },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
await app.startAllMicroservices();
|
|
71
|
+
await app.listen(3001);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Non-HTTP Applications
|
|
75
|
+
|
|
76
|
+
Use `app.init()` instead of `app.listen()` when not handling HTTP:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
await app.startAllMicroservices();
|
|
80
|
+
await app.init();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Binding Patterns to Transport
|
|
84
|
+
|
|
85
|
+
When multiple transports exist, bind `@MessagePattern()` to specific transport:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
@MessagePattern('time.us.*', Transport.NATS)
|
|
89
|
+
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
|
|
90
|
+
return new Date().toLocaleTimeString();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
|
|
94
|
+
getTCPDate(@Payload() data: number[]) {
|
|
95
|
+
return new Date().toLocaleTimeString();
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Inherit App Config
|
|
100
|
+
|
|
101
|
+
By default, microservices don't inherit global pipes/guards/interceptors. To inherit:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
app.connectMicroservice<MicroserviceOptions>(
|
|
105
|
+
{ transport: Transport.TCP },
|
|
106
|
+
{ inheritAppConfig: true },
|
|
107
|
+
);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Key Points
|
|
111
|
+
|
|
112
|
+
- `rawBody: true` must be set at app creation
|
|
113
|
+
- Don't use `bodyParser: false` with raw body
|
|
114
|
+
- `RawBodyRequest` interface adds `rawBody` to request
|
|
115
|
+
- Each `connectMicroservice()` adds one transport
|
|
116
|
+
- Call `startAllMicroservices()` before `listen()`
|
|
117
|
+
|
|
118
|
+
<!--
|
|
119
|
+
Source references:
|
|
120
|
+
- https://docs.nestjs.com/faq/raw-body
|
|
121
|
+
- https://docs.nestjs.com/faq/hybrid-application
|
|
122
|
+
-->
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: circular-dependency
|
|
3
|
+
description: Resolving circular dependencies between providers and modules
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Circular Dependency
|
|
7
|
+
|
|
8
|
+
Circular dependencies occur when two classes depend on each other. While they should be avoided, NestJS provides techniques to resolve them when necessary.
|
|
9
|
+
|
|
10
|
+
## Forward Reference for Providers
|
|
11
|
+
|
|
12
|
+
Use `forwardRef()` when two providers depend on each other:
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// cats.service.ts
|
|
16
|
+
import { Injectable, Inject, forwardRef } from '@nestjs/common';
|
|
17
|
+
import { CommonService } from './common.service';
|
|
18
|
+
|
|
19
|
+
@Injectable()
|
|
20
|
+
export class CatsService {
|
|
21
|
+
constructor(
|
|
22
|
+
@Inject(forwardRef(() => CommonService))
|
|
23
|
+
private commonService: CommonService,
|
|
24
|
+
) {}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// common.service.ts
|
|
30
|
+
@Injectable()
|
|
31
|
+
export class CommonService {
|
|
32
|
+
constructor(
|
|
33
|
+
@Inject(forwardRef(() => CatsService))
|
|
34
|
+
private catsService: CatsService,
|
|
35
|
+
) {}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Forward Reference for Modules
|
|
40
|
+
|
|
41
|
+
Apply `forwardRef()` on both sides of module imports:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// common.module.ts
|
|
45
|
+
@Module({
|
|
46
|
+
imports: [forwardRef(() => CatsModule)],
|
|
47
|
+
})
|
|
48
|
+
export class CommonModule {}
|
|
49
|
+
|
|
50
|
+
// cats.module.ts
|
|
51
|
+
@Module({
|
|
52
|
+
imports: [forwardRef(() => CommonModule)],
|
|
53
|
+
})
|
|
54
|
+
export class CatsModule {}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Using ModuleRef Alternative
|
|
58
|
+
|
|
59
|
+
Refactor to use `ModuleRef` to retrieve providers dynamically:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
@Injectable()
|
|
63
|
+
export class CatsService implements OnModuleInit {
|
|
64
|
+
private commonService: CommonService;
|
|
65
|
+
|
|
66
|
+
constructor(private moduleRef: ModuleRef) {}
|
|
67
|
+
|
|
68
|
+
onModuleInit() {
|
|
69
|
+
this.commonService = this.moduleRef.get(CommonService);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Common Causes
|
|
75
|
+
|
|
76
|
+
- Barrel files (index.ts) grouping imports - avoid when importing within same directory
|
|
77
|
+
- Over-coupled service design
|
|
78
|
+
|
|
79
|
+
## Key Points
|
|
80
|
+
|
|
81
|
+
- `forwardRef()` is imported from `@nestjs/common`
|
|
82
|
+
- Instantiation order is indeterminate with forward references
|
|
83
|
+
- Avoid circular dependencies with `Scope.REQUEST` providers (can cause undefined dependencies)
|
|
84
|
+
- Consider refactoring to eliminate circular dependencies when possible
|
|
85
|
+
|
|
86
|
+
<!--
|
|
87
|
+
Source references:
|
|
88
|
+
- https://docs.nestjs.com/fundamentals/circular-dependency
|
|
89
|
+
-->
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fundamentals-custom-decorators
|
|
3
|
+
description: Creating custom parameter decorators in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Custom Decorators
|
|
7
|
+
|
|
8
|
+
Create custom parameter decorators to extract data from requests in a reusable way.
|
|
9
|
+
|
|
10
|
+
## Basic Custom Decorator
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
|
14
|
+
|
|
15
|
+
export const User = createParamDecorator(
|
|
16
|
+
(data: unknown, ctx: ExecutionContext) => {
|
|
17
|
+
const request = ctx.switchToHttp().getRequest();
|
|
18
|
+
return request.user;
|
|
19
|
+
},
|
|
20
|
+
);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Usage:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
@Get()
|
|
27
|
+
async findOne(@User() user: UserEntity) {
|
|
28
|
+
console.log(user);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Decorator with Data
|
|
33
|
+
|
|
34
|
+
Pass data to decorator:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
export const User = createParamDecorator(
|
|
38
|
+
(data: string, ctx: ExecutionContext) => {
|
|
39
|
+
const request = ctx.switchToHttp().getRequest();
|
|
40
|
+
const user = request.user;
|
|
41
|
+
|
|
42
|
+
return data ? user?.[data] : user;
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Usage:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
@Get()
|
|
51
|
+
async findOne(@User('firstName') firstName: string) {
|
|
52
|
+
console.log(`Hello ${firstName}`);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Working with Pipes
|
|
57
|
+
|
|
58
|
+
Apply pipes to custom decorators:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
@Get()
|
|
62
|
+
async findOne(
|
|
63
|
+
@User(new ValidationPipe({ validateCustomDecorators: true }))
|
|
64
|
+
user: UserEntity,
|
|
65
|
+
) {
|
|
66
|
+
console.log(user);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Decorator Composition
|
|
71
|
+
|
|
72
|
+
Combine multiple decorators:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { applyDecorators } from '@nestjs/common';
|
|
76
|
+
|
|
77
|
+
export function Auth(...roles: Role[]) {
|
|
78
|
+
return applyDecorators(
|
|
79
|
+
SetMetadata('roles', roles),
|
|
80
|
+
UseGuards(AuthGuard, RolesGuard),
|
|
81
|
+
ApiBearerAuth(),
|
|
82
|
+
ApiUnauthorizedResponse({ description: 'Unauthorized' }),
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Usage:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
@Get('users')
|
|
91
|
+
@Auth('admin')
|
|
92
|
+
findAllUsers() {}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Key Points
|
|
96
|
+
|
|
97
|
+
- Use `createParamDecorator()` to create custom decorators
|
|
98
|
+
- Decorators receive `ExecutionContext` for accessing request/response
|
|
99
|
+
- Pass data as second parameter to decorator factory
|
|
100
|
+
- Custom decorators work with pipes
|
|
101
|
+
- Use `applyDecorators()` to compose multiple decorators
|
|
102
|
+
- TypeScript generics can enforce type safety
|
|
103
|
+
|
|
104
|
+
<!--
|
|
105
|
+
Source references:
|
|
106
|
+
- https://docs.nestjs.com/custom-decorators
|
|
107
|
+
-->
|