@hatem427/code-guard-ci 3.3.0 → 3.4.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.
Files changed (86) hide show
  1. package/config/angular.config.ts +29 -708
  2. package/config/guidelines.config.ts +5 -130
  3. package/config/nextjs.config.ts +27 -511
  4. package/config/react.config.ts +19 -614
  5. package/dist/config/angular.config.d.ts +5 -8
  6. package/dist/config/angular.config.d.ts.map +1 -1
  7. package/dist/config/angular.config.js +28 -666
  8. package/dist/config/angular.config.js.map +1 -1
  9. package/dist/config/guidelines.config.d.ts.map +1 -1
  10. package/dist/config/guidelines.config.js +5 -127
  11. package/dist/config/guidelines.config.js.map +1 -1
  12. package/dist/config/nextjs.config.d.ts +7 -9
  13. package/dist/config/nextjs.config.d.ts.map +1 -1
  14. package/dist/config/nextjs.config.js +26 -472
  15. package/dist/config/nextjs.config.js.map +1 -1
  16. package/dist/config/react.config.d.ts +4 -5
  17. package/dist/config/react.config.d.ts.map +1 -1
  18. package/dist/config/react.config.js +19 -586
  19. package/dist/config/react.config.js.map +1 -1
  20. package/dist/scripts/auto-fix.d.ts +0 -5
  21. package/dist/scripts/auto-fix.d.ts.map +1 -1
  22. package/dist/scripts/auto-fix.js +0 -5
  23. package/dist/scripts/auto-fix.js.map +1 -1
  24. package/dist/scripts/cli.js +211 -415
  25. package/dist/scripts/cli.js.map +1 -1
  26. package/dist/scripts/config-generators/ai-config-generator.d.ts.map +1 -1
  27. package/dist/scripts/config-generators/ai-config-generator.js +71 -15
  28. package/dist/scripts/config-generators/ai-config-generator.js.map +1 -1
  29. package/dist/scripts/config-generators/eslint-generator.d.ts.map +1 -1
  30. package/dist/scripts/config-generators/eslint-generator.js +13 -625
  31. package/dist/scripts/config-generators/eslint-generator.js.map +1 -1
  32. package/dist/scripts/config-generators/index.d.ts +0 -1
  33. package/dist/scripts/config-generators/index.d.ts.map +1 -1
  34. package/dist/scripts/config-generators/index.js +1 -5
  35. package/dist/scripts/config-generators/index.js.map +1 -1
  36. package/dist/scripts/config-generators/typescript-generator.d.ts.map +1 -1
  37. package/dist/scripts/config-generators/typescript-generator.js +0 -33
  38. package/dist/scripts/config-generators/typescript-generator.js.map +1 -1
  39. package/dist/scripts/config-generators/vscode-generator.d.ts.map +1 -1
  40. package/dist/scripts/config-generators/vscode-generator.js +28 -171
  41. package/dist/scripts/config-generators/vscode-generator.js.map +1 -1
  42. package/dist/scripts/generate-pr-checklist.d.ts +0 -5
  43. package/dist/scripts/generate-pr-checklist.d.ts.map +1 -1
  44. package/dist/scripts/generate-pr-checklist.js +1 -6
  45. package/dist/scripts/generate-pr-checklist.js.map +1 -1
  46. package/dist/scripts/postinstall.js +0 -38
  47. package/dist/scripts/postinstall.js.map +1 -1
  48. package/dist/scripts/precommit-check.d.ts +0 -5
  49. package/dist/scripts/precommit-check.d.ts.map +1 -1
  50. package/dist/scripts/precommit-check.js +92 -149
  51. package/dist/scripts/precommit-check.js.map +1 -1
  52. package/dist/scripts/utils/naming-validator.d.ts.map +1 -1
  53. package/dist/scripts/utils/naming-validator.js +2 -96
  54. package/dist/scripts/utils/naming-validator.js.map +1 -1
  55. package/dist/scripts/utils/project-detector.d.ts +9 -12
  56. package/dist/scripts/utils/project-detector.d.ts.map +1 -1
  57. package/dist/scripts/utils/project-detector.js +11 -63
  58. package/dist/scripts/utils/project-detector.js.map +1 -1
  59. package/dist/scripts/utils/report-generator.js +5 -17
  60. package/dist/scripts/utils/report-generator.js.map +1 -1
  61. package/dist/scripts/utils/structure-validator.d.ts.map +1 -1
  62. package/dist/scripts/utils/structure-validator.js +0 -50
  63. package/dist/scripts/utils/structure-validator.js.map +1 -1
  64. package/package.json +1 -12
  65. package/scripts/auto-fix.ts +0 -5
  66. package/scripts/cli.ts +226 -451
  67. package/scripts/config-generators/ai-config-generator.ts +78 -28
  68. package/scripts/config-generators/eslint-generator.ts +7 -621
  69. package/scripts/config-generators/index.ts +0 -1
  70. package/scripts/config-generators/typescript-generator.ts +0 -36
  71. package/scripts/config-generators/vscode-generator.ts +40 -178
  72. package/scripts/generate-pr-checklist.ts +1 -6
  73. package/scripts/postinstall.ts +0 -38
  74. package/scripts/precommit-check.ts +113 -278
  75. package/scripts/utils/naming-validator.ts +2 -104
  76. package/scripts/utils/project-detector.ts +11 -78
  77. package/scripts/utils/report-generator.ts +5 -19
  78. package/scripts/utils/structure-validator.ts +0 -54
  79. package/config/fastify.config.ts +0 -326
  80. package/config/hono.config.ts +0 -331
  81. package/config/nestjs.config.ts +0 -500
  82. package/config/python.config.ts +0 -512
  83. package/templates/feature-doc-api.md +0 -101
  84. package/templates/feature-doc-backend.md +0 -114
  85. package/templates/feature-doc-service.md +0 -113
  86. package/templates/feature-doc-ui.md +0 -91
@@ -1,331 +0,0 @@
1
- /**
2
- * ============================================================================
3
- * hono.config.ts — Hono-specific coding rules
4
- * ============================================================================
5
- *
6
- * Registers rules that apply to Hono (edge + server) projects:
7
- * - Zod validation enforcement
8
- * - Context variable typing
9
- * - Middleware chaining patterns
10
- * - HTTPException usage
11
- * - Environment access patterns
12
- * - Stateless / edge-first patterns
13
- */
14
-
15
- import { registerRules, Rule } from './guidelines.config';
16
-
17
- const honoRules: Rule[] = [
18
-
19
- // ── Validation ────────────────────────────────────────────────────────────
20
-
21
- // ─────────────────────────────────────────
22
- // RULE: hono-use-zod-validator
23
- // ROLE: Enforce schema-based request validation
24
- // PURPOSE: Accessing c.req.json() or c.req.query() without validation
25
- // passes raw untyped data to your handlers. Using @hono/zod-validator
26
- // ensures type safety and returns a 400 automatically on bad input.
27
- // EXAMPLE:
28
- // WRONG:
29
- // app.post('/users', async (c) => {
30
- // const body = await c.req.json(); // untyped, unvalidated
31
- // });
32
- // RIGHT:
33
- // import { zValidator } from '@hono/zod-validator';
34
- // app.post('/users', zValidator('json', CreateUserSchema), async (c) => {
35
- // const body = c.req.valid('json'); // typed and validated
36
- // });
37
- // ─────────────────────────────────────────
38
- {
39
- id: 'hono-use-zod-validator',
40
- label: 'Use zValidator for request body validation',
41
- description:
42
- 'Use @hono/zod-validator middleware on routes that accept request bodies. Calling c.req.json() directly bypasses type safety and validation.',
43
- severity: 'error',
44
- fileExtensions: ['ts'],
45
- pattern: null,
46
- customCheck: (file) => {
47
- const violations: Array<{ line: number | null; message: string }> = [];
48
-
49
- if (
50
- !file.relativePath.includes('/routes/') &&
51
- !file.relativePath.endsWith('.route.ts') &&
52
- !file.relativePath.endsWith('.routes.ts')
53
- ) {
54
- return [];
55
- }
56
-
57
- // Detect routes that use c.req.json() without zValidator
58
- for (let i = 0; i < file.lines.length; i++) {
59
- const line = file.lines[i];
60
- if (/c\.req\.json\s*\(/.test(line)) {
61
- // Check surrounding context for zValidator
62
- const context = file.lines.slice(Math.max(0, i - 10), i).join('\n');
63
- if (!context.includes('zValidator') && !context.includes('z.object')) {
64
- violations.push({
65
- line: i + 1,
66
- message:
67
- 'c.req.json() used without zValidator middleware. Use zValidator("json", schema) before the handler and access via c.req.valid("json").',
68
- });
69
- }
70
- }
71
- }
72
-
73
- return violations;
74
- },
75
- applicableTo: ['hono'],
76
- category: 'Validation',
77
- },
78
-
79
- // ─────────────────────────────────────────
80
- // RULE: hono-use-valid-not-json
81
- // ROLE: Enforce validated data access after zValidator
82
- // PURPOSE: After applying zValidator middleware, handlers must use
83
- // c.req.valid() to access the validated, typed data.
84
- // c.req.json() bypasses validation and returns raw untyped data.
85
- // EXAMPLE:
86
- // WRONG:
87
- // app.post('/user', zValidator('json', schema), async (c) => {
88
- // const body = await c.req.json(); // still untyped!
89
- // });
90
- // RIGHT:
91
- // app.post('/user', zValidator('json', schema), async (c) => {
92
- // const body = c.req.valid('json'); // typed + validated
93
- // });
94
- // ─────────────────────────────────────────
95
- {
96
- id: 'hono-use-valid-not-json',
97
- label: 'After zValidator, use c.req.valid() not c.req.json()',
98
- description:
99
- 'When zValidator middleware is applied, access validated data via c.req.valid("json") instead of await c.req.json(). The latter bypasses type narrowing.',
100
- severity: 'warning',
101
- fileExtensions: ['ts'],
102
- pattern: null,
103
- customCheck: (file) => {
104
- const violations: Array<{ line: number | null; message: string }> = [];
105
-
106
- if (!file.content.includes('zValidator')) return [];
107
-
108
- for (let i = 0; i < file.lines.length; i++) {
109
- if (/await c\.req\.json\s*\(/.test(file.lines[i])) {
110
- violations.push({
111
- line: i + 1,
112
- message:
113
- 'zValidator is used in this file. Replace await c.req.json() with c.req.valid("json") to access the typed validated data.',
114
- });
115
- }
116
- }
117
-
118
- return violations;
119
- },
120
- applicableTo: ['hono'],
121
- category: 'Validation',
122
- },
123
-
124
- // ── Error Handling ────────────────────────────────────────────────────────
125
-
126
- // ─────────────────────────────────────────
127
- // RULE: hono-use-http-exception
128
- // ROLE: Enforce HTTPException for expected errors
129
- // PURPOSE: Throwing a raw Error in a Hono handler produces a generic 500
130
- // response with no meaningful body. HTTPException allows you to set
131
- // a specific status code and message that will be formatted by
132
- // Hono's onError handler consistently.
133
- // EXAMPLE:
134
- // WRONG:
135
- // throw new Error('User not found');
136
- // RIGHT:
137
- // throw new HTTPException(404, { message: 'User not found' });
138
- // ─────────────────────────────────────────
139
- {
140
- id: 'hono-use-http-exception',
141
- label: 'Use HTTPException instead of raw Error',
142
- description:
143
- 'Throw HTTPException from hono with a status code and message for expected errors (404, 401, 400, etc.). Raw Error objects produce unformatted 500 responses.',
144
- severity: 'warning',
145
- fileExtensions: ['ts'],
146
- pattern: null,
147
- customCheck: (file) => {
148
- const violations: Array<{ line: number | null; message: string }> = [];
149
-
150
- if (
151
- !file.relativePath.includes('/routes/') &&
152
- !file.relativePath.includes('/handlers/') &&
153
- !file.relativePath.endsWith('.route.ts') &&
154
- !file.relativePath.endsWith('.handler.ts')
155
- ) {
156
- return [];
157
- }
158
-
159
- for (let i = 0; i < file.lines.length; i++) {
160
- if (/throw\s+new\s+Error\s*\(/.test(file.lines[i])) {
161
- violations.push({
162
- line: i + 1,
163
- message:
164
- 'Raw Error thrown. Use HTTPException: throw new HTTPException(404, { message: "Not found" })',
165
- });
166
- }
167
- }
168
-
169
- return violations;
170
- },
171
- applicableTo: ['hono'],
172
- category: 'Error Handling',
173
- },
174
-
175
- // ── Context Variables ─────────────────────────────────────────────────────
176
-
177
- // ─────────────────────────────────────────
178
- // RULE: hono-type-context-variables
179
- // ROLE: Enforce typed context variables
180
- // PURPOSE: Using c.get() and c.set() without typed Variables means the
181
- // TypeScript compiler cannot verify keys exist, leading to
182
- // undefined value bugs at runtime.
183
- // EXAMPLE:
184
- // WRONG:
185
- // app.use(async (c, next) => {
186
- // c.set('user', user); // no type checking on 'user' key
187
- // });
188
- // RIGHT:
189
- // type Variables = { user: User };
190
- // const app = new Hono<{ Variables: Variables }>();
191
- // app.use(async (c, next) => { c.set('user', user); });
192
- // ─────────────────────────────────────────
193
- {
194
- id: 'hono-type-context-variables',
195
- label: 'Type context Variables for c.get() / c.set()',
196
- description:
197
- 'Declare a typed Variables interface and pass it as a generic to new Hono<{ Variables: Variables }>(). This enables TypeScript to validate context variable keys and values.',
198
- severity: 'warning',
199
- fileExtensions: ['ts'],
200
- pattern: null,
201
- customCheck: (file) => {
202
- const hasContextSet = /c\.set\s*\(/.test(file.content);
203
- const hasHonoGeneric = /new\s+Hono\s*</.test(file.content);
204
- const hasVariablesType = /Variables\s*=\s*\{/.test(file.content);
205
-
206
- if (hasContextSet && !hasHonoGeneric && !hasVariablesType) {
207
- return [
208
- {
209
- line: null,
210
- message:
211
- 'c.set() is used without typed Variables. Define: type Variables = { ... } and use new Hono<{ Variables: Variables }>().',
212
- },
213
- ];
214
- }
215
-
216
- return [];
217
- },
218
- applicableTo: ['hono'],
219
- category: 'Type Safety',
220
- },
221
-
222
- // ── Environment Access ────────────────────────────────────────────────────
223
-
224
- // ─────────────────────────────────────────
225
- // RULE: hono-use-c-env
226
- // ROLE: Enforce correct env access on edge runtimes
227
- // PURPOSE: On Cloudflare Workers and similar runtimes, process.env is
228
- // unavailable. Environment bindings are accessed via c.env.
229
- // Even on Node.js, centralising env access via c.env makes
230
- // the app portable across runtimes.
231
- // EXAMPLE:
232
- // WRONG:
233
- // const secret = process.env['JWT_SECRET'];
234
- // RIGHT:
235
- // // In Hono handler:
236
- // const secret = c.env.JWT_SECRET;
237
- // ─────────────────────────────────────────
238
- {
239
- id: 'hono-use-c-env',
240
- label: 'Use c.env for environment variables (edge-compatible)',
241
- description:
242
- 'Prefer c.env over process.env for environment variables. process.env is not available in Cloudflare Workers or Deno and makes apps runtime-specific.',
243
- severity: 'warning',
244
- fileExtensions: ['ts'],
245
- pattern: null,
246
- customCheck: (file) => {
247
- const violations: Array<{ line: number | null; message: string }> = [];
248
-
249
- if (
250
- !file.relativePath.includes('/routes/') &&
251
- !file.relativePath.includes('/handlers/') &&
252
- !file.relativePath.endsWith('.route.ts') &&
253
- !file.relativePath.endsWith('.handler.ts') &&
254
- !file.relativePath.endsWith('.middleware.ts')
255
- ) {
256
- return [];
257
- }
258
-
259
- for (let i = 0; i < file.lines.length; i++) {
260
- if (/process\.env\b/.test(file.lines[i])) {
261
- violations.push({
262
- line: i + 1,
263
- message:
264
- 'process.env used in Hono handler/route. Use c.env.VARIABLE_NAME for edge-runtime portability.',
265
- });
266
- }
267
- }
268
-
269
- return violations;
270
- },
271
- applicableTo: ['hono'],
272
- category: 'Security',
273
- },
274
-
275
- // ── Route Organisation ────────────────────────────────────────────────────
276
-
277
- // ─────────────────────────────────────────
278
- // RULE: hono-use-sub-apps
279
- // ROLE: Enforce composable route architecture
280
- // PURPOSE: Defining all routes on a single root Hono instance leads to a
281
- // monolithic file. Sub-apps (separate Hono instances per domain)
282
- // composed via app.route() enable feature isolation and per-domain
283
- // middleware application.
284
- // EXAMPLE:
285
- // WRONG:
286
- // app.get('/users', ...)
287
- // app.post('/users', ...)
288
- // app.get('/products', ...) // all in one file
289
- // RIGHT:
290
- // // users.route.ts
291
- // const users = new Hono();
292
- // users.get('/', ...)
293
- // export default users;
294
- // // app.ts
295
- // app.route('/users', users);
296
- // ─────────────────────────────────────────
297
- {
298
- id: 'hono-use-sub-apps',
299
- label: 'Organise routes as Hono sub-apps using app.route()',
300
- description:
301
- 'Define each domain\'s routes in a separate Hono sub-app and compose them via app.route("/prefix", subApp). Avoid putting all routes on a single root instance.',
302
- severity: 'info',
303
- fileExtensions: ['ts'],
304
- pattern: null,
305
- customCheck: (file) => {
306
- if (!file.relativePath.endsWith('index.ts') && !file.relativePath.endsWith('app.ts')) {
307
- return [];
308
- }
309
-
310
- const routeCount = (file.content.match(/app\.\s*(?:get|post|put|patch|delete)\s*\(/g) || []).length;
311
-
312
- if (routeCount > 5) {
313
- return [
314
- {
315
- line: null,
316
- message: `${routeCount} routes defined on a single Hono instance. Extract into domain sub-apps and use app.route('/prefix', subApp).`,
317
- },
318
- ];
319
- }
320
-
321
- return [];
322
- },
323
- applicableTo: ['hono'],
324
- category: 'Architecture',
325
- },
326
- ];
327
-
328
- // Register all Hono-specific rules
329
- registerRules('hono', honoRules);
330
-
331
- export { honoRules };