@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,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-scheduling
|
|
3
|
+
description: Cron jobs, intervals, and timeouts with @nestjs/schedule
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task Scheduling
|
|
7
|
+
|
|
8
|
+
Schedule tasks to run at fixed times, recurring intervals, or after delays.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @nestjs/schedule
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Module } from '@nestjs/common';
|
|
20
|
+
import { ScheduleModule } from '@nestjs/schedule';
|
|
21
|
+
|
|
22
|
+
@Module({
|
|
23
|
+
imports: [ScheduleModule.forRoot()],
|
|
24
|
+
})
|
|
25
|
+
export class AppModule {}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Cron Jobs
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { Injectable, Logger } from '@nestjs/common';
|
|
32
|
+
import { Cron, CronExpression } from '@nestjs/schedule';
|
|
33
|
+
|
|
34
|
+
@Injectable()
|
|
35
|
+
export class TasksService {
|
|
36
|
+
private readonly logger = new Logger(TasksService.name);
|
|
37
|
+
|
|
38
|
+
// Using cron pattern
|
|
39
|
+
@Cron('45 * * * * *')
|
|
40
|
+
handleCron() {
|
|
41
|
+
this.logger.log('Called at second 45 of every minute');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Using CronExpression enum
|
|
45
|
+
@Cron(CronExpression.EVERY_30_SECONDS)
|
|
46
|
+
handleEvery30Seconds() {
|
|
47
|
+
this.logger.log('Called every 30 seconds');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// With options
|
|
51
|
+
@Cron('0 0 8 * * *', {
|
|
52
|
+
name: 'dailyReport',
|
|
53
|
+
timeZone: 'America/New_York',
|
|
54
|
+
})
|
|
55
|
+
generateDailyReport() {
|
|
56
|
+
this.logger.log('Generating daily report');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Cron Pattern
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
* * * * * *
|
|
65
|
+
| | | | | |
|
|
66
|
+
| | | | | day of week (0-7)
|
|
67
|
+
| | | | month (1-12)
|
|
68
|
+
| | | day of month (1-31)
|
|
69
|
+
| | hours (0-23)
|
|
70
|
+
| minutes (0-59)
|
|
71
|
+
seconds (0-59, optional)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Intervals
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
@Interval(10000)
|
|
78
|
+
handleInterval() {
|
|
79
|
+
this.logger.log('Called every 10 seconds');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Named interval
|
|
83
|
+
@Interval('notifications', 2500)
|
|
84
|
+
handleNotifications() {}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Timeouts
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
@Timeout(5000)
|
|
91
|
+
handleTimeout() {
|
|
92
|
+
this.logger.log('Called once after 5 seconds');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Named timeout
|
|
96
|
+
@Timeout('welcome', 3000)
|
|
97
|
+
sendWelcome() {}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Dynamic API
|
|
101
|
+
|
|
102
|
+
Manage scheduled tasks programmatically:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { Injectable } from '@nestjs/common';
|
|
106
|
+
import { SchedulerRegistry } from '@nestjs/schedule';
|
|
107
|
+
import { CronJob } from 'cron';
|
|
108
|
+
|
|
109
|
+
@Injectable()
|
|
110
|
+
export class TaskService {
|
|
111
|
+
constructor(private schedulerRegistry: SchedulerRegistry) {}
|
|
112
|
+
|
|
113
|
+
// Access existing cron job
|
|
114
|
+
stopCronJob() {
|
|
115
|
+
const job = this.schedulerRegistry.getCronJob('dailyReport');
|
|
116
|
+
job.stop();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Create dynamic cron job
|
|
120
|
+
addCronJob(name: string, cronTime: string) {
|
|
121
|
+
const job = new CronJob(cronTime, () => {
|
|
122
|
+
console.log(`Dynamic job ${name} running`);
|
|
123
|
+
});
|
|
124
|
+
this.schedulerRegistry.addCronJob(name, job);
|
|
125
|
+
job.start();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Delete cron job
|
|
129
|
+
deleteCronJob(name: string) {
|
|
130
|
+
this.schedulerRegistry.deleteCronJob(name);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// List all cron jobs
|
|
134
|
+
getCronJobs() {
|
|
135
|
+
const jobs = this.schedulerRegistry.getCronJobs();
|
|
136
|
+
jobs.forEach((job, key) => {
|
|
137
|
+
console.log(`Job: ${key}, Next: ${job.nextDate().toJSDate()}`);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## CronJob Methods
|
|
144
|
+
|
|
145
|
+
| Method | Description |
|
|
146
|
+
|--------|-------------|
|
|
147
|
+
| `stop()` | Stop the job |
|
|
148
|
+
| `start()` | Restart a stopped job |
|
|
149
|
+
| `setTime(time)` | Set new time and restart |
|
|
150
|
+
| `lastDate()` | Last execution date |
|
|
151
|
+
| `nextDate()` | Next scheduled execution |
|
|
152
|
+
|
|
153
|
+
## Cron Options
|
|
154
|
+
|
|
155
|
+
| Option | Description |
|
|
156
|
+
|--------|-------------|
|
|
157
|
+
| `name` | Name for dynamic access |
|
|
158
|
+
| `timeZone` | Timezone for execution |
|
|
159
|
+
| `utcOffset` | UTC offset alternative |
|
|
160
|
+
| `disabled` | Disable job execution |
|
|
161
|
+
| `waitForCompletion` | Wait for current run before next |
|
|
162
|
+
|
|
163
|
+
<!--
|
|
164
|
+
Source references:
|
|
165
|
+
- https://docs.nestjs.com/techniques/task-scheduling
|
|
166
|
+
-->
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: techniques-validation
|
|
3
|
+
description: Data validation using ValidationPipe and class-validator in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Validation
|
|
7
|
+
|
|
8
|
+
NestJS provides `ValidationPipe` for automatic validation of incoming requests using `class-validator` decorators.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm i --save class-validator class-transformer
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Global ValidationPipe
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
async function bootstrap() {
|
|
20
|
+
const app = await NestFactory.create(AppModule);
|
|
21
|
+
app.useGlobalPipes(new ValidationPipe());
|
|
22
|
+
await app.listen(3000);
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## DTO with Validation
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { IsString, IsInt, Min, Max } from 'class-validator';
|
|
30
|
+
|
|
31
|
+
export class CreateCatDto {
|
|
32
|
+
@IsString()
|
|
33
|
+
name: string;
|
|
34
|
+
|
|
35
|
+
@IsInt()
|
|
36
|
+
@Min(0)
|
|
37
|
+
@Max(20)
|
|
38
|
+
age: number;
|
|
39
|
+
|
|
40
|
+
@IsString()
|
|
41
|
+
breed: string;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## ValidationPipe Options
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
app.useGlobalPipes(
|
|
49
|
+
new ValidationPipe({
|
|
50
|
+
whitelist: true,
|
|
51
|
+
forbidNonWhitelisted: true,
|
|
52
|
+
transform: true,
|
|
53
|
+
transformOptions: {
|
|
54
|
+
enableImplicitConversion: true,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Common Options
|
|
61
|
+
|
|
62
|
+
- `whitelist` - Strip non-whitelisted properties
|
|
63
|
+
- `forbidNonWhitelisted` - Throw error on non-whitelisted properties
|
|
64
|
+
- `transform` - Automatically transform payloads to DTO instances
|
|
65
|
+
- `disableErrorMessages` - Disable error messages
|
|
66
|
+
- `validationError.target` - Expose target in ValidationError
|
|
67
|
+
- `stopAtFirstError` - Stop validation on first error
|
|
68
|
+
|
|
69
|
+
## Custom Validators
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { registerDecorator, ValidationOptions } from 'class-validator';
|
|
73
|
+
|
|
74
|
+
export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
|
|
75
|
+
return function (object: Object, propertyName: string) {
|
|
76
|
+
registerDecorator({
|
|
77
|
+
name: 'isLongerThan',
|
|
78
|
+
target: object.constructor,
|
|
79
|
+
propertyName: propertyName,
|
|
80
|
+
constraints: [property],
|
|
81
|
+
options: validationOptions,
|
|
82
|
+
validator: {
|
|
83
|
+
validate(value: any, args: ValidationArguments) {
|
|
84
|
+
const [relatedPropertyName] = args.constraints;
|
|
85
|
+
const relatedValue = (args.object as any)[relatedPropertyName];
|
|
86
|
+
return typeof value === 'string' && typeof relatedValue === 'string' && value.length > relatedValue.length;
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Validation Groups
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
export class CreateUserDto {
|
|
98
|
+
@IsString({ groups: ['registration'] })
|
|
99
|
+
email: string;
|
|
100
|
+
|
|
101
|
+
@IsString({ groups: ['update'] })
|
|
102
|
+
password: string;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Conditional Validation
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
@ValidateIf((o) => o.type === 'email')
|
|
110
|
+
@IsEmail()
|
|
111
|
+
email: string;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Key Points
|
|
115
|
+
|
|
116
|
+
- Use `ValidationPipe` globally for automatic validation
|
|
117
|
+
- Decorate DTO properties with `class-validator` decorators
|
|
118
|
+
- Enable `transform` to auto-transform payloads
|
|
119
|
+
- Use `whitelist` to strip unknown properties
|
|
120
|
+
- Create custom validators for complex validation
|
|
121
|
+
- Use validation groups for different scenarios
|
|
122
|
+
|
|
123
|
+
<!--
|
|
124
|
+
Source references:
|
|
125
|
+
- https://docs.nestjs.com/techniques/validation
|
|
126
|
+
-->
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: versioning
|
|
3
|
+
description: API versioning strategies in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API Versioning
|
|
7
|
+
|
|
8
|
+
NestJS supports four versioning strategies for HTTP applications.
|
|
9
|
+
|
|
10
|
+
## Versioning Types
|
|
11
|
+
|
|
12
|
+
| Type | Description |
|
|
13
|
+
|------|-------------|
|
|
14
|
+
| URI | Version in URL path (`/v1/cats`) |
|
|
15
|
+
| Header | Custom header specifies version |
|
|
16
|
+
| Media Type | `Accept` header with version |
|
|
17
|
+
| Custom | Custom extractor function |
|
|
18
|
+
|
|
19
|
+
## Enable Versioning
|
|
20
|
+
|
|
21
|
+
### URI Versioning (Default)
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// main.ts
|
|
25
|
+
import { VersioningType } from '@nestjs/common';
|
|
26
|
+
|
|
27
|
+
const app = await NestFactory.create(AppModule);
|
|
28
|
+
app.enableVersioning({
|
|
29
|
+
type: VersioningType.URI,
|
|
30
|
+
prefix: 'v', // Optional, default is 'v'
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Header Versioning
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
app.enableVersioning({
|
|
38
|
+
type: VersioningType.HEADER,
|
|
39
|
+
header: 'X-API-Version',
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Media Type Versioning
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
app.enableVersioning({
|
|
47
|
+
type: VersioningType.MEDIA_TYPE,
|
|
48
|
+
key: 'v=', // Accept: application/json;v=1
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Controller Versioning
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
@Controller({ path: 'cats', version: '1' })
|
|
56
|
+
export class CatsControllerV1 {
|
|
57
|
+
@Get()
|
|
58
|
+
findAll() {
|
|
59
|
+
return 'Version 1';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@Controller({ path: 'cats', version: '2' })
|
|
64
|
+
export class CatsControllerV2 {
|
|
65
|
+
@Get()
|
|
66
|
+
findAll() {
|
|
67
|
+
return 'Version 2';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Route Versioning
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
@Controller('cats')
|
|
76
|
+
export class CatsController {
|
|
77
|
+
@Version('1')
|
|
78
|
+
@Get()
|
|
79
|
+
findAllV1() {
|
|
80
|
+
return 'Version 1';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Version('2')
|
|
84
|
+
@Get()
|
|
85
|
+
findAllV2() {
|
|
86
|
+
return 'Version 2';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Multiple Versions
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
@Controller({ path: 'cats', version: ['1', '2'] })
|
|
95
|
+
export class CatsController {
|
|
96
|
+
@Get()
|
|
97
|
+
findAll() {
|
|
98
|
+
return 'Handles both v1 and v2';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Version Neutral
|
|
104
|
+
|
|
105
|
+
Routes that work regardless of version:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { VERSION_NEUTRAL } from '@nestjs/common';
|
|
109
|
+
|
|
110
|
+
@Controller({ path: 'health', version: VERSION_NEUTRAL })
|
|
111
|
+
export class HealthController {
|
|
112
|
+
@Get()
|
|
113
|
+
check() {
|
|
114
|
+
return { status: 'ok' };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Default Version
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
app.enableVersioning({
|
|
123
|
+
type: VersioningType.URI,
|
|
124
|
+
defaultVersion: '1',
|
|
125
|
+
// Or multiple: defaultVersion: ['1', '2']
|
|
126
|
+
// Or neutral: defaultVersion: VERSION_NEUTRAL
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Middleware Versioning
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
@Module({})
|
|
134
|
+
export class AppModule implements NestModule {
|
|
135
|
+
configure(consumer: MiddlewareConsumer) {
|
|
136
|
+
consumer
|
|
137
|
+
.apply(LoggerMiddleware)
|
|
138
|
+
.forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Key Points
|
|
144
|
+
|
|
145
|
+
- Unversioned routes return 404 when versioning is enabled
|
|
146
|
+
- URI version appears after global prefix
|
|
147
|
+
- Use `VERSION_NEUTRAL` for version-agnostic endpoints
|
|
148
|
+
- Route-level versions override controller-level versions
|
|
149
|
+
|
|
150
|
+
<!--
|
|
151
|
+
Source references:
|
|
152
|
+
- https://docs.nestjs.com/techniques/versioning
|
|
153
|
+
-->
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: websockets-advanced
|
|
3
|
+
description: WebSocket guards, interceptors, pipes, exception filters, and adapters
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WebSocket Advanced Features
|
|
7
|
+
|
|
8
|
+
## Guards
|
|
9
|
+
|
|
10
|
+
Use `WsException` instead of `HttpException` in WebSocket context:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { WsException } from '@nestjs/websockets';
|
|
14
|
+
|
|
15
|
+
@UseGuards(AuthGuard)
|
|
16
|
+
@SubscribeMessage('events')
|
|
17
|
+
handleEvent(client: Socket, data: unknown) {
|
|
18
|
+
if (!data) {
|
|
19
|
+
throw new WsException('Invalid data');
|
|
20
|
+
}
|
|
21
|
+
return { event: 'events', data };
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Exception Filters
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Catch, ArgumentsHost } from '@nestjs/common';
|
|
29
|
+
import { BaseWsExceptionFilter, WsException } from '@nestjs/websockets';
|
|
30
|
+
|
|
31
|
+
@Catch(WsException)
|
|
32
|
+
export class AllExceptionsFilter extends BaseWsExceptionFilter {
|
|
33
|
+
catch(exception: WsException, host: ArgumentsHost) {
|
|
34
|
+
const client = host.switchToWs().getClient<Socket>();
|
|
35
|
+
const error = exception.getError();
|
|
36
|
+
const details = error instanceof Object ? { ...error } : { message: error };
|
|
37
|
+
client.emit('exception', details);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Apply globally:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
app.useGlobalFilters(new AllExceptionsFilter());
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Interceptors
|
|
49
|
+
|
|
50
|
+
Same pattern as HTTP—use `@UseInterceptors()` on gateway or handlers.
|
|
51
|
+
|
|
52
|
+
## Pipes
|
|
53
|
+
|
|
54
|
+
Validation pipes work in WebSocket handlers. Use `@Payload()` with validation:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
@SubscribeMessage('events')
|
|
58
|
+
handleEvent(
|
|
59
|
+
@Payload(new ValidationPipe({ whitelist: true })) data: CreateEventDto,
|
|
60
|
+
) {
|
|
61
|
+
return { event: 'events', data };
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Custom Adapter
|
|
66
|
+
|
|
67
|
+
Use custom WebSocket adapter (e.g., for Redis pub/sub scaling):
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { IoAdapter } from '@nestjs/platform-socket.io';
|
|
71
|
+
|
|
72
|
+
export class RedisIoAdapter extends IoAdapter {
|
|
73
|
+
// Override to use Redis adapter
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const app = await NestFactory.create(AppModule);
|
|
79
|
+
app.useWebSocketAdapter(new RedisIoAdapter(app));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Key Points
|
|
83
|
+
|
|
84
|
+
- `WsException` from `@nestjs/websockets`
|
|
85
|
+
- `BaseWsExceptionFilter` for WebSocket exception handling
|
|
86
|
+
- Guards, interceptors, pipes work same as HTTP
|
|
87
|
+
- Use `@Payload()` for typed message body with validation
|
|
88
|
+
|
|
89
|
+
<!--
|
|
90
|
+
Source references:
|
|
91
|
+
- https://docs.nestjs.com/websockets/guards
|
|
92
|
+
- https://docs.nestjs.com/websockets/exception-filters
|
|
93
|
+
- https://docs.nestjs.com/websockets/interceptors
|
|
94
|
+
- https://docs.nestjs.com/websockets/pipes
|
|
95
|
+
- https://docs.nestjs.com/websockets/adapter
|
|
96
|
+
-->
|