create-charcole 2.1.0 → 2.2.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 (79) hide show
  1. package/.github/workflows/release.yml +26 -26
  2. package/CHANGELOG.md +301 -211
  3. package/LICENSE +21 -21
  4. package/README.md +354 -213
  5. package/bin/index.js +444 -288
  6. package/bin/lib/pkgManager.js +49 -49
  7. package/bin/lib/templateHandler.js +33 -33
  8. package/create-charcole-2.1.0.tgz +0 -0
  9. package/package.json +42 -27
  10. package/packages/swagger/BACKWARD_COMPATIBILITY.md +145 -0
  11. package/packages/swagger/CHANGELOG.md +404 -0
  12. package/packages/swagger/README.md +578 -0
  13. package/packages/swagger/charcole-swagger-1.0.0.tgz +0 -0
  14. package/packages/swagger/package-lock.json +1715 -0
  15. package/packages/swagger/package.json +57 -0
  16. package/packages/swagger/src/helpers.js +427 -0
  17. package/packages/swagger/src/index.d.ts +126 -0
  18. package/packages/swagger/src/index.js +12 -0
  19. package/packages/swagger/src/setup.js +100 -0
  20. package/template/js/.env.example +15 -15
  21. package/template/js/README.md +978 -855
  22. package/template/js/basePackage.json +26 -26
  23. package/template/js/src/app.js +81 -78
  24. package/template/js/src/config/constants.js +20 -20
  25. package/template/js/src/config/env.js +26 -26
  26. package/template/js/src/config/swagger.config.js +15 -0
  27. package/template/js/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
  28. package/template/js/src/middlewares/errorHandler.js +180 -180
  29. package/template/js/src/middlewares/requestLogger.js +33 -33
  30. package/template/js/src/middlewares/validateRequest.js +42 -42
  31. package/template/js/src/modules/auth/auth.constants.js +3 -3
  32. package/template/js/src/modules/auth/auth.controller.js +29 -29
  33. package/template/js/src/modules/auth/auth.middlewares.js +19 -19
  34. package/template/js/src/modules/auth/auth.routes.js +131 -9
  35. package/template/js/src/modules/auth/auth.schemas.js +60 -60
  36. package/template/js/src/modules/auth/auth.service.js +67 -67
  37. package/template/js/src/modules/auth/package.json +6 -6
  38. package/template/js/src/modules/health/controller.js +151 -50
  39. package/template/js/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
  40. package/template/js/src/modules/swagger/package.json +5 -0
  41. package/template/js/src/repositories/user.repo.js +19 -19
  42. package/template/js/src/routes/index.js +25 -25
  43. package/template/js/src/routes/protected.js +57 -13
  44. package/template/js/src/server.js +38 -38
  45. package/template/js/src/utils/AppError.js +182 -182
  46. package/template/js/src/utils/logger.js +73 -73
  47. package/template/js/src/utils/response.js +51 -51
  48. package/template/ts/.env.example +15 -15
  49. package/template/ts/README.md +978 -855
  50. package/template/ts/basePackage.json +36 -36
  51. package/template/ts/build.js +46 -46
  52. package/template/ts/src/app.ts +71 -67
  53. package/template/ts/src/config/constants.ts +27 -27
  54. package/template/ts/src/config/env.ts +40 -40
  55. package/template/ts/src/config/swagger.config.ts +30 -0
  56. package/template/ts/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
  57. package/template/ts/src/middlewares/errorHandler.ts +201 -201
  58. package/template/ts/src/middlewares/requestLogger.ts +38 -38
  59. package/template/ts/src/middlewares/validateRequest.ts +46 -46
  60. package/template/ts/src/modules/auth/auth.constants.ts +6 -6
  61. package/template/ts/src/modules/auth/auth.controller.ts +32 -32
  62. package/template/ts/src/modules/auth/auth.middlewares.ts +46 -46
  63. package/template/ts/src/modules/auth/auth.routes.ts +52 -9
  64. package/template/ts/src/modules/auth/auth.schemas.ts +73 -73
  65. package/template/ts/src/modules/auth/auth.service.ts +106 -106
  66. package/template/ts/src/modules/auth/package.json +10 -10
  67. package/template/ts/src/modules/health/controller.ts +80 -64
  68. package/template/ts/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
  69. package/template/ts/src/modules/swagger/package.json +5 -0
  70. package/template/ts/src/repositories/user.repo.ts +33 -33
  71. package/template/ts/src/routes/index.ts +24 -24
  72. package/template/ts/src/routes/protected.ts +46 -13
  73. package/template/ts/src/server.ts +41 -41
  74. package/template/ts/src/types/express.d.ts +9 -9
  75. package/template/ts/src/utils/AppError.ts +220 -220
  76. package/template/ts/src/utils/logger.ts +55 -55
  77. package/template/ts/src/utils/response.ts +100 -100
  78. package/template/ts/tsconfig.json +26 -26
  79. package/plans/V2_1_PLAN.md +0 -20
@@ -0,0 +1,561 @@
1
+ # Swagger Documentation Guide
2
+
3
+ **@charcoles/swagger** - Effortless API documentation that eliminates duplication and dramatically reduces manual work.
4
+
5
+ ## 🎯 What's New
6
+
7
+ The new @charcoles/swagger **automatically generates API schemas from your Zod validations**, eliminating the need to write the same schema twice. You now write **60-80% less documentation** while keeping perfect synchronization between your validation logic and API docs.
8
+
9
+ ## 🚀 Quick Start
10
+
11
+ ### 1. Register Your Zod Schemas (One-Time Setup)
12
+
13
+ In `src/config/swagger.config.ts`, import and register your Zod schemas:
14
+
15
+ ```typescript
16
+ import { registerSchema, loginSchema } from "../modules/auth/auth.schemas.ts";
17
+ import { createItemSchema } from "../modules/health/controller.ts";
18
+
19
+ const swaggerConfig = {
20
+ title: "My API",
21
+ version: "1.0.0",
22
+ // Auto-register schemas - they'll be converted to OpenAPI automatically!
23
+ schemas: {
24
+ registerSchema,
25
+ loginSchema,
26
+ createItemSchema,
27
+ },
28
+ };
29
+
30
+ export default swaggerConfig;
31
+ ```
32
+
33
+ That's it! Your Zod schemas are now available as `$ref` in Swagger.
34
+
35
+ ### 2. Use Schema References in Your Routes
36
+
37
+ **Before (Old Way - 76 lines):**
38
+
39
+ ```typescript
40
+ /**
41
+ * @swagger
42
+ * /api/items:
43
+ * post:
44
+ * requestBody:
45
+ * content:
46
+ * application/json:
47
+ * schema:
48
+ * type: object
49
+ * required:
50
+ * - name
51
+ * properties:
52
+ * name:
53
+ * type: string
54
+ * minLength: 1
55
+ * maxLength: 100
56
+ * example: My Item
57
+ * description:
58
+ * type: string
59
+ * responses:
60
+ * 201:
61
+ * description: Item created successfully
62
+ * content:
63
+ * application/json:
64
+ * schema:
65
+ * type: object
66
+ * properties:
67
+ * success:
68
+ * type: boolean
69
+ * ... 50 more lines
70
+ */
71
+ ```
72
+
73
+ **After (New Way - 16 lines):**
74
+
75
+ ```typescript
76
+ /**
77
+ * @swagger
78
+ * /api/items:
79
+ * post:
80
+ * summary: Create a new item
81
+ * tags:
82
+ * - Items
83
+ * requestBody:
84
+ * required: true
85
+ * content:
86
+ * application/json:
87
+ * schema:
88
+ * $ref: '#/components/schemas/createItemSchema'
89
+ * responses:
90
+ * 201:
91
+ * $ref: '#/components/responses/Success'
92
+ * 400:
93
+ * $ref: '#/components/responses/ValidationError'
94
+ */
95
+ ```
96
+
97
+ **Result:** 60 lines eliminated! And your schema stays in sync automatically.
98
+
99
+ ---
100
+
101
+ ## 📚 Complete Examples
102
+
103
+ ### Example 1: Simple GET Endpoint
104
+
105
+ ```typescript
106
+ /**
107
+ * @swagger
108
+ * /api/health:
109
+ * get:
110
+ * summary: Health check endpoint
111
+ * tags:
112
+ * - Health
113
+ * responses:
114
+ * 200:
115
+ * $ref: '#/components/responses/Success'
116
+ */
117
+ export const getHealth = asyncHandler(async (req, res) => {
118
+ sendSuccess(res, { status: "healthy" }, 200, "Service is healthy");
119
+ });
120
+ ```
121
+
122
+ **Just 9 lines!** Common responses like `Success`, `ValidationError`, `Unauthorized` are included automatically.
123
+
124
+ ### Example 2: POST with Zod Validation
125
+
126
+ **Step 1:** Define your Zod schema (you're already doing this for validation):
127
+
128
+ ```typescript
129
+ // src/modules/items/items.schemas.ts
130
+ export const createItemSchema = z.object({
131
+ body: z.object({
132
+ name: z.string().min(1).max(100),
133
+ description: z.string().optional(),
134
+ price: z.number().positive(),
135
+ }),
136
+ });
137
+ ```
138
+
139
+ **Step 2:** Register it in `swagger.config.ts`:
140
+
141
+ ```typescript
142
+ import { createItemSchema } from "../modules/items/items.schemas.ts";
143
+
144
+ const swaggerConfig = {
145
+ // ...
146
+ schemas: {
147
+ createItemSchema, // Auto-converted to OpenAPI!
148
+ },
149
+ };
150
+ ```
151
+
152
+ **Step 3:** Reference it in your endpoint:
153
+
154
+ ```typescript
155
+ /**
156
+ * @swagger
157
+ * /api/items:
158
+ * post:
159
+ * summary: Create a new item
160
+ * tags:
161
+ * - Items
162
+ * requestBody:
163
+ * required: true
164
+ * content:
165
+ * application/json:
166
+ * schema:
167
+ * $ref: '#/components/schemas/createItemSchema'
168
+ * responses:
169
+ * 201:
170
+ * $ref: '#/components/responses/Success'
171
+ * 400:
172
+ * $ref: '#/components/responses/ValidationError'
173
+ */
174
+ router.post("/items", createItem);
175
+ ```
176
+
177
+ **No duplication!** Change your Zod schema once, and Swagger updates automatically.
178
+
179
+ ### Example 3: Protected Endpoint with Authentication
180
+
181
+ ```typescript
182
+ /**
183
+ * @swagger
184
+ * /api/profile:
185
+ * get:
186
+ * summary: Get user profile
187
+ * tags:
188
+ * - Profile
189
+ * security:
190
+ * - bearerAuth: []
191
+ * responses:
192
+ * 200:
193
+ * $ref: '#/components/responses/Success'
194
+ * 401:
195
+ * $ref: '#/components/responses/Unauthorized'
196
+ */
197
+ router.get("/profile", requireAuth, getProfile);
198
+ ```
199
+
200
+ ### Example 4: Path Parameters
201
+
202
+ ```typescript
203
+ /**
204
+ * @swagger
205
+ * /api/users/{id}:
206
+ * get:
207
+ * summary: Get user by ID
208
+ * tags:
209
+ * - Users
210
+ * parameters:
211
+ * - in: path
212
+ * name: id
213
+ * required: true
214
+ * schema:
215
+ * type: string
216
+ * description: User ID
217
+ * responses:
218
+ * 200:
219
+ * $ref: '#/components/responses/Success'
220
+ * 404:
221
+ * $ref: '#/components/responses/NotFound'
222
+ */
223
+ router.get("/:id", getUserById);
224
+ ```
225
+
226
+ ### Example 5: Query Parameters (Pagination, Filtering)
227
+
228
+ ```typescript
229
+ /**
230
+ * @swagger
231
+ * /api/products:
232
+ * get:
233
+ * summary: Search products
234
+ * tags:
235
+ * - Products
236
+ * parameters:
237
+ * - in: query
238
+ * name: category
239
+ * schema:
240
+ * type: string
241
+ * description: Filter by category
242
+ * - in: query
243
+ * name: page
244
+ * schema:
245
+ * type: integer
246
+ * default: 1
247
+ * - in: query
248
+ * name: limit
249
+ * schema:
250
+ * type: integer
251
+ * default: 10
252
+ * responses:
253
+ * 200:
254
+ * $ref: '#/components/responses/Success'
255
+ */
256
+ router.get("/products", getProducts);
257
+ ```
258
+
259
+ ---
260
+
261
+ ## 🎁 Built-in Response Templates
262
+
263
+ These responses are **automatically available** - no configuration needed:
264
+
265
+ | Response Name | Status | When to Use |
266
+ | ----------------- | ------- | --------------------------------- |
267
+ | `Success` | 200/201 | Successful operations |
268
+ | `ValidationError` | 400 | Request validation failures |
269
+ | `Unauthorized` | 401 | Missing or invalid authentication |
270
+ | `Forbidden` | 403 | Insufficient permissions |
271
+ | `NotFound` | 404 | Resource not found |
272
+ | `InternalError` | 500 | Server errors |
273
+
274
+ Use them with `$ref`:
275
+
276
+ ```yaml
277
+ responses:
278
+ 200:
279
+ $ref: "#/components/responses/Success"
280
+ 400:
281
+ $ref: "#/components/responses/ValidationError"
282
+ ```
283
+
284
+ ---
285
+
286
+ ## 🔧 Advanced Features
287
+
288
+ ### Custom Response Schemas
289
+
290
+ If you need custom responses beyond the built-in ones:
291
+
292
+ ```typescript
293
+ // In swagger.config.ts
294
+ const swaggerConfig = {
295
+ // ...
296
+ customResponses: {
297
+ UserCreated: {
298
+ description: "User created successfully",
299
+ content: {
300
+ "application/json": {
301
+ schema: {
302
+ type: "object",
303
+ properties: {
304
+ userId: { type: "string" },
305
+ token: { type: "string" },
306
+ },
307
+ },
308
+ },
309
+ },
310
+ },
311
+ },
312
+ };
313
+ ```
314
+
315
+ Then use it:
316
+
317
+ ```yaml
318
+ responses:
319
+ 201:
320
+ $ref: "#/components/responses/UserCreated"
321
+ ```
322
+
323
+ ### Helper Functions for Programmatic Documentation
324
+
325
+ For advanced use cases, you can use helper functions:
326
+
327
+ ```typescript
328
+ import { convertZodToOpenAPI, endpoint } from "@charcoles/swagger";
329
+
330
+ // Convert a single Zod schema to JSON Schema
331
+ const jsonSchema = convertZodToOpenAPI(myZodSchema, "MySchema");
332
+
333
+ // Create endpoint documentation programmatically
334
+ const apiDef = endpoint("POST", "/api/users", {
335
+ summary: "Create user",
336
+ schema: "createUserSchema",
337
+ responseSchema: "Success",
338
+ security: true,
339
+ });
340
+ ```
341
+
342
+ ---
343
+
344
+ ## 📖 Migration Guide
345
+
346
+ ### Migrating from Old JSDoc Approach
347
+
348
+ **Old (Manual Schema):**
349
+
350
+ ```typescript
351
+ /**
352
+ * @swagger
353
+ * /api/auth/register:
354
+ * post:
355
+ * requestBody:
356
+ * content:
357
+ * application/json:
358
+ * schema:
359
+ * type: object
360
+ * required:
361
+ * - email
362
+ * - password
363
+ * properties:
364
+ * email:
365
+ * type: string
366
+ * format: email
367
+ * password:
368
+ * type: string
369
+ * minLength: 8
370
+ */
371
+ ```
372
+
373
+ **New (Schema Reference):**
374
+
375
+ ```typescript
376
+ // 1. Register the schema in swagger.config.ts
377
+ schemas: {
378
+ registerSchema, // Already defined in auth.schemas.ts
379
+ }
380
+
381
+ // 2. Use reference in JSDoc
382
+ /**
383
+ * @swagger
384
+ * /api/auth/register:
385
+ * post:
386
+ * requestBody:
387
+ * content:
388
+ * application/json:
389
+ * schema:
390
+ * $ref: '#/components/schemas/registerSchema'
391
+ * responses:
392
+ * 201:
393
+ * $ref: '#/components/responses/Success'
394
+ * 400:
395
+ * $ref: '#/components/responses/ValidationError'
396
+ */
397
+ ```
398
+
399
+ ---
400
+
401
+ ## ✅ Best Practices
402
+
403
+ 1. **Always register schemas in swagger.config.ts**
404
+ - One central place for all schema registrations
405
+ - Easy to see what's documented
406
+
407
+ 2. **Use built-in response templates**
408
+ - Consistency across your API
409
+ - Less code to maintain
410
+
411
+ 3. **Keep Zod schemas colocated with modules**
412
+ - `modules/auth/auth.schemas.ts`
413
+ - `modules/users/users.schemas.ts`
414
+
415
+ 4. **Name schemas descriptively**
416
+ - ✅ `createUserSchema`, `updateUserSchema`
417
+ - ❌ `schema1`, `userSchema`
418
+
419
+ 5. **One schema definition = One source of truth**
420
+ - Define in Zod for validation
421
+ - Auto-generate for Swagger
422
+ - Never duplicate!
423
+
424
+ ---
425
+
426
+ ## 🆚 Comparison: Before vs After
427
+
428
+ | Aspect | Before | After | Improvement |
429
+ | ---------------------- | ----------------- | -------------- | ------------------ |
430
+ | **Lines per endpoint** | 45-76 lines | 10-20 lines | **60-75% less** |
431
+ | **Schema duplication** | Zod + Manual YAML | Zod only | **0% duplication** |
432
+ | **Maintenance** | Update 2 places | Update 1 place | **50% less work** |
433
+ | **Sync issues** | Common | Impossible | **Always in sync** |
434
+ | **Response templates** | Copy-paste | Built-in | **Reusable** |
435
+
436
+ ---
437
+
438
+ ## 🔍 Troubleshooting
439
+
440
+ ### Schema not appearing in Swagger UI?
441
+
442
+ 1. Check that the schema is imported in `swagger.config.ts`
443
+ 2. Restart your server (schemas are loaded at startup)
444
+ 3. Check browser console for errors
445
+
446
+ ### Zod schema not converting correctly?
447
+
448
+ - Ensure you're using `zod-to-json-schema` compatible Zod features
449
+ - Complex transforms may not convert perfectly
450
+ - Use simpler Zod primitives when possible
451
+
452
+ ### Want to see raw OpenAPI spec?
453
+
454
+ Visit `/api-docs.json` (if enabled) or check the console logs on startup.
455
+
456
+ ---
457
+
458
+ ## 📦 Using @charcoles/swagger in Non-Charcole Projects
459
+
460
+ Even if you didn't create your project with `create-charcole`, you can still use @charcoles/swagger!
461
+
462
+ ```bash
463
+ npm install @charcoles/swagger zod
464
+ ```
465
+
466
+ ```typescript
467
+ import express from "express";
468
+ import { setupSwagger } from "@charcoles/swagger";
469
+ import { mySchema } from "./schemas";
470
+
471
+ const app = express();
472
+
473
+ setupSwagger(app, {
474
+ title: "My API",
475
+ version: "1.0.0",
476
+ schemas: {
477
+ mySchema, // Your Zod schemas
478
+ },
479
+ });
480
+
481
+ app.listen(3000);
482
+ ```
483
+
484
+ Works with any Express.js project!
485
+
486
+ ---
487
+
488
+ ## 🎓 Quick Reference
489
+
490
+ ### Minimal Endpoint (GET)
491
+
492
+ ```typescript
493
+ /**
494
+ * @swagger
495
+ * /api/endpoint:
496
+ * get:
497
+ * summary: Short description
498
+ * tags: [Tag]
499
+ * responses:
500
+ * 200:
501
+ * $ref: '#/components/responses/Success'
502
+ */
503
+ ```
504
+
505
+ ### With Request Body (POST/PUT/PATCH)
506
+
507
+ ```typescript
508
+ /**
509
+ * @swagger
510
+ * /api/endpoint:
511
+ * post:
512
+ * summary: Short description
513
+ * tags: [Tag]
514
+ * requestBody:
515
+ * required: true
516
+ * content:
517
+ * application/json:
518
+ * schema:
519
+ * $ref: '#/components/schemas/schemaName'
520
+ * responses:
521
+ * 201:
522
+ * $ref: '#/components/responses/Success'
523
+ * 400:
524
+ * $ref: '#/components/responses/ValidationError'
525
+ */
526
+ ```
527
+
528
+ ### Protected Endpoint
529
+
530
+ ```typescript
531
+ /**
532
+ * @swagger
533
+ * /api/endpoint:
534
+ * get:
535
+ * security:
536
+ * - bearerAuth: []
537
+ * responses:
538
+ * 401:
539
+ * $ref: '#/components/responses/Unauthorized'
540
+ */
541
+ ```
542
+
543
+ ---
544
+
545
+ ## 💡 Need Help?
546
+
547
+ Check the examples in:
548
+
549
+ - `src/modules/health/controller.ts` - GET/POST examples
550
+ - `src/modules/auth/auth.routes.ts` - Authentication endpoints
551
+ - `src/config/swagger.config.ts` - Schema registration
552
+
553
+ **Test your documentation:**
554
+
555
+ 1. Start server: `npm start`
556
+ 2. Visit: `http://localhost:3000/api-docs`
557
+ 3. Try out endpoints directly in Swagger UI!
558
+
559
+ ---
560
+
561
+ **Remember:** With @charcoles/swagger, you define your schemas once in Zod, and documentation happens automatically. No more duplication, no more sync issues, dramatically less effort! 🎉