@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.
Files changed (85) hide show
  1. package/README.md +5 -1
  2. package/package.json +1 -1
  3. package/registry/registry.json +15 -0
  4. package/specs/coding.md +11 -0
  5. package/src/commands/skills/add.js +115 -31
  6. package/src/commands/skills/list.js +25 -52
  7. package/src/commands/skills/remove.js +45 -27
  8. package/src/commands/skills/resolve.js +104 -0
  9. package/src/commands/skills/update.js +58 -74
  10. package/src/config.js +5 -0
  11. package/src/skills/nest-best-practices/SKILL.md +251 -0
  12. package/src/skills/nest-best-practices/references/best-practices-request-lifecycle.md +158 -0
  13. package/src/skills/nest-best-practices/references/cli-monorepo.md +106 -0
  14. package/src/skills/nest-best-practices/references/cli-overview.md +157 -0
  15. package/src/skills/nest-best-practices/references/core-controllers.md +165 -0
  16. package/src/skills/nest-best-practices/references/core-dependency-injection.md +179 -0
  17. package/src/skills/nest-best-practices/references/core-middleware.md +139 -0
  18. package/src/skills/nest-best-practices/references/core-modules.md +138 -0
  19. package/src/skills/nest-best-practices/references/core-providers.md +188 -0
  20. package/src/skills/nest-best-practices/references/faq-raw-body-hybrid.md +122 -0
  21. package/src/skills/nest-best-practices/references/fundamentals-circular-dependency.md +89 -0
  22. package/src/skills/nest-best-practices/references/fundamentals-custom-decorators.md +107 -0
  23. package/src/skills/nest-best-practices/references/fundamentals-dynamic-modules.md +125 -0
  24. package/src/skills/nest-best-practices/references/fundamentals-exception-filters.md +202 -0
  25. package/src/skills/nest-best-practices/references/fundamentals-execution-context.md +107 -0
  26. package/src/skills/nest-best-practices/references/fundamentals-guards.md +136 -0
  27. package/src/skills/nest-best-practices/references/fundamentals-interceptors.md +187 -0
  28. package/src/skills/nest-best-practices/references/fundamentals-lazy-loading.md +89 -0
  29. package/src/skills/nest-best-practices/references/fundamentals-lifecycle-events.md +87 -0
  30. package/src/skills/nest-best-practices/references/fundamentals-module-reference.md +107 -0
  31. package/src/skills/nest-best-practices/references/fundamentals-pipes.md +197 -0
  32. package/src/skills/nest-best-practices/references/fundamentals-provider-scopes.md +92 -0
  33. package/src/skills/nest-best-practices/references/fundamentals-testing.md +142 -0
  34. package/src/skills/nest-best-practices/references/graphql-overview.md +233 -0
  35. package/src/skills/nest-best-practices/references/graphql-resolvers-mutations.md +199 -0
  36. package/src/skills/nest-best-practices/references/graphql-scalars-unions-enums.md +180 -0
  37. package/src/skills/nest-best-practices/references/graphql-subscriptions.md +228 -0
  38. package/src/skills/nest-best-practices/references/microservices-grpc.md +175 -0
  39. package/src/skills/nest-best-practices/references/microservices-overview.md +221 -0
  40. package/src/skills/nest-best-practices/references/microservices-transports.md +119 -0
  41. package/src/skills/nest-best-practices/references/openapi-swagger.md +207 -0
  42. package/src/skills/nest-best-practices/references/recipes-authentication.md +97 -0
  43. package/src/skills/nest-best-practices/references/recipes-cqrs.md +176 -0
  44. package/src/skills/nest-best-practices/references/recipes-crud-generator.md +87 -0
  45. package/src/skills/nest-best-practices/references/recipes-documentation.md +93 -0
  46. package/src/skills/nest-best-practices/references/recipes-mongoose.md +153 -0
  47. package/src/skills/nest-best-practices/references/recipes-prisma.md +98 -0
  48. package/src/skills/nest-best-practices/references/recipes-terminus.md +148 -0
  49. package/src/skills/nest-best-practices/references/recipes-typeorm.md +122 -0
  50. package/src/skills/nest-best-practices/references/security-authorization.md +196 -0
  51. package/src/skills/nest-best-practices/references/security-cors-helmet-rate-limiting.md +204 -0
  52. package/src/skills/nest-best-practices/references/security-encryption-hashing.md +93 -0
  53. package/src/skills/nest-best-practices/references/techniques-caching.md +142 -0
  54. package/src/skills/nest-best-practices/references/techniques-compression-streaming-sse.md +194 -0
  55. package/src/skills/nest-best-practices/references/techniques-configuration.md +132 -0
  56. package/src/skills/nest-best-practices/references/techniques-database.md +153 -0
  57. package/src/skills/nest-best-practices/references/techniques-events.md +163 -0
  58. package/src/skills/nest-best-practices/references/techniques-fastify.md +137 -0
  59. package/src/skills/nest-best-practices/references/techniques-file-upload.md +140 -0
  60. package/src/skills/nest-best-practices/references/techniques-http-module.md +176 -0
  61. package/src/skills/nest-best-practices/references/techniques-logging.md +146 -0
  62. package/src/skills/nest-best-practices/references/techniques-mvc-serve-static.md +132 -0
  63. package/src/skills/nest-best-practices/references/techniques-queues.md +162 -0
  64. package/src/skills/nest-best-practices/references/techniques-serialization.md +158 -0
  65. package/src/skills/nest-best-practices/references/techniques-sessions-cookies.md +167 -0
  66. package/src/skills/nest-best-practices/references/techniques-task-scheduling.md +166 -0
  67. package/src/skills/nest-best-practices/references/techniques-validation.md +126 -0
  68. package/src/skills/nest-best-practices/references/techniques-versioning.md +153 -0
  69. package/src/skills/nest-best-practices/references/websockets-advanced.md +96 -0
  70. package/src/skills/nest-best-practices/references/websockets-gateways.md +215 -0
  71. package/src/skills/typescript-expert/SKILL.md +145 -0
  72. package/src/skills/typescript-expert/commands/typescript-fix.md +65 -0
  73. package/src/skills/typescript-expert/references/advanced-conditional-types.md +190 -0
  74. package/src/skills/typescript-expert/references/advanced-decorators.md +243 -0
  75. package/src/skills/typescript-expert/references/advanced-mapped-types.md +223 -0
  76. package/src/skills/typescript-expert/references/advanced-template-literals.md +209 -0
  77. package/src/skills/typescript-expert/references/advanced-type-guards.md +308 -0
  78. package/src/skills/typescript-expert/references/best-practices-patterns.md +313 -0
  79. package/src/skills/typescript-expert/references/best-practices-performance.md +185 -0
  80. package/src/skills/typescript-expert/references/best-practices-tsconfig.md +242 -0
  81. package/src/skills/typescript-expert/references/core-generics.md +246 -0
  82. package/src/skills/typescript-expert/references/core-interfaces-types.md +231 -0
  83. package/src/skills/typescript-expert/references/core-type-system.md +261 -0
  84. package/src/skills/typescript-expert/references/core-utility-types.md +235 -0
  85. package/src/skills/typescript-expert/references/features-ts5x.md +370 -0
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: fundamentals-interceptors
3
+ description: NestJS interceptors for aspect-oriented programming
4
+ ---
5
+
6
+ # Interceptors
7
+
8
+ Interceptors implement aspect-oriented programming (AOP). They can bind extra logic before/after method execution, transform results, handle exceptions, and extend function behavior.
9
+
10
+ ## Basic Interceptor
11
+
12
+ ```typescript
13
+ import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
14
+ import { Observable } from 'rxjs';
15
+ import { tap } from 'rxjs/operators';
16
+
17
+ @Injectable()
18
+ export class LoggingInterceptor implements NestInterceptor {
19
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
20
+ console.log('Before...');
21
+
22
+ const now = Date.now();
23
+ return next
24
+ .handle()
25
+ .pipe(
26
+ tap(() => console.log(`After... ${Date.now() - now}ms`)),
27
+ );
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## Response Transformation
33
+
34
+ ```typescript
35
+ import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
36
+ import { Observable } from 'rxjs';
37
+ import { map } from 'rxjs/operators';
38
+
39
+ export interface Response<T> {
40
+ data: T;
41
+ }
42
+
43
+ @Injectable()
44
+ export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
45
+ intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
46
+ return next.handle().pipe(map(data => ({ data })));
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## Exception Mapping
52
+
53
+ ```typescript
54
+ import {
55
+ Injectable,
56
+ NestInterceptor,
57
+ ExecutionContext,
58
+ BadGatewayException,
59
+ CallHandler,
60
+ } from '@nestjs/common';
61
+ import { Observable, throwError } from 'rxjs';
62
+ import { catchError } from 'rxjs/operators';
63
+
64
+ @Injectable()
65
+ export class ErrorsInterceptor implements NestInterceptor {
66
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
67
+ return next
68
+ .handle()
69
+ .pipe(
70
+ catchError(err => throwError(() => new BadGatewayException())),
71
+ );
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## Caching Interceptor
77
+
78
+ ```typescript
79
+ import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
80
+ import { Observable, of } from 'rxjs';
81
+
82
+ @Injectable()
83
+ export class CacheInterceptor implements NestInterceptor {
84
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
85
+ const isCached = true;
86
+ if (isCached) {
87
+ return of([]);
88
+ }
89
+ return next.handle();
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Timeout Interceptor
95
+
96
+ ```typescript
97
+ import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
98
+ import { Observable, throwError, TimeoutError } from 'rxjs';
99
+ import { catchError, timeout } from 'rxjs/operators';
100
+
101
+ @Injectable()
102
+ export class TimeoutInterceptor implements NestInterceptor {
103
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
104
+ return next.handle().pipe(
105
+ timeout(5000),
106
+ catchError(err => {
107
+ if (err instanceof TimeoutError) {
108
+ return throwError(() => new RequestTimeoutException());
109
+ }
110
+ return throwError(() => err);
111
+ }),
112
+ );
113
+ }
114
+ }
115
+ ```
116
+
117
+ ## Binding Interceptors
118
+
119
+ ### Controller-scoped
120
+
121
+ ```typescript
122
+ @Controller('cats')
123
+ @UseInterceptors(LoggingInterceptor)
124
+ export class CatsController {}
125
+ ```
126
+
127
+ ### Method-scoped
128
+
129
+ ```typescript
130
+ @Get()
131
+ @UseInterceptors(LoggingInterceptor)
132
+ async findAll() {
133
+ return [];
134
+ }
135
+ ```
136
+
137
+ ### Global Interceptors
138
+
139
+ ```typescript
140
+ const app = await NestFactory.create(AppModule);
141
+ app.useGlobalInterceptors(new LoggingInterceptor());
142
+ ```
143
+
144
+ Or via module:
145
+
146
+ ```typescript
147
+ import { Module } from '@nestjs/common';
148
+ import { APP_INTERCEPTOR } from '@nestjs/core';
149
+
150
+ @Module({
151
+ providers: [
152
+ {
153
+ provide: APP_INTERCEPTOR,
154
+ useClass: LoggingInterceptor,
155
+ },
156
+ ],
157
+ })
158
+ export class AppModule {}
159
+ ```
160
+
161
+ ## Null Transformation
162
+
163
+ ```typescript
164
+ @Injectable()
165
+ export class ExcludeNullInterceptor implements NestInterceptor {
166
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
167
+ return next
168
+ .handle()
169
+ .pipe(map(value => value === null ? '' : value));
170
+ }
171
+ }
172
+ ```
173
+
174
+ ## Key Points
175
+
176
+ - Interceptors wrap request/response stream
177
+ - Use RxJS operators to manipulate streams
178
+ - Must call `next.handle()` to continue execution
179
+ - Can transform responses using `map()`
180
+ - Can handle errors using `catchError()`
181
+ - Can override stream completely (caching)
182
+ - Interceptors support dependency injection
183
+
184
+ <!--
185
+ Source references:
186
+ - https://docs.nestjs.com/interceptors
187
+ -->
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: lazy-loading
3
+ description: Lazy loading modules for serverless and performance optimization
4
+ ---
5
+
6
+ # Lazy Loading Modules
7
+
8
+ Lazy loading helps decrease bootstrap time by loading modules only when needed, particularly useful for serverless environments where cold start latency matters.
9
+
10
+ ## Basic Usage
11
+
12
+ Inject `LazyModuleLoader` to load modules on-demand:
13
+
14
+ ```typescript
15
+ import { Injectable } from '@nestjs/common';
16
+ import { LazyModuleLoader } from '@nestjs/core';
17
+
18
+ @Injectable()
19
+ export class CatsService {
20
+ constructor(private lazyModuleLoader: LazyModuleLoader) {}
21
+
22
+ async loadFeature() {
23
+ const { LazyModule } = await import('./lazy.module');
24
+ const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
25
+
26
+ const { LazyService } = await import('./lazy.service');
27
+ const lazyService = moduleRef.get(LazyService);
28
+ return lazyService.doSomething();
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## Module Definition
34
+
35
+ Lazy loaded modules are standard Nest modules:
36
+
37
+ ```typescript
38
+ @Module({
39
+ providers: [LazyService],
40
+ exports: [LazyService],
41
+ })
42
+ export class LazyModule {}
43
+ ```
44
+
45
+ ## Caching Behavior
46
+
47
+ Lazy loaded modules are cached after the first load:
48
+
49
+ ```
50
+ Load "LazyModule" attempt: 1 - time: 2.379ms
51
+ Load "LazyModule" attempt: 2 - time: 0.294ms // Cached
52
+ ```
53
+
54
+ ## Limitations
55
+
56
+ **Cannot lazy load:**
57
+ - Controllers (routes must be registered at startup)
58
+ - Resolvers (GraphQL schema generated at startup)
59
+ - Gateways (WebSocket routes registered at startup)
60
+
61
+ **Other restrictions:**
62
+ - Cannot register as global modules
63
+ - Global enhancers (guards/interceptors) won't work
64
+ - Lifecycle hooks are not invoked in lazy loaded modules
65
+
66
+ ## Webpack Configuration
67
+
68
+ For Webpack, update `tsconfig.json`:
69
+
70
+ ```json
71
+ {
72
+ "compilerOptions": {
73
+ "module": "esnext",
74
+ "moduleResolution": "node"
75
+ }
76
+ }
77
+ ```
78
+
79
+ ## Use Cases
80
+
81
+ Best suited for:
82
+ - Serverless functions (Lambda, Cloud Functions)
83
+ - Worker/cron jobs with conditional logic
84
+ - Feature modules loaded based on runtime conditions
85
+
86
+ <!--
87
+ Source references:
88
+ - https://docs.nestjs.com/fundamentals/lazy-loading-modules
89
+ -->
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: lifecycle-events
3
+ description: Application and provider lifecycle hooks in NestJS
4
+ ---
5
+
6
+ # Lifecycle Events
7
+
8
+ NestJS provides lifecycle hooks that give visibility into key application events and allow running code when they occur.
9
+
10
+ ## Lifecycle Sequence
11
+
12
+ The lifecycle consists of three phases: **initializing**, **running**, and **terminating**.
13
+
14
+ ## Lifecycle Hooks
15
+
16
+ | Hook | When Triggered |
17
+ |------|----------------|
18
+ | `onModuleInit()` | Called once the host module's dependencies have been resolved |
19
+ | `onApplicationBootstrap()` | Called once all modules have been initialized, but before listening |
20
+ | `onModuleDestroy()` | Called after a termination signal (e.g., SIGTERM) has been received |
21
+ | `beforeApplicationShutdown()` | Called after all `onModuleDestroy()` handlers have completed |
22
+ | `onApplicationShutdown()` | Called after connections close (`app.close()` resolves) |
23
+
24
+ ## Usage
25
+
26
+ Implement the appropriate interface to register a lifecycle hook:
27
+
28
+ ```typescript
29
+ import { Injectable, OnModuleInit, OnApplicationBootstrap } from '@nestjs/common';
30
+
31
+ @Injectable()
32
+ export class UsersService implements OnModuleInit, OnApplicationBootstrap {
33
+ onModuleInit() {
34
+ console.log('Module initialized');
35
+ }
36
+
37
+ onApplicationBootstrap() {
38
+ console.log('Application bootstrapped');
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Asynchronous Initialization
44
+
45
+ Hooks can be async - Nest will wait for the promise to resolve:
46
+
47
+ ```typescript
48
+ async onModuleInit(): Promise<void> {
49
+ await this.fetchConfiguration();
50
+ }
51
+ ```
52
+
53
+ ## Enabling Shutdown Hooks
54
+
55
+ Shutdown hooks are disabled by default. Enable them in `main.ts`:
56
+
57
+ ```typescript
58
+ async function bootstrap() {
59
+ const app = await NestFactory.create(AppModule);
60
+ app.enableShutdownHooks();
61
+ await app.listen(3000);
62
+ }
63
+ ```
64
+
65
+ Handle shutdown signals:
66
+
67
+ ```typescript
68
+ @Injectable()
69
+ class DatabaseService implements OnApplicationShutdown {
70
+ onApplicationShutdown(signal: string) {
71
+ console.log(`Received ${signal}, closing connections...`);
72
+ // Cleanup logic
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## Key Points
78
+
79
+ - Lifecycle hooks are not triggered for **request-scoped** providers
80
+ - Execution order depends on module import order
81
+ - Windows has limited shutdown hook support (SIGINT works, SIGTERM doesn't)
82
+ - `enableShutdownHooks` consumes memory by starting listeners
83
+
84
+ <!--
85
+ Source references:
86
+ - https://docs.nestjs.com/fundamentals/lifecycle-events
87
+ -->
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: module-reference
3
+ description: Accessing providers dynamically with ModuleRef
4
+ ---
5
+
6
+ # Module Reference
7
+
8
+ `ModuleRef` provides methods to navigate the DI container and obtain references to providers dynamically.
9
+
10
+ ## Basic Usage
11
+
12
+ Inject `ModuleRef` to access providers:
13
+
14
+ ```typescript
15
+ import { Injectable, OnModuleInit } from '@nestjs/common';
16
+ import { ModuleRef } from '@nestjs/core';
17
+
18
+ @Injectable()
19
+ export class CatsService implements OnModuleInit {
20
+ private service: Service;
21
+
22
+ constructor(private moduleRef: ModuleRef) {}
23
+
24
+ onModuleInit() {
25
+ this.service = this.moduleRef.get(Service);
26
+ }
27
+ }
28
+ ```
29
+
30
+ ## Retrieving Instances
31
+
32
+ ### Static Instances (`get()`)
33
+
34
+ ```typescript
35
+ // From current module
36
+ const service = this.moduleRef.get(Service);
37
+
38
+ // From global context (different module)
39
+ const service = this.moduleRef.get(Service, { strict: false });
40
+ ```
41
+
42
+ ### Scoped Providers (`resolve()`)
43
+
44
+ For transient or request-scoped providers:
45
+
46
+ ```typescript
47
+ const transientService = await this.moduleRef.resolve(TransientService);
48
+ ```
49
+
50
+ Each `resolve()` call returns a unique instance. To get the same instance, pass a context identifier:
51
+
52
+ ```typescript
53
+ import { ContextIdFactory } from '@nestjs/core';
54
+
55
+ const contextId = ContextIdFactory.create();
56
+ const service1 = await this.moduleRef.resolve(TransientService, contextId);
57
+ const service2 = await this.moduleRef.resolve(TransientService, contextId);
58
+ // service1 === service2
59
+ ```
60
+
61
+ ## Request Context
62
+
63
+ Get the context ID from an existing request:
64
+
65
+ ```typescript
66
+ @Injectable()
67
+ export class CatsService {
68
+ constructor(
69
+ @Inject(REQUEST) private request: Record<string, unknown>,
70
+ private moduleRef: ModuleRef,
71
+ ) {}
72
+
73
+ async getRepository() {
74
+ const contextId = ContextIdFactory.getByRequest(this.request);
75
+ return this.moduleRef.resolve(CatsRepository, contextId);
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## Dynamic Instantiation
81
+
82
+ Create instances of classes not registered as providers:
83
+
84
+ ```typescript
85
+ const factory = await this.moduleRef.create(CatsFactory);
86
+ ```
87
+
88
+ ## Register REQUEST Provider
89
+
90
+ For manually created DI sub-trees:
91
+
92
+ ```typescript
93
+ const contextId = ContextIdFactory.create();
94
+ this.moduleRef.registerRequestByContextId(myRequestObject, contextId);
95
+ ```
96
+
97
+ ## Key Points
98
+
99
+ - `get()` only retrieves static (singleton) instances
100
+ - `resolve()` is async and for scoped providers
101
+ - Use `{ strict: false }` to access providers from other modules
102
+ - `ModuleRef` is imported from `@nestjs/core`
103
+
104
+ <!--
105
+ Source references:
106
+ - https://docs.nestjs.com/fundamentals/module-ref
107
+ -->
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: fundamentals-pipes
3
+ description: NestJS pipes for data transformation and validation
4
+ ---
5
+
6
+ # Pipes
7
+
8
+ Pipes transform input data to the desired form or validate input data. They operate on arguments before route handlers are invoked.
9
+
10
+ ## Built-in Pipes
11
+
12
+ - `ValidationPipe` - Validates DTOs
13
+ - `ParseIntPipe` - Parses strings to integers
14
+ - `ParseFloatPipe` - Parses strings to floats
15
+ - `ParseBoolPipe` - Parses strings to booleans
16
+ - `ParseArrayPipe` - Parses strings to arrays
17
+ - `ParseUUIDPipe` - Validates UUIDs
18
+ - `ParseEnumPipe` - Validates enum values
19
+ - `DefaultValuePipe` - Provides default values
20
+ - `ParseFilePipe` - Validates file uploads
21
+ - `ParseDatePipe` - Parses date strings
22
+
23
+ ## Binding Pipes
24
+
25
+ ### Parameter-level Binding
26
+
27
+ ```typescript
28
+ @Get(':id')
29
+ async findOne(@Param('id', ParseIntPipe) id: number) {
30
+ return this.catsService.findOne(id);
31
+ }
32
+ ```
33
+
34
+ ### With Options
35
+
36
+ ```typescript
37
+ @Get(':id')
38
+ async findOne(
39
+ @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
40
+ id: number,
41
+ ) {
42
+ return this.catsService.findOne(id);
43
+ }
44
+ ```
45
+
46
+ ### Query Parameters
47
+
48
+ ```typescript
49
+ @Get()
50
+ async findOne(@Query('id', ParseIntPipe) id: number) {
51
+ return this.catsService.findOne(id);
52
+ }
53
+ ```
54
+
55
+ ## Custom Pipes
56
+
57
+ ### Basic Pipe
58
+
59
+ ```typescript
60
+ import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
61
+
62
+ @Injectable()
63
+ export class ValidationPipe implements PipeTransform {
64
+ transform(value: any, metadata: ArgumentMetadata) {
65
+ return value;
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### Validation Pipe with Zod
71
+
72
+ ```typescript
73
+ import { PipeTransform, ArgumentMetadata, BadRequestException } from '@nestjs/common';
74
+ import { ZodSchema } from 'zod';
75
+
76
+ export class ZodValidationPipe implements PipeTransform {
77
+ constructor(private schema: ZodSchema) {}
78
+
79
+ transform(value: unknown, metadata: ArgumentMetadata) {
80
+ try {
81
+ const parsedValue = this.schema.parse(value);
82
+ return parsedValue;
83
+ } catch (error) {
84
+ throw new BadRequestException('Validation failed');
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ Usage:
91
+
92
+ ```typescript
93
+ @Post()
94
+ @UsePipes(new ZodValidationPipe(createCatSchema))
95
+ async create(@Body() createCatDto: CreateCatDto) {
96
+ this.catsService.create(createCatDto);
97
+ }
98
+ ```
99
+
100
+ ### Validation Pipe with class-validator
101
+
102
+ ```typescript
103
+ import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
104
+ import { validate } from 'class-validator';
105
+ import { plainToInstance } from 'class-transformer';
106
+
107
+ @Injectable()
108
+ export class ValidationPipe implements PipeTransform<any> {
109
+ async transform(value: any, { metatype }: ArgumentMetadata) {
110
+ if (!metatype || !this.toValidate(metatype)) {
111
+ return value;
112
+ }
113
+ const object = plainToInstance(metatype, value);
114
+ const errors = await validate(object);
115
+ if (errors.length > 0) {
116
+ throw new BadRequestException('Validation failed');
117
+ }
118
+ return value;
119
+ }
120
+
121
+ private toValidate(metatype: Function): boolean {
122
+ const types: Function[] = [String, Boolean, Number, Array, Object];
123
+ return !types.includes(metatype);
124
+ }
125
+ }
126
+ ```
127
+
128
+ ### Transformation Pipe
129
+
130
+ ```typescript
131
+ import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
132
+
133
+ @Injectable()
134
+ export class ParseIntPipe implements PipeTransform<string, number> {
135
+ transform(value: string, metadata: ArgumentMetadata): number {
136
+ const val = parseInt(value, 10);
137
+ if (isNaN(val)) {
138
+ throw new BadRequestException('Validation failed');
139
+ }
140
+ return val;
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Global Pipes
146
+
147
+ ```typescript
148
+ async function bootstrap() {
149
+ const app = await NestFactory.create(AppModule);
150
+ app.useGlobalPipes(new ValidationPipe());
151
+ await app.listen(3000);
152
+ }
153
+ ```
154
+
155
+ Or via module:
156
+
157
+ ```typescript
158
+ import { Module } from '@nestjs/common';
159
+ import { APP_PIPE } from '@nestjs/core';
160
+
161
+ @Module({
162
+ providers: [
163
+ {
164
+ provide: APP_PIPE,
165
+ useClass: ValidationPipe,
166
+ },
167
+ ],
168
+ })
169
+ export class AppModule {}
170
+ ```
171
+
172
+ ## Default Values
173
+
174
+ ```typescript
175
+ @Get()
176
+ async findAll(
177
+ @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
178
+ @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
179
+ ) {
180
+ return this.catsService.findAll({ activeOnly, page });
181
+ }
182
+ ```
183
+
184
+ ## Key Points
185
+
186
+ - Pipes run before route handlers
187
+ - Pipes can transform or validate data
188
+ - Use built-in `ValidationPipe` for DTO validation
189
+ - Pipes can be parameter, method, controller, or global scoped
190
+ - Pipes throw exceptions to stop execution
191
+ - Use `DefaultValuePipe` before `Parse*` pipes for optional parameters
192
+
193
+ <!--
194
+ Source references:
195
+ - https://docs.nestjs.com/pipes
196
+ - https://docs.nestjs.com/techniques/validation
197
+ -->