create-charcole 2.0.4 → 2.2.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/CHANGELOG.md +290 -14
- package/README.md +258 -312
- package/bin/index.js +392 -55
- package/bin/lib/pkgManager.js +8 -25
- package/bin/lib/templateHandler.js +5 -42
- package/create-charcole-2.1.0.tgz +0 -0
- package/package.json +2 -2
- package/packages/swagger/BACKWARD_COMPATIBILITY.md +145 -0
- package/packages/swagger/CHANGELOG.md +404 -0
- package/packages/swagger/README.md +578 -0
- package/packages/swagger/charcole-swagger-1.0.0.tgz +0 -0
- package/packages/swagger/package-lock.json +1715 -0
- package/packages/swagger/package.json +44 -0
- package/packages/swagger/src/helpers.js +427 -0
- package/packages/swagger/src/index.d.ts +126 -0
- package/packages/swagger/src/index.js +12 -0
- package/packages/swagger/src/setup.js +100 -0
- package/template/js/.env.example +8 -0
- package/template/js/README.md +128 -5
- package/template/js/basePackage.json +11 -13
- package/template/js/src/app.js +8 -2
- package/template/js/src/config/swagger.config.js +15 -0
- package/template/js/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
- package/template/js/src/modules/auth/auth.constants.js +3 -0
- package/template/js/src/modules/auth/auth.controller.js +29 -0
- package/template/js/src/modules/auth/auth.middlewares.js +19 -0
- package/template/js/src/modules/auth/auth.routes.js +131 -0
- package/template/js/src/modules/auth/auth.schemas.js +60 -0
- package/template/js/src/modules/auth/auth.service.js +67 -0
- package/template/js/src/modules/auth/package.json +6 -0
- package/template/js/src/modules/health/controller.js +104 -3
- package/template/js/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
- package/template/js/src/modules/swagger/package.json +5 -0
- package/template/js/src/repositories/user.repo.js +19 -0
- package/template/js/src/routes/index.js +25 -0
- package/template/js/src/routes/protected.js +57 -0
- package/template/ts/.env.example +8 -0
- package/template/ts/README.md +128 -5
- package/template/ts/basePackage.json +19 -15
- package/template/ts/build.js +46 -0
- package/template/ts/src/app.ts +12 -7
- package/template/ts/src/config/swagger.config.ts +30 -0
- package/template/ts/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
- package/template/ts/src/middlewares/errorHandler.ts +15 -23
- package/template/ts/src/middlewares/requestLogger.ts +1 -1
- package/template/ts/src/middlewares/validateRequest.ts +1 -1
- package/template/ts/src/modules/auth/auth.constants.ts +6 -0
- package/template/ts/src/modules/auth/auth.controller.ts +32 -0
- package/template/ts/src/modules/auth/auth.middlewares.ts +46 -0
- package/template/ts/src/modules/auth/auth.routes.ts +52 -0
- package/template/ts/src/modules/auth/auth.schemas.ts +73 -0
- package/template/ts/src/modules/auth/auth.service.ts +106 -0
- package/template/ts/src/modules/auth/package.json +10 -0
- package/template/ts/src/modules/health/controller.ts +61 -45
- package/template/ts/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
- package/template/ts/src/modules/swagger/package.json +5 -0
- package/template/ts/src/repositories/user.repo.ts +33 -0
- package/template/ts/src/routes/index.ts +24 -0
- package/template/ts/src/routes/protected.ts +46 -0
- package/template/ts/src/server.ts +3 -4
- package/template/ts/src/utils/logger.ts +1 -1
- package/template/ts/tsconfig.json +14 -7
- package/tmpclaude-1049-cwd +1 -0
- package/tmpclaude-3e37-cwd +1 -0
- package/tmpclaude-4d73-cwd +1 -0
- package/tmpclaude-8a8e-cwd +1 -0
- package/template/js/ARCHITECTURE_DIAGRAMS.md +0 -283
- package/template/js/CHECKLIST.md +0 -279
- package/template/js/COMPLETE.md +0 -405
- package/template/js/ERROR_HANDLING.md +0 -393
- package/template/js/IMPLEMENTATION.md +0 -368
- package/template/js/IMPLEMENTATION_COMPLETE.md +0 -363
- package/template/js/INDEX.md +0 -290
- package/template/js/QUICK_REFERENCE.md +0 -270
- package/template/js/package.json +0 -28
- package/template/js/src/routes.js +0 -17
- package/template/js/test-api.js +0 -100
- package/template/ts/ARCHITECTURE_DIAGRAMS.md +0 -283
- package/template/ts/CHECKLIST.md +0 -279
- package/template/ts/COMPLETE.md +0 -405
- package/template/ts/ERROR_HANDLING.md +0 -393
- package/template/ts/IMPLEMENTATION.md +0 -368
- package/template/ts/IMPLEMENTATION_COMPLETE.md +0 -363
- package/template/ts/INDEX.md +0 -290
- package/template/ts/QUICK_REFERENCE.md +0 -270
- package/template/ts/package.json +0 -32
- package/template/ts/src/app.js +0 -75
- package/template/ts/src/config/constants.js +0 -20
- package/template/ts/src/config/env.js +0 -26
- package/template/ts/src/middlewares/errorHandler.js +0 -180
- package/template/ts/src/middlewares/requestLogger.js +0 -33
- package/template/ts/src/middlewares/validateRequest.js +0 -42
- package/template/ts/src/modules/health/controller.js +0 -50
- package/template/ts/src/routes.js +0 -17
- package/template/ts/src/routes.ts +0 -16
- package/template/ts/src/server.js +0 -38
- package/template/ts/src/utils/AppError.js +0 -182
- package/template/ts/src/utils/logger.js +0 -73
- package/template/ts/src/utils/response.js +0 -51
- package/template/ts/test-api.js +0 -100
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
# @charcoles/swagger
|
|
2
|
+
|
|
3
|
+
Effortless API documentation for Express.js applications. Automatically generates OpenAPI 3.0 specs from your Zod validation schemas.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
✨ **Zero Schema Duplication** - Define schemas once in Zod, use everywhere
|
|
8
|
+
🚀 **60-80% Less Code** - Minimal documentation overhead
|
|
9
|
+
🔄 **Always In Sync** - Impossible to have outdated docs
|
|
10
|
+
📦 **Built-in Templates** - Common response schemas included
|
|
11
|
+
🎯 **Framework Agnostic** - Works with any Express.js project
|
|
12
|
+
💪 **TypeScript First** - Full type safety with optional JavaScript support
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @charcoles/swagger zod
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### 1. Setup Swagger in your Express app
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import express from "express";
|
|
26
|
+
import { setupSwagger } from "@charcoles/swagger";
|
|
27
|
+
import { createUserSchema, loginSchema } from "./schemas";
|
|
28
|
+
|
|
29
|
+
const app = express();
|
|
30
|
+
|
|
31
|
+
setupSwagger(app, {
|
|
32
|
+
title: "My API",
|
|
33
|
+
version: "1.0.0",
|
|
34
|
+
schemas: {
|
|
35
|
+
createUserSchema, // Auto-converted from Zod!
|
|
36
|
+
loginSchema,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
app.listen(3000);
|
|
41
|
+
// Swagger UI now available at http://localhost:3000/api-docs
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Document your endpoints
|
|
45
|
+
|
|
46
|
+
**Traditional Way (Manual Schema - 76 lines):**
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
/**
|
|
50
|
+
* @swagger
|
|
51
|
+
* /api/users:
|
|
52
|
+
* post:
|
|
53
|
+
* requestBody:
|
|
54
|
+
* content:
|
|
55
|
+
* application/json:
|
|
56
|
+
* schema:
|
|
57
|
+
* type: object
|
|
58
|
+
* required:
|
|
59
|
+
* - name
|
|
60
|
+
* - email
|
|
61
|
+
* properties:
|
|
62
|
+
* name:
|
|
63
|
+
* type: string
|
|
64
|
+
* minLength: 1
|
|
65
|
+
* maxLength: 100
|
|
66
|
+
* email:
|
|
67
|
+
* type: string
|
|
68
|
+
* format: email
|
|
69
|
+
* ... 50+ more lines
|
|
70
|
+
*/
|
|
71
|
+
router.post("/users", createUser);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**With @charcoles/swagger (16 lines):**
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
/**
|
|
78
|
+
* @swagger
|
|
79
|
+
* /api/users:
|
|
80
|
+
* post:
|
|
81
|
+
* summary: Create a new user
|
|
82
|
+
* tags:
|
|
83
|
+
* - Users
|
|
84
|
+
* requestBody:
|
|
85
|
+
* required: true
|
|
86
|
+
* content:
|
|
87
|
+
* application/json:
|
|
88
|
+
* schema:
|
|
89
|
+
* $ref: '#/components/schemas/createUserSchema'
|
|
90
|
+
* responses:
|
|
91
|
+
* 201:
|
|
92
|
+
* $ref: '#/components/responses/Success'
|
|
93
|
+
* 400:
|
|
94
|
+
* $ref: '#/components/responses/ValidationError'
|
|
95
|
+
*/
|
|
96
|
+
router.post("/users", createUser);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## API Reference
|
|
100
|
+
|
|
101
|
+
### `setupSwagger(app, options)`
|
|
102
|
+
|
|
103
|
+
Sets up Swagger UI and documentation generation.
|
|
104
|
+
|
|
105
|
+
#### Options
|
|
106
|
+
|
|
107
|
+
| Option | Type | Default | Description |
|
|
108
|
+
| ------------------------ | ------- | ---------------------------------- | ----------------------------------- |
|
|
109
|
+
| `title` | string | "Charcole API" | API title |
|
|
110
|
+
| `version` | string | "1.0.0" | API version |
|
|
111
|
+
| `description` | string | "Auto-generated API documentation" | API description |
|
|
112
|
+
| `path` | string | "/api-docs" | Swagger UI path |
|
|
113
|
+
| `servers` | array | `[{url: "http://localhost:3000"}]` | Server URLs |
|
|
114
|
+
| `schemas` | object | `{}` | Zod schemas to auto-register |
|
|
115
|
+
| `includeCommonResponses` | boolean | `true` | Include built-in response templates |
|
|
116
|
+
| `customResponses` | object | `{}` | Additional custom response schemas |
|
|
117
|
+
|
|
118
|
+
#### Example
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
setupSwagger(app, {
|
|
122
|
+
title: "My E-commerce API",
|
|
123
|
+
version: "2.0.0",
|
|
124
|
+
description: "Production-ready REST API for e-commerce",
|
|
125
|
+
path: "/docs",
|
|
126
|
+
servers: [
|
|
127
|
+
{ url: "https://api.example.com", description: "Production" },
|
|
128
|
+
{ url: "http://localhost:3000", description: "Development" },
|
|
129
|
+
],
|
|
130
|
+
schemas: {
|
|
131
|
+
createProductSchema,
|
|
132
|
+
updateProductSchema,
|
|
133
|
+
orderSchema,
|
|
134
|
+
},
|
|
135
|
+
customResponses: {
|
|
136
|
+
ProductCreated: {
|
|
137
|
+
description: "Product created successfully",
|
|
138
|
+
content: {
|
|
139
|
+
"application/json": {
|
|
140
|
+
schema: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
productId: { type: "string" },
|
|
144
|
+
name: { type: "string" },
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Built-in Response Templates
|
|
155
|
+
|
|
156
|
+
The following responses are automatically available:
|
|
157
|
+
|
|
158
|
+
- `Success` (200/201) - Standard success response
|
|
159
|
+
- `ValidationError` (400) - Request validation failures
|
|
160
|
+
- `Unauthorized` (401) - Authentication failures
|
|
161
|
+
- `Forbidden` (403) - Permission denied
|
|
162
|
+
- `NotFound` (404) - Resource not found
|
|
163
|
+
- `InternalError` (500) - Server errors
|
|
164
|
+
|
|
165
|
+
Use them with `$ref`:
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
responses:
|
|
169
|
+
200:
|
|
170
|
+
$ref: "#/components/responses/Success"
|
|
171
|
+
400:
|
|
172
|
+
$ref: "#/components/responses/ValidationError"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Helper Functions
|
|
176
|
+
|
|
177
|
+
#### `convertZodToOpenAPI(zodSchema, name)`
|
|
178
|
+
|
|
179
|
+
Converts a Zod schema to OpenAPI 3.0 JSON Schema.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { convertZodToOpenAPI } from "@charcoles/swagger";
|
|
183
|
+
import { z } from "zod";
|
|
184
|
+
|
|
185
|
+
const userSchema = z.object({
|
|
186
|
+
name: z.string(),
|
|
187
|
+
email: z.string().email(),
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const openApiSchema = convertZodToOpenAPI(userSchema, "User");
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### `registerSchemas(schemas)`
|
|
194
|
+
|
|
195
|
+
Registers multiple Zod schemas at once.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { registerSchemas } from "@charcoles/swagger";
|
|
199
|
+
|
|
200
|
+
const components = registerSchemas({
|
|
201
|
+
createUserSchema,
|
|
202
|
+
updateUserSchema,
|
|
203
|
+
loginSchema,
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### `getCommonResponses()`
|
|
208
|
+
|
|
209
|
+
Returns all built-in response templates.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { getCommonResponses } from "@charcoles/swagger";
|
|
213
|
+
|
|
214
|
+
const responses = getCommonResponses();
|
|
215
|
+
// { Success: {...}, ValidationError: {...}, Unauthorized: {...}, ... }
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Integration with Zod
|
|
219
|
+
|
|
220
|
+
@charcoles/swagger seamlessly integrates with your Zod validation schemas:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Define schema once
|
|
224
|
+
export const createUserSchema = z.object({
|
|
225
|
+
body: z.object({
|
|
226
|
+
name: z.string().min(1, "Name is required").max(100),
|
|
227
|
+
email: z.string().email("Invalid email"),
|
|
228
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
229
|
+
}),
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// Register in swagger config
|
|
233
|
+
setupSwagger(app, {
|
|
234
|
+
schemas: { createUserSchema },
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Use in controller with validation
|
|
238
|
+
const createUser = async (req, res) => {
|
|
239
|
+
const { body } = createUserSchema.parse({ body: req.body });
|
|
240
|
+
// Your logic here
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Reference in documentation
|
|
244
|
+
/**
|
|
245
|
+
* @swagger
|
|
246
|
+
* /api/users:
|
|
247
|
+
* post:
|
|
248
|
+
* requestBody:
|
|
249
|
+
* content:
|
|
250
|
+
* application/json:
|
|
251
|
+
* schema:
|
|
252
|
+
* $ref: '#/components/schemas/createUserSchema'
|
|
253
|
+
*/
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Single source of truth!** Change your Zod schema, and both validation and documentation update automatically.
|
|
257
|
+
|
|
258
|
+
## TypeScript Support
|
|
259
|
+
|
|
260
|
+
Full TypeScript support with type definitions included:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
import { setupSwagger, SwaggerOptions, OpenAPISpec } from "@charcoles/swagger";
|
|
264
|
+
import type { Application } from "express";
|
|
265
|
+
|
|
266
|
+
const app: Application = express();
|
|
267
|
+
|
|
268
|
+
const options: SwaggerOptions = {
|
|
269
|
+
title: "My API",
|
|
270
|
+
version: "1.0.0",
|
|
271
|
+
schemas: {
|
|
272
|
+
mySchema,
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const spec: OpenAPISpec = setupSwagger(app, options);
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## JavaScript Support
|
|
280
|
+
|
|
281
|
+
Works perfectly with JavaScript projects too:
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
const express = require("express");
|
|
285
|
+
const { setupSwagger } = require("@charcoles/swagger");
|
|
286
|
+
const { z } = require("zod");
|
|
287
|
+
|
|
288
|
+
const app = express();
|
|
289
|
+
|
|
290
|
+
const userSchema = z.object({
|
|
291
|
+
name: z.string(),
|
|
292
|
+
email: z.string().email(),
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
setupSwagger(app, {
|
|
296
|
+
title: "My JavaScript API",
|
|
297
|
+
schemas: { userSchema },
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Examples
|
|
302
|
+
|
|
303
|
+
### Complete CRUD API
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import { z } from "zod";
|
|
307
|
+
import { setupSwagger } from "@charcoles/swagger";
|
|
308
|
+
|
|
309
|
+
// Define schemas
|
|
310
|
+
const createPostSchema = z.object({
|
|
311
|
+
body: z.object({
|
|
312
|
+
title: z.string().min(1).max(200),
|
|
313
|
+
content: z.string().min(1),
|
|
314
|
+
published: z.boolean().default(false),
|
|
315
|
+
}),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const updatePostSchema = z.object({
|
|
319
|
+
body: z.object({
|
|
320
|
+
title: z.string().min(1).max(200).optional(),
|
|
321
|
+
content: z.string().min(1).optional(),
|
|
322
|
+
published: z.boolean().optional(),
|
|
323
|
+
}),
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Setup Swagger
|
|
327
|
+
setupSwagger(app, {
|
|
328
|
+
title: "Blog API",
|
|
329
|
+
schemas: {
|
|
330
|
+
createPostSchema,
|
|
331
|
+
updatePostSchema,
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// Document routes
|
|
336
|
+
/**
|
|
337
|
+
* @swagger
|
|
338
|
+
* /api/posts:
|
|
339
|
+
* get:
|
|
340
|
+
* summary: Get all posts
|
|
341
|
+
* tags: [Posts]
|
|
342
|
+
* responses:
|
|
343
|
+
* 200:
|
|
344
|
+
* $ref: '#/components/responses/Success'
|
|
345
|
+
*
|
|
346
|
+
* post:
|
|
347
|
+
* summary: Create a new post
|
|
348
|
+
* tags: [Posts]
|
|
349
|
+
* security:
|
|
350
|
+
* - bearerAuth: []
|
|
351
|
+
* requestBody:
|
|
352
|
+
* required: true
|
|
353
|
+
* content:
|
|
354
|
+
* application/json:
|
|
355
|
+
* schema:
|
|
356
|
+
* $ref: '#/components/schemas/createPostSchema'
|
|
357
|
+
* responses:
|
|
358
|
+
* 201:
|
|
359
|
+
* $ref: '#/components/responses/Success'
|
|
360
|
+
* 400:
|
|
361
|
+
* $ref: '#/components/responses/ValidationError'
|
|
362
|
+
* 401:
|
|
363
|
+
* $ref: '#/components/responses/Unauthorized'
|
|
364
|
+
*
|
|
365
|
+
* /api/posts/{id}:
|
|
366
|
+
* get:
|
|
367
|
+
* summary: Get post by ID
|
|
368
|
+
* tags: [Posts]
|
|
369
|
+
* parameters:
|
|
370
|
+
* - in: path
|
|
371
|
+
* name: id
|
|
372
|
+
* required: true
|
|
373
|
+
* schema:
|
|
374
|
+
* type: string
|
|
375
|
+
* responses:
|
|
376
|
+
* 200:
|
|
377
|
+
* $ref: '#/components/responses/Success'
|
|
378
|
+
* 404:
|
|
379
|
+
* $ref: '#/components/responses/NotFound'
|
|
380
|
+
*
|
|
381
|
+
* put:
|
|
382
|
+
* summary: Update post
|
|
383
|
+
* tags: [Posts]
|
|
384
|
+
* security:
|
|
385
|
+
* - bearerAuth: []
|
|
386
|
+
* parameters:
|
|
387
|
+
* - in: path
|
|
388
|
+
* name: id
|
|
389
|
+
* required: true
|
|
390
|
+
* schema:
|
|
391
|
+
* type: string
|
|
392
|
+
* requestBody:
|
|
393
|
+
* required: true
|
|
394
|
+
* content:
|
|
395
|
+
* application/json:
|
|
396
|
+
* schema:
|
|
397
|
+
* $ref: '#/components/schemas/updatePostSchema'
|
|
398
|
+
* responses:
|
|
399
|
+
* 200:
|
|
400
|
+
* $ref: '#/components/responses/Success'
|
|
401
|
+
* 400:
|
|
402
|
+
* $ref: '#/components/responses/ValidationError'
|
|
403
|
+
* 401:
|
|
404
|
+
* $ref: '#/components/responses/Unauthorized'
|
|
405
|
+
* 404:
|
|
406
|
+
* $ref: '#/components/responses/NotFound'
|
|
407
|
+
*
|
|
408
|
+
* delete:
|
|
409
|
+
* summary: Delete post
|
|
410
|
+
* tags: [Posts]
|
|
411
|
+
* security:
|
|
412
|
+
* - bearerAuth: []
|
|
413
|
+
* parameters:
|
|
414
|
+
* - in: path
|
|
415
|
+
* name: id
|
|
416
|
+
* required: true
|
|
417
|
+
* schema:
|
|
418
|
+
* type: string
|
|
419
|
+
* responses:
|
|
420
|
+
* 204:
|
|
421
|
+
* description: Post deleted successfully
|
|
422
|
+
* 401:
|
|
423
|
+
* $ref: '#/components/responses/Unauthorized'
|
|
424
|
+
* 404:
|
|
425
|
+
* $ref: '#/components/responses/NotFound'
|
|
426
|
+
*/
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## Benefits
|
|
430
|
+
|
|
431
|
+
### Before @charcoles/swagger
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// Zod schema (for validation)
|
|
435
|
+
const createUserSchema = z.object({
|
|
436
|
+
body: z.object({
|
|
437
|
+
name: z.string().min(1).max(100),
|
|
438
|
+
email: z.string().email(),
|
|
439
|
+
}),
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// Swagger docs (manual duplication - 45 lines)
|
|
443
|
+
/**
|
|
444
|
+
* @swagger
|
|
445
|
+
* /api/users:
|
|
446
|
+
* post:
|
|
447
|
+
* requestBody:
|
|
448
|
+
* content:
|
|
449
|
+
* application/json:
|
|
450
|
+
* schema:
|
|
451
|
+
* type: object
|
|
452
|
+
* required: [name, email]
|
|
453
|
+
* properties:
|
|
454
|
+
* name:
|
|
455
|
+
* type: string
|
|
456
|
+
* minLength: 1
|
|
457
|
+
* maxLength: 100
|
|
458
|
+
* email:
|
|
459
|
+
* type: string
|
|
460
|
+
* format: email
|
|
461
|
+
* responses:
|
|
462
|
+
* 201:
|
|
463
|
+
* description: User created
|
|
464
|
+
* content:
|
|
465
|
+
* application/json:
|
|
466
|
+
* schema:
|
|
467
|
+
* type: object
|
|
468
|
+
* properties:
|
|
469
|
+
* success:
|
|
470
|
+
* type: boolean
|
|
471
|
+
* ... 20+ more lines
|
|
472
|
+
*/
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
**Problems:**
|
|
476
|
+
|
|
477
|
+
- ❌ Schema defined twice
|
|
478
|
+
- ❌ 45+ lines of docs per endpoint
|
|
479
|
+
- ❌ Easy to get out of sync
|
|
480
|
+
- ❌ Copy-paste errors
|
|
481
|
+
- ❌ High maintenance burden
|
|
482
|
+
|
|
483
|
+
### After @charcoles/swagger
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
// Zod schema (single source of truth)
|
|
487
|
+
const createUserSchema = z.object({
|
|
488
|
+
body: z.object({
|
|
489
|
+
name: z.string().min(1).max(100),
|
|
490
|
+
email: z.string().email(),
|
|
491
|
+
}),
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// Register once
|
|
495
|
+
setupSwagger(app, {
|
|
496
|
+
schemas: { createUserSchema },
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// Reference in docs (15 lines)
|
|
500
|
+
/**
|
|
501
|
+
* @swagger
|
|
502
|
+
* /api/users:
|
|
503
|
+
* post:
|
|
504
|
+
* summary: Create user
|
|
505
|
+
* tags: [Users]
|
|
506
|
+
* requestBody:
|
|
507
|
+
* content:
|
|
508
|
+
* application/json:
|
|
509
|
+
* schema:
|
|
510
|
+
* $ref: '#/components/schemas/createUserSchema'
|
|
511
|
+
* responses:
|
|
512
|
+
* 201:
|
|
513
|
+
* $ref: '#/components/responses/Success'
|
|
514
|
+
* 400:
|
|
515
|
+
* $ref: '#/components/responses/ValidationError'
|
|
516
|
+
*/
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Benefits:**
|
|
520
|
+
|
|
521
|
+
- ✅ Schema defined once
|
|
522
|
+
- ✅ 15 lines of docs (70% reduction)
|
|
523
|
+
- ✅ Always in sync (impossible to drift)
|
|
524
|
+
- ✅ No duplication
|
|
525
|
+
- ✅ Easy to maintain
|
|
526
|
+
|
|
527
|
+
## Comparison
|
|
528
|
+
|
|
529
|
+
| Feature | @charcoles/swagger | swagger-jsdoc | tsoa | NestJS |
|
|
530
|
+
| ----------------------- | ------------------ | ------------- | ------ | ------ |
|
|
531
|
+
| **Zero duplication** | ✅ | ❌ | ✅ | ✅ |
|
|
532
|
+
| **Framework agnostic** | ✅ | ✅ | ❌ | ❌ |
|
|
533
|
+
| **JavaScript support** | ✅ | ✅ | ❌ | ❌ |
|
|
534
|
+
| **Auto Zod conversion** | ✅ | ❌ | ❌ | ⚠️ |
|
|
535
|
+
| **No build step** | ✅ | ✅ | ❌ | ✅ |
|
|
536
|
+
| **Lines of code** | Very Low | High | Low | Medium |
|
|
537
|
+
| **Learning curve** | Easy | Easy | Medium | High |
|
|
538
|
+
|
|
539
|
+
## Troubleshooting
|
|
540
|
+
|
|
541
|
+
### Schema not appearing in Swagger UI?
|
|
542
|
+
|
|
543
|
+
1. Verify the schema is imported in your config
|
|
544
|
+
2. Restart your server
|
|
545
|
+
3. Check console for errors during startup
|
|
546
|
+
|
|
547
|
+
### Zod schema not converting correctly?
|
|
548
|
+
|
|
549
|
+
- Use standard Zod primitives when possible
|
|
550
|
+
- Avoid complex `.transform()` or `.refine()` for documented schemas
|
|
551
|
+
- Check that `zod-to-json-schema` supports your Zod features
|
|
552
|
+
|
|
553
|
+
### Want more control?
|
|
554
|
+
|
|
555
|
+
Use the helper functions for custom conversions:
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
import { convertZodToOpenAPI } from "@charcoles/swagger";
|
|
559
|
+
|
|
560
|
+
const customSchema = convertZodToOpenAPI(myZodSchema, "MySchema");
|
|
561
|
+
// Modify customSchema as needed
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
## License
|
|
565
|
+
|
|
566
|
+
ISC
|
|
567
|
+
|
|
568
|
+
## Author
|
|
569
|
+
|
|
570
|
+
Sheraz Manzoor
|
|
571
|
+
|
|
572
|
+
## Contributing
|
|
573
|
+
|
|
574
|
+
Issues and PRs welcome at [https://github.com/your-repo/charcole](https://github.com/your-repo/charcole)
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
**@charcoles/swagger** - Because life's too short to write schemas twice. 🎉
|
|
Binary file
|