@hatem427/code-guard-ci 3.0.0 → 3.1.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/config/fastify.config.ts +326 -0
- package/config/hono.config.ts +331 -0
- package/config/nestjs.config.ts +500 -0
- package/config/node.config.ts +425 -0
- package/config/python.config.ts +512 -0
- package/dist/config/fastify.config.d.ts +17 -0
- package/dist/config/fastify.config.d.ts.map +1 -0
- package/dist/config/fastify.config.js +279 -0
- package/dist/config/fastify.config.js.map +1 -0
- package/dist/config/hono.config.d.ts +17 -0
- package/dist/config/hono.config.d.ts.map +1 -0
- package/dist/config/hono.config.js +287 -0
- package/dist/config/hono.config.js.map +1 -0
- package/dist/config/nestjs.config.d.ts +17 -0
- package/dist/config/nestjs.config.d.ts.map +1 -0
- package/dist/config/nestjs.config.js +440 -0
- package/dist/config/nestjs.config.js.map +1 -0
- package/dist/config/node.config.d.ts +17 -0
- package/dist/config/node.config.d.ts.map +1 -0
- package/dist/config/node.config.js +363 -0
- package/dist/config/node.config.js.map +1 -0
- package/dist/config/python.config.d.ts +15 -0
- package/dist/config/python.config.d.ts.map +1 -0
- package/dist/config/python.config.js +475 -0
- package/dist/config/python.config.js.map +1 -0
- package/dist/scripts/auto-fix.d.ts +5 -0
- package/dist/scripts/auto-fix.d.ts.map +1 -1
- package/dist/scripts/auto-fix.js +5 -0
- package/dist/scripts/auto-fix.js.map +1 -1
- package/dist/scripts/cli.js +2 -2
- package/dist/scripts/cli.js.map +1 -1
- package/dist/scripts/config-generators/ai-config-generator.d.ts.map +1 -1
- package/dist/scripts/config-generators/ai-config-generator.js +6 -0
- package/dist/scripts/config-generators/ai-config-generator.js.map +1 -1
- package/dist/scripts/config-generators/eslint-generator.d.ts.map +1 -1
- package/dist/scripts/config-generators/eslint-generator.js +108 -0
- package/dist/scripts/config-generators/eslint-generator.js.map +1 -1
- package/dist/scripts/config-generators/frameworks/fastify.d.ts +6 -0
- package/dist/scripts/config-generators/frameworks/fastify.d.ts.map +1 -0
- package/dist/scripts/config-generators/frameworks/fastify.js +68 -0
- package/dist/scripts/config-generators/frameworks/fastify.js.map +1 -0
- package/dist/scripts/config-generators/frameworks/hono.d.ts +6 -0
- package/dist/scripts/config-generators/frameworks/hono.d.ts.map +1 -0
- package/dist/scripts/config-generators/frameworks/hono.js +63 -0
- package/dist/scripts/config-generators/frameworks/hono.js.map +1 -0
- package/dist/scripts/config-generators/frameworks/index.d.ts +3 -0
- package/dist/scripts/config-generators/frameworks/index.d.ts.map +1 -1
- package/dist/scripts/config-generators/frameworks/index.js +7 -1
- package/dist/scripts/config-generators/frameworks/index.js.map +1 -1
- package/dist/scripts/config-generators/frameworks/nestjs.d.ts +6 -0
- package/dist/scripts/config-generators/frameworks/nestjs.d.ts.map +1 -0
- package/dist/scripts/config-generators/frameworks/nestjs.js +83 -0
- package/dist/scripts/config-generators/frameworks/nestjs.js.map +1 -0
- package/dist/scripts/config-generators/frameworks/node.d.ts +2 -2
- package/dist/scripts/config-generators/frameworks/node.d.ts.map +1 -1
- package/dist/scripts/config-generators/frameworks/node.js +56 -11
- package/dist/scripts/config-generators/frameworks/node.js.map +1 -1
- package/dist/scripts/config-generators/typescript-generator.d.ts.map +1 -1
- package/dist/scripts/config-generators/typescript-generator.js +33 -0
- package/dist/scripts/config-generators/typescript-generator.js.map +1 -1
- package/dist/scripts/config-generators/vscode-generator.d.ts.map +1 -1
- package/dist/scripts/config-generators/vscode-generator.js +73 -0
- package/dist/scripts/config-generators/vscode-generator.js.map +1 -1
- package/dist/scripts/generate-pr-checklist.d.ts +5 -0
- package/dist/scripts/generate-pr-checklist.d.ts.map +1 -1
- package/dist/scripts/generate-pr-checklist.js +6 -1
- package/dist/scripts/generate-pr-checklist.js.map +1 -1
- package/dist/scripts/postinstall.js +38 -0
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/precommit-check.d.ts +13 -0
- package/dist/scripts/precommit-check.d.ts.map +1 -1
- package/dist/scripts/precommit-check.js +288 -5
- package/dist/scripts/precommit-check.js.map +1 -1
- package/dist/scripts/utils/naming-validator.d.ts.map +1 -1
- package/dist/scripts/utils/naming-validator.js +96 -2
- package/dist/scripts/utils/naming-validator.js.map +1 -1
- package/dist/scripts/utils/project-detector.d.ts +12 -9
- package/dist/scripts/utils/project-detector.d.ts.map +1 -1
- package/dist/scripts/utils/project-detector.js +63 -11
- package/dist/scripts/utils/project-detector.js.map +1 -1
- package/dist/scripts/utils/structure-validator.d.ts.map +1 -1
- package/dist/scripts/utils/structure-validator.js +50 -0
- package/dist/scripts/utils/structure-validator.js.map +1 -1
- package/package.json +10 -3
- package/scripts/auto-fix.ts +5 -0
- package/scripts/cli.ts +2 -2
- package/scripts/config-generators/ai-config-generator.ts +9 -0
- package/scripts/config-generators/eslint-generator.ts +110 -0
- package/scripts/config-generators/frameworks/fastify.ts +65 -0
- package/scripts/config-generators/frameworks/hono.ts +60 -0
- package/scripts/config-generators/frameworks/index.ts +3 -0
- package/scripts/config-generators/frameworks/nestjs.ts +80 -0
- package/scripts/config-generators/frameworks/node.ts +57 -11
- package/scripts/config-generators/typescript-generator.ts +36 -0
- package/scripts/config-generators/vscode-generator.ts +84 -0
- package/scripts/generate-pr-checklist.ts +6 -1
- package/scripts/postinstall.ts +38 -0
- package/scripts/precommit-check.ts +334 -6
- package/scripts/utils/naming-validator.ts +104 -2
- package/scripts/utils/project-detector.ts +78 -11
- package/scripts/utils/structure-validator.ts +54 -0
- package/templates/feature-doc-backend.md +114 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ============================================================================
|
|
4
|
+
* nestjs.config.ts — NestJS-specific coding rules
|
|
5
|
+
* ============================================================================
|
|
6
|
+
*
|
|
7
|
+
* Registers rules that only apply to NestJS projects:
|
|
8
|
+
* - Module / controller / service separation
|
|
9
|
+
* - DTO validation enforcement
|
|
10
|
+
* - Security patterns (no raw process.env, no eval)
|
|
11
|
+
* - Error handling with HttpException
|
|
12
|
+
* - Dependency injection correctness
|
|
13
|
+
* - Async/await patterns
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.nestjsRules = void 0;
|
|
17
|
+
const guidelines_config_1 = require("./guidelines.config");
|
|
18
|
+
const nestjsRules = [
|
|
19
|
+
// ── Architecture ──────────────────────────────────────────────────────────
|
|
20
|
+
// ─────────────────────────────────────────
|
|
21
|
+
// RULE: nestjs-no-logic-in-controller
|
|
22
|
+
// ROLE: Enforce thin controllers
|
|
23
|
+
// PURPOSE: Controllers should only parse the HTTP request and delegate to
|
|
24
|
+
// the service layer. Business logic in a controller cannot be
|
|
25
|
+
// unit-tested without spinning up a full HTTP context.
|
|
26
|
+
// EXAMPLE:
|
|
27
|
+
// WRONG:
|
|
28
|
+
// @Post()
|
|
29
|
+
// async create(@Body() dto: CreateUserDto) {
|
|
30
|
+
// const salt = await bcrypt.genSalt();
|
|
31
|
+
// const hash = await bcrypt.hash(dto.password, salt);
|
|
32
|
+
// return this.usersRepo.save({ ...dto, password: hash });
|
|
33
|
+
// }
|
|
34
|
+
// RIGHT:
|
|
35
|
+
// @Post()
|
|
36
|
+
// async create(@Body() dto: CreateUserDto) {
|
|
37
|
+
// return this.usersService.create(dto);
|
|
38
|
+
// }
|
|
39
|
+
// ─────────────────────────────────────────
|
|
40
|
+
{
|
|
41
|
+
id: 'nestjs-no-logic-in-controller',
|
|
42
|
+
label: 'No business logic in controllers',
|
|
43
|
+
description: 'Controllers should only handle HTTP concerns (parse request, call service, return response). Move all business logic to the service layer.',
|
|
44
|
+
severity: 'warning',
|
|
45
|
+
fileExtensions: ['ts'],
|
|
46
|
+
pattern: null,
|
|
47
|
+
customCheck: (file) => {
|
|
48
|
+
const violations = [];
|
|
49
|
+
if (!file.relativePath.includes('.controller.'))
|
|
50
|
+
return [];
|
|
51
|
+
// Flag common business logic patterns inside controllers
|
|
52
|
+
const businessPatterns = [
|
|
53
|
+
{ regex: /bcrypt\.(hash|compare|genSalt)/g, label: 'bcrypt hashing' },
|
|
54
|
+
{ regex: /\.save\s*\(/g, label: 'direct repository save()' },
|
|
55
|
+
{ regex: /\.find\s*\(/g, label: 'direct repository find()' },
|
|
56
|
+
{ regex: /new\s+\w+(?:Service|Repository)\s*\(/g, label: 'manual service instantiation' },
|
|
57
|
+
];
|
|
58
|
+
for (let i = 0; i < file.lines.length; i++) {
|
|
59
|
+
for (const { regex, label } of businessPatterns) {
|
|
60
|
+
regex.lastIndex = 0;
|
|
61
|
+
if (regex.test(file.lines[i])) {
|
|
62
|
+
violations.push({
|
|
63
|
+
line: i + 1,
|
|
64
|
+
message: `Business logic found in controller (${label}). Move to the service layer.`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return violations;
|
|
70
|
+
},
|
|
71
|
+
applicableTo: ['nestjs'],
|
|
72
|
+
category: 'Architecture',
|
|
73
|
+
},
|
|
74
|
+
// ─────────────────────────────────────────
|
|
75
|
+
// RULE: nestjs-use-dto
|
|
76
|
+
// ROLE: Enforce DTO type-safety on route handlers
|
|
77
|
+
// PURPOSE: Using plain 'any' or 'object' types on @Body()/@Param()/@Query()
|
|
78
|
+
// bypasses TypeScript type safety and class-validator validation.
|
|
79
|
+
// DTOs document the API contract and allow automatic validation.
|
|
80
|
+
// EXAMPLE:
|
|
81
|
+
// WRONG:
|
|
82
|
+
// @Post() create(@Body() body: any) { ... }
|
|
83
|
+
// RIGHT:
|
|
84
|
+
// @Post() create(@Body() body: CreateUserDto) { ... }
|
|
85
|
+
// ─────────────────────────────────────────
|
|
86
|
+
{
|
|
87
|
+
id: 'nestjs-use-dto',
|
|
88
|
+
label: 'Use DTOs for @Body(), @Param(), @Query()',
|
|
89
|
+
description: 'Always type @Body(), @Param(), and @Query() parameters with dedicated DTO classes, not "any" or "object". DTOs enforce validation and document the API contract.',
|
|
90
|
+
severity: 'error',
|
|
91
|
+
fileExtensions: ['ts'],
|
|
92
|
+
pattern: /@(?:Body|Param|Query)\(\s*\)\s*\w+\s*:\s*(?:any|object)\b/g,
|
|
93
|
+
applicableTo: ['nestjs'],
|
|
94
|
+
category: 'Type Safety',
|
|
95
|
+
},
|
|
96
|
+
// ── Validation ────────────────────────────────────────────────────────────
|
|
97
|
+
// ─────────────────────────────────────────
|
|
98
|
+
// RULE: nestjs-dto-needs-class-validator
|
|
99
|
+
// ROLE: Enforce class-validator decorators on DTO files
|
|
100
|
+
// PURPOSE: A DTO class without class-validator decorators gets no runtime
|
|
101
|
+
// validation. The ValidationPipe only enforces rules declared
|
|
102
|
+
// with @IsString(), @IsEmail(), @IsNotEmpty(), etc.
|
|
103
|
+
// EXAMPLE:
|
|
104
|
+
// WRONG:
|
|
105
|
+
// export class CreateUserDto { email: string; name: string; }
|
|
106
|
+
// RIGHT:
|
|
107
|
+
// export class CreateUserDto {
|
|
108
|
+
// @IsEmail() email: string;
|
|
109
|
+
// @IsNotEmpty() @IsString() name: string;
|
|
110
|
+
// }
|
|
111
|
+
// ─────────────────────────────────────────
|
|
112
|
+
{
|
|
113
|
+
id: 'nestjs-dto-needs-class-validator',
|
|
114
|
+
label: 'DTOs must use class-validator decorators',
|
|
115
|
+
description: 'DTO files must import and use class-validator decorators (@IsString, @IsEmail, @IsNotEmpty, etc.) for runtime validation with ValidationPipe.',
|
|
116
|
+
severity: 'error',
|
|
117
|
+
fileExtensions: ['ts'],
|
|
118
|
+
pattern: null,
|
|
119
|
+
customCheck: (file) => {
|
|
120
|
+
if (!file.relativePath.endsWith('.dto.ts'))
|
|
121
|
+
return [];
|
|
122
|
+
const hasClassValidator = /from ['"]class-validator['"]/.test(file.content);
|
|
123
|
+
const hasClass = /export\s+class\s+\w+Dto/.test(file.content);
|
|
124
|
+
if (hasClass && !hasClassValidator) {
|
|
125
|
+
return [
|
|
126
|
+
{
|
|
127
|
+
line: null,
|
|
128
|
+
message: 'DTO file is missing class-validator imports. Add @IsString(), @IsEmail(), @IsNotEmpty(), etc. for runtime validation.',
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
},
|
|
134
|
+
applicableTo: ['nestjs'],
|
|
135
|
+
category: 'Validation',
|
|
136
|
+
},
|
|
137
|
+
// ─────────────────────────────────────────
|
|
138
|
+
// RULE: nestjs-dto-whitelist-validation
|
|
139
|
+
// ROLE: Enforce input sanitization at ValidationPipe level
|
|
140
|
+
// PURPOSE: Without { whitelist: true }, extra properties sent by clients
|
|
141
|
+
// pass through to the service layer unchecked, creating mass
|
|
142
|
+
// assignment vulnerabilities.
|
|
143
|
+
// EXAMPLE:
|
|
144
|
+
// WRONG:
|
|
145
|
+
// app.useGlobalPipes(new ValidationPipe());
|
|
146
|
+
// RIGHT:
|
|
147
|
+
// app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }));
|
|
148
|
+
// ─────────────────────────────────────────
|
|
149
|
+
{
|
|
150
|
+
id: 'nestjs-dto-whitelist-validation',
|
|
151
|
+
label: 'ValidationPipe must use whitelist: true',
|
|
152
|
+
description: 'Set whitelist: true and forbidNonWhitelisted: true on ValidationPipe to strip/reject extra properties and prevent mass assignment vulnerabilities.',
|
|
153
|
+
severity: 'error',
|
|
154
|
+
fileExtensions: ['ts'],
|
|
155
|
+
pattern: null,
|
|
156
|
+
customCheck: (file) => {
|
|
157
|
+
// Only check main.ts or bootstrap files
|
|
158
|
+
if (!file.relativePath.endsWith('main.ts'))
|
|
159
|
+
return [];
|
|
160
|
+
const hasValidationPipe = /new\s+ValidationPipe/.test(file.content);
|
|
161
|
+
const hasWhitelist = /whitelist\s*:\s*true/.test(file.content);
|
|
162
|
+
if (hasValidationPipe && !hasWhitelist) {
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
line: null,
|
|
166
|
+
message: 'ValidationPipe is missing whitelist: true. Add: new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true })',
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
return [];
|
|
171
|
+
},
|
|
172
|
+
applicableTo: ['nestjs'],
|
|
173
|
+
category: 'Validation',
|
|
174
|
+
},
|
|
175
|
+
// ── Error Handling ────────────────────────────────────────────────────────
|
|
176
|
+
// ─────────────────────────────────────────
|
|
177
|
+
// RULE: nestjs-use-http-exception
|
|
178
|
+
// ROLE: Enforce NestJS-native error throwing
|
|
179
|
+
// PURPOSE: Throwing raw Error objects in a NestJS context bypasses the
|
|
180
|
+
// exception filter pipeline, resulting in a generic 500 with
|
|
181
|
+
// an exposed stack trace. Use built-in HttpException subclasses
|
|
182
|
+
// (NotFoundException, BadRequestException, etc.) so the global
|
|
183
|
+
// filter can shape the response correctly.
|
|
184
|
+
// EXAMPLE:
|
|
185
|
+
// WRONG:
|
|
186
|
+
// throw new Error('User not found');
|
|
187
|
+
// RIGHT:
|
|
188
|
+
// throw new NotFoundException('User not found');
|
|
189
|
+
// ─────────────────────────────────────────
|
|
190
|
+
{
|
|
191
|
+
id: 'nestjs-use-http-exception',
|
|
192
|
+
label: 'Throw HttpException subclasses, not raw Error',
|
|
193
|
+
description: 'Throw NestJS HttpException subclasses (NotFoundException, BadRequestException, ForbiddenException, etc.) instead of raw Error objects to ensure proper HTTP response shaping.',
|
|
194
|
+
severity: 'warning',
|
|
195
|
+
fileExtensions: ['ts'],
|
|
196
|
+
pattern: null,
|
|
197
|
+
customCheck: (file) => {
|
|
198
|
+
const violations = [];
|
|
199
|
+
if (!file.relativePath.includes('.service.') && !file.relativePath.includes('.controller.')) {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
for (let i = 0; i < file.lines.length; i++) {
|
|
203
|
+
const line = file.lines[i];
|
|
204
|
+
// Match "throw new Error(" but not "throw new HttpException", "throw new NotFoundException", etc.
|
|
205
|
+
if (/throw\s+new\s+Error\s*\(/.test(line)) {
|
|
206
|
+
violations.push({
|
|
207
|
+
line: i + 1,
|
|
208
|
+
message: 'Raw Error thrown. Use NestJS HttpException subclasses: NotFoundException, BadRequestException, ForbiddenException, ConflictException, etc.',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return violations;
|
|
213
|
+
},
|
|
214
|
+
applicableTo: ['nestjs'],
|
|
215
|
+
category: 'Error Handling',
|
|
216
|
+
},
|
|
217
|
+
// ── Security ──────────────────────────────────────────────────────────────
|
|
218
|
+
// ─────────────────────────────────────────
|
|
219
|
+
// RULE: nestjs-no-process-env-in-services
|
|
220
|
+
// ROLE: Enforce centralised configuration access
|
|
221
|
+
// PURPOSE: Accessing process.env directly in services scatters
|
|
222
|
+
// configuration reads across the codebase, making it impossible
|
|
223
|
+
// to validate env vars at startup or mock config in tests.
|
|
224
|
+
// ConfigService provides a single validated source of truth.
|
|
225
|
+
// EXAMPLE:
|
|
226
|
+
// WRONG:
|
|
227
|
+
// const secret = process.env['JWT_SECRET'];
|
|
228
|
+
// RIGHT:
|
|
229
|
+
// constructor(private config: ConfigService) {}
|
|
230
|
+
// const secret = this.config.get<string>('JWT_SECRET');
|
|
231
|
+
// ─────────────────────────────────────────
|
|
232
|
+
{
|
|
233
|
+
id: 'nestjs-no-process-env-in-services',
|
|
234
|
+
label: 'Use ConfigService, not process.env directly',
|
|
235
|
+
description: 'Access environment variables via NestJS ConfigService, not process.env directly. This enables validation at startup and simplifies testing.',
|
|
236
|
+
severity: 'warning',
|
|
237
|
+
fileExtensions: ['ts'],
|
|
238
|
+
pattern: null,
|
|
239
|
+
customCheck: (file) => {
|
|
240
|
+
const violations = [];
|
|
241
|
+
// Only check services and controllers (not main.ts, config files)
|
|
242
|
+
if (!file.relativePath.includes('.service.') &&
|
|
243
|
+
!file.relativePath.includes('.controller.') &&
|
|
244
|
+
!file.relativePath.includes('.guard.')) {
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
for (let i = 0; i < file.lines.length; i++) {
|
|
248
|
+
if (/process\.env\b/.test(file.lines[i])) {
|
|
249
|
+
violations.push({
|
|
250
|
+
line: i + 1,
|
|
251
|
+
message: 'process.env used directly. Inject ConfigService and use this.config.get("VAR_NAME") instead.',
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return violations;
|
|
256
|
+
},
|
|
257
|
+
applicableTo: ['nestjs'],
|
|
258
|
+
category: 'Security',
|
|
259
|
+
},
|
|
260
|
+
// ─────────────────────────────────────────
|
|
261
|
+
// RULE: nestjs-no-manual-instantiation
|
|
262
|
+
// ROLE: Enforce NestJS Dependency Injection
|
|
263
|
+
// PURPOSE: Manually instantiating services with `new` bypasses NestJS's
|
|
264
|
+
// DI container. The new instance won't have its own dependencies
|
|
265
|
+
// resolved, won't be scoped correctly, and can't be mocked in tests.
|
|
266
|
+
// EXAMPLE:
|
|
267
|
+
// WRONG:
|
|
268
|
+
// const service = new UserService(new UsersRepository());
|
|
269
|
+
// RIGHT:
|
|
270
|
+
// constructor(private readonly usersService: UsersService) {}
|
|
271
|
+
// ─────────────────────────────────────────
|
|
272
|
+
{
|
|
273
|
+
id: 'nestjs-no-manual-instantiation',
|
|
274
|
+
label: 'No manual service instantiation with new',
|
|
275
|
+
description: 'Never instantiate NestJS services, repositories, or guards with "new". Let the DI container manage lifecycle and dependency resolution.',
|
|
276
|
+
severity: 'error',
|
|
277
|
+
fileExtensions: ['ts'],
|
|
278
|
+
pattern: null,
|
|
279
|
+
customCheck: (file) => {
|
|
280
|
+
const violations = [];
|
|
281
|
+
if (!file.relativePath.includes('.service.') &&
|
|
282
|
+
!file.relativePath.includes('.controller.') &&
|
|
283
|
+
!file.relativePath.includes('.module.')) {
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
for (let i = 0; i < file.lines.length; i++) {
|
|
287
|
+
const line = file.lines[i];
|
|
288
|
+
// Detect `new SomeService(` or `new SomeRepository(` patterns
|
|
289
|
+
if (/new\s+[A-Z]\w*(?:Service|Repository|Guard|Pipe)\s*\(/.test(line)) {
|
|
290
|
+
violations.push({
|
|
291
|
+
line: i + 1,
|
|
292
|
+
message: 'Manual service/guard/repository instantiation found. Inject via constructor or use the DI container.',
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return violations;
|
|
297
|
+
},
|
|
298
|
+
applicableTo: ['nestjs'],
|
|
299
|
+
category: 'Dependency Injection',
|
|
300
|
+
},
|
|
301
|
+
// ── Async Patterns ────────────────────────────────────────────────────────
|
|
302
|
+
// ─────────────────────────────────────────
|
|
303
|
+
// RULE: nestjs-async-await-consistency
|
|
304
|
+
// ROLE: Enforce consistent async patterns
|
|
305
|
+
// PURPOSE: Mixing Promises and callbacks without await or without
|
|
306
|
+
// propagating errors upward leads to unhandled rejections that
|
|
307
|
+
// silently crash the process or produce incorrect API responses.
|
|
308
|
+
// EXAMPLE:
|
|
309
|
+
// WRONG:
|
|
310
|
+
// findUser(id: string) {
|
|
311
|
+
// return this.repo.findOne(id).then(user => {
|
|
312
|
+
// if (!user) throw new NotFoundException();
|
|
313
|
+
// return user;
|
|
314
|
+
// });
|
|
315
|
+
// }
|
|
316
|
+
// RIGHT:
|
|
317
|
+
// async findUser(id: string): Promise<User> {
|
|
318
|
+
// const user = await this.repo.findOne({ where: { id } });
|
|
319
|
+
// if (!user) throw new NotFoundException('User not found');
|
|
320
|
+
// return user;
|
|
321
|
+
// }
|
|
322
|
+
// ─────────────────────────────────────────
|
|
323
|
+
{
|
|
324
|
+
id: 'nestjs-async-await-consistency',
|
|
325
|
+
label: 'Use async/await, not .then()/.catch() chains',
|
|
326
|
+
description: 'Prefer async/await over .then()/.catch() chains in NestJS services and controllers for consistent, readable async code that handles errors properly.',
|
|
327
|
+
severity: 'warning',
|
|
328
|
+
fileExtensions: ['ts'],
|
|
329
|
+
pattern: /\.then\s*\(\s*(?:async\s*)?\(|\.catch\s*\(\s*(?:async\s*)?\(/g,
|
|
330
|
+
applicableTo: ['nestjs'],
|
|
331
|
+
category: 'Async Patterns',
|
|
332
|
+
},
|
|
333
|
+
// ── Module Structure ──────────────────────────────────────────────────────
|
|
334
|
+
// ─────────────────────────────────────────
|
|
335
|
+
// RULE: nestjs-injectable-decorator
|
|
336
|
+
// ROLE: Enforce @Injectable() on all service classes
|
|
337
|
+
// PURPOSE: A service class without @Injectable() cannot be resolved by
|
|
338
|
+
// the NestJS DI container. The app will throw a runtime error
|
|
339
|
+
// when the module tries to instantiate it.
|
|
340
|
+
// EXAMPLE:
|
|
341
|
+
// WRONG:
|
|
342
|
+
// export class UserService { ... }
|
|
343
|
+
// RIGHT:
|
|
344
|
+
// @Injectable()
|
|
345
|
+
// export class UserService { ... }
|
|
346
|
+
// ─────────────────────────────────────────
|
|
347
|
+
{
|
|
348
|
+
id: 'nestjs-injectable-decorator',
|
|
349
|
+
label: 'Service classes must use @Injectable()',
|
|
350
|
+
description: 'All service classes must be decorated with @Injectable() to be manageable by the NestJS DI container.',
|
|
351
|
+
severity: 'error',
|
|
352
|
+
fileExtensions: ['ts'],
|
|
353
|
+
pattern: null,
|
|
354
|
+
customCheck: (file) => {
|
|
355
|
+
if (!file.relativePath.endsWith('.service.ts'))
|
|
356
|
+
return [];
|
|
357
|
+
const hasInjectable = /@Injectable\s*\(/.test(file.content);
|
|
358
|
+
const hasExportedClass = /export\s+class\s+\w+Service/.test(file.content);
|
|
359
|
+
if (hasExportedClass && !hasInjectable) {
|
|
360
|
+
return [
|
|
361
|
+
{
|
|
362
|
+
line: null,
|
|
363
|
+
message: 'Service class is missing @Injectable() decorator. NestJS cannot inject this service without it.',
|
|
364
|
+
},
|
|
365
|
+
];
|
|
366
|
+
}
|
|
367
|
+
return [];
|
|
368
|
+
},
|
|
369
|
+
applicableTo: ['nestjs'],
|
|
370
|
+
category: 'Module Structure',
|
|
371
|
+
},
|
|
372
|
+
// ─────────────────────────────────────────
|
|
373
|
+
// RULE: nestjs-response-type-annotation
|
|
374
|
+
// ROLE: Enforce explicit return types on controllers
|
|
375
|
+
// PURPOSE: Controller handler methods without explicit return types make
|
|
376
|
+
// it hard to know the API contract from code alone and can lead
|
|
377
|
+
// to accidental leaking of internal fields (e.g., passwords).
|
|
378
|
+
// EXAMPLE:
|
|
379
|
+
// WRONG:
|
|
380
|
+
// @Get(':id') findOne(@Param('id') id: string) { ... }
|
|
381
|
+
// RIGHT:
|
|
382
|
+
// @Get(':id') findOne(@Param('id') id: string): Promise<UserResponseDto> { ... }
|
|
383
|
+
// ─────────────────────────────────────────
|
|
384
|
+
{
|
|
385
|
+
id: 'nestjs-response-type-annotation',
|
|
386
|
+
label: 'Controller handlers must declare return types',
|
|
387
|
+
description: 'Add explicit return types to all controller handler methods to document the response contract and prevent accidental data leaks.',
|
|
388
|
+
severity: 'warning',
|
|
389
|
+
fileExtensions: ['ts'],
|
|
390
|
+
pattern: null,
|
|
391
|
+
customCheck: (file) => {
|
|
392
|
+
const violations = [];
|
|
393
|
+
if (!file.relativePath.includes('.controller.'))
|
|
394
|
+
return [];
|
|
395
|
+
for (let i = 0; i < file.lines.length; i++) {
|
|
396
|
+
const line = file.lines[i];
|
|
397
|
+
// Handler: has @Get/@Post/@Put/@Patch/@Delete decorator on previous lines
|
|
398
|
+
// and async method without return type annotation
|
|
399
|
+
if (/(?:async\s+\w+|(?<!\/\/)\w+)\s*\(@(?:Body|Param|Query)/.test(line) &&
|
|
400
|
+
!/\)\s*:\s*(?:Promise|Observable|\w+)/.test(line)) {
|
|
401
|
+
violations.push({
|
|
402
|
+
line: i + 1,
|
|
403
|
+
message: 'Controller handler is missing an explicit return type. Add `: Promise<ResponseDto>` to document the API contract.',
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return violations;
|
|
408
|
+
},
|
|
409
|
+
applicableTo: ['nestjs'],
|
|
410
|
+
category: 'Type Safety',
|
|
411
|
+
},
|
|
412
|
+
// ── Security - Sensitive Data ──────────────────────────────────────────────
|
|
413
|
+
// ─────────────────────────────────────────
|
|
414
|
+
// RULE: nestjs-no-password-in-response
|
|
415
|
+
// ROLE: Prevent credential leaks in API responses
|
|
416
|
+
// PURPOSE: Returning entity objects directly from controllers exposes
|
|
417
|
+
// all fields including password hashes. Always map to a response
|
|
418
|
+
// DTO that explicitly includes only safe fields.
|
|
419
|
+
// EXAMPLE:
|
|
420
|
+
// WRONG:
|
|
421
|
+
// return this.usersService.findOne(id); // returns User entity with password
|
|
422
|
+
// RIGHT:
|
|
423
|
+
// const user = await this.usersService.findOne(id);
|
|
424
|
+
// return plainToInstance(UserResponseDto, user, { excludeExtraneousValues: true });
|
|
425
|
+
// ─────────────────────────────────────────
|
|
426
|
+
{
|
|
427
|
+
id: 'nestjs-no-password-in-response',
|
|
428
|
+
label: 'Never return password fields in responses',
|
|
429
|
+
description: 'Map entity results to response DTOs using class-transformer. Never return raw entity objects that may contain password hashes or sensitive fields.',
|
|
430
|
+
severity: 'error',
|
|
431
|
+
fileExtensions: ['ts'],
|
|
432
|
+
pattern: /(?:password|passwordHash|hashedPassword)\s*[,}]|select\s*:\s*{[^}]*password/g,
|
|
433
|
+
applicableTo: ['nestjs'],
|
|
434
|
+
category: 'Security',
|
|
435
|
+
},
|
|
436
|
+
];
|
|
437
|
+
exports.nestjsRules = nestjsRules;
|
|
438
|
+
// Register all NestJS-specific rules
|
|
439
|
+
(0, guidelines_config_1.registerRules)('nestjs', nestjsRules);
|
|
440
|
+
//# sourceMappingURL=nestjs.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs.config.js","sourceRoot":"","sources":["../../config/nestjs.config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* node.config.ts — Express / Node.js-specific coding rules
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* Registers rules that apply to Express and generic Node.js backend projects:
|
|
7
|
+
* - Route handler / service separation
|
|
8
|
+
* - Async error propagation
|
|
9
|
+
* - Input validation enforcement
|
|
10
|
+
* - Security: helmet, CORS, parameterized queries
|
|
11
|
+
* - Environment configuration patterns
|
|
12
|
+
* - Graceful shutdown
|
|
13
|
+
*/
|
|
14
|
+
import { Rule } from './guidelines.config';
|
|
15
|
+
declare const nodeRules: Rule[];
|
|
16
|
+
export { nodeRules };
|
|
17
|
+
//# sourceMappingURL=node.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.config.d.ts","sourceRoot":"","sources":["../../config/node.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiB,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE1D,QAAA,MAAM,SAAS,EAAE,IAAI,EAmZpB,CAAC;AAKF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|