create-charcole 2.2.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.
- package/.github/workflows/release.yml +26 -26
- package/CHANGELOG.md +301 -301
- package/LICENSE +21 -21
- package/README.md +354 -354
- package/bin/index.js +444 -444
- package/bin/lib/pkgManager.js +49 -49
- package/bin/lib/templateHandler.js +33 -33
- package/package.json +42 -27
- package/packages/swagger/package-lock.json +1715 -1715
- package/packages/swagger/package.json +57 -44
- package/packages/swagger/src/index.d.ts +126 -126
- package/packages/swagger/src/index.js +12 -12
- package/packages/swagger/src/setup.js +100 -100
- package/template/js/.env.example +15 -15
- package/template/js/README.md +978 -978
- package/template/js/basePackage.json +26 -26
- package/template/js/src/app.js +81 -81
- package/template/js/src/config/constants.js +20 -20
- package/template/js/src/config/env.js +26 -26
- package/template/js/src/config/swagger.config.js +15 -15
- package/template/js/src/middlewares/errorHandler.js +180 -180
- package/template/js/src/middlewares/requestLogger.js +33 -33
- package/template/js/src/middlewares/validateRequest.js +42 -42
- package/template/js/src/modules/auth/auth.constants.js +3 -3
- package/template/js/src/modules/auth/auth.controller.js +29 -29
- package/template/js/src/modules/auth/auth.middlewares.js +19 -19
- package/template/js/src/modules/auth/auth.routes.js +131 -131
- package/template/js/src/modules/auth/auth.schemas.js +60 -60
- package/template/js/src/modules/auth/auth.service.js +67 -67
- package/template/js/src/modules/auth/package.json +6 -6
- package/template/js/src/modules/health/controller.js +151 -151
- package/template/js/src/modules/swagger/package.json +5 -5
- package/template/js/src/repositories/user.repo.js +19 -19
- package/template/js/src/routes/index.js +25 -25
- package/template/js/src/routes/protected.js +57 -57
- package/template/js/src/server.js +38 -38
- package/template/js/src/utils/AppError.js +182 -182
- package/template/js/src/utils/logger.js +73 -73
- package/template/js/src/utils/response.js +51 -51
- package/template/ts/.env.example +15 -15
- package/template/ts/README.md +978 -978
- package/template/ts/basePackage.json +36 -36
- package/template/ts/build.js +46 -46
- package/template/ts/src/app.ts +71 -71
- package/template/ts/src/config/constants.ts +27 -27
- package/template/ts/src/config/env.ts +40 -40
- package/template/ts/src/config/swagger.config.ts +30 -30
- package/template/ts/src/middlewares/errorHandler.ts +201 -201
- package/template/ts/src/middlewares/requestLogger.ts +38 -38
- package/template/ts/src/middlewares/validateRequest.ts +46 -46
- package/template/ts/src/modules/auth/auth.constants.ts +6 -6
- package/template/ts/src/modules/auth/auth.controller.ts +32 -32
- package/template/ts/src/modules/auth/auth.middlewares.ts +46 -46
- package/template/ts/src/modules/auth/auth.routes.ts +52 -52
- package/template/ts/src/modules/auth/auth.schemas.ts +73 -73
- package/template/ts/src/modules/auth/auth.service.ts +106 -106
- package/template/ts/src/modules/auth/package.json +10 -10
- package/template/ts/src/modules/health/controller.ts +80 -80
- package/template/ts/src/modules/swagger/package.json +5 -5
- package/template/ts/src/repositories/user.repo.ts +33 -33
- package/template/ts/src/routes/index.ts +24 -24
- package/template/ts/src/routes/protected.ts +46 -46
- package/template/ts/src/server.ts +41 -41
- package/template/ts/src/types/express.d.ts +9 -9
- package/template/ts/src/utils/AppError.ts +220 -220
- package/template/ts/src/utils/logger.ts +55 -55
- package/template/ts/src/utils/response.ts +100 -100
- package/template/ts/tsconfig.json +26 -26
- package/tmpclaude-1049-cwd +0 -1
- package/tmpclaude-3e37-cwd +0 -1
- package/tmpclaude-4d73-cwd +0 -1
- package/tmpclaude-8a8e-cwd +0 -1
package/README.md
CHANGED
|
@@ -1,354 +1,354 @@
|
|
|
1
|
-
# Charcole API v2.2
|
|
2
|
-
|
|
3
|
-
> **Charcole v2.2 is a production-grade Node.js backend starter CLI that scaffolds enterprise-ready Express APIs with first-class TypeScript or JavaScript support, centralized error handling, Zod validation, structured logging, optional JWT authentication, **auto-generated Swagger documentation**, and a revolutionary repository pattern for database abstraction.**
|
|
4
|
-
|
|
5
|
-
[](https://nodejs.org/)
|
|
6
|
-
[](https://expressjs.com/)
|
|
7
|
-
[](https://zod.dev/)
|
|
8
|
-
[](https://www.typescriptlang.org/)
|
|
9
|
-
[](LICENSE)
|
|
10
|
-
|
|
11
|
-
## What's New in v2.2
|
|
12
|
-
|
|
13
|
-
### 🎯 Auto-Generated Swagger Documentation (@charcoles/swagger)
|
|
14
|
-
|
|
15
|
-
The game-changing feature that eliminates 60-80% of API documentation overhead:
|
|
16
|
-
|
|
17
|
-
- **Zero schema duplication** - Define Zod schemas once, auto-generate OpenAPI specs
|
|
18
|
-
- **Effortless documentation** - Minimal JSDoc comments with `$ref` to Zod schemas
|
|
19
|
-
- **Built-in response templates** - Common responses (Success, ValidationError, Unauthorized, NotFound) included
|
|
20
|
-
- **Always in sync** - Impossible for docs to drift from validation schemas
|
|
21
|
-
- **Optional module** - Include/exclude during project creation
|
|
22
|
-
- **Framework agnostic** - Works with any Express.js project via `npm install @charcoles/swagger`
|
|
23
|
-
|
|
24
|
-
**Before (76 lines of manual duplication):**
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
// Zod schema for validation
|
|
28
|
-
const registerSchema = z.object({
|
|
29
|
-
email: z.string().email(),
|
|
30
|
-
password: z.string().min(8),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Manual OpenAPI schema (duplicate!)
|
|
34
|
-
/**
|
|
35
|
-
* @swagger
|
|
36
|
-
* /api/auth/register:
|
|
37
|
-
* post:
|
|
38
|
-
* requestBody:
|
|
39
|
-
* schema:
|
|
40
|
-
* type: object
|
|
41
|
-
* properties:
|
|
42
|
-
* email:
|
|
43
|
-
* type: string
|
|
44
|
-
* format: email
|
|
45
|
-
* password:
|
|
46
|
-
* type: string
|
|
47
|
-
* minLength: 8
|
|
48
|
-
* ... 60 more lines
|
|
49
|
-
*/
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
**After with @charcoles/swagger (20 lines, zero duplication):**
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
// 1. Register schema once in swagger.config.ts
|
|
56
|
-
setupSwagger(app, {
|
|
57
|
-
schemas: { registerSchema }, // Auto-converted!
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// 2. Reference in JSDoc
|
|
61
|
-
/**
|
|
62
|
-
* @swagger
|
|
63
|
-
* /api/auth/register:
|
|
64
|
-
* post:
|
|
65
|
-
* summary: Register user
|
|
66
|
-
* requestBody:
|
|
67
|
-
* content:
|
|
68
|
-
* application/json:
|
|
69
|
-
* schema:
|
|
70
|
-
* $ref: '#/components/schemas/registerSchema'
|
|
71
|
-
* responses:
|
|
72
|
-
* 201:
|
|
73
|
-
* $ref: '#/components/responses/Success'
|
|
74
|
-
* 400:
|
|
75
|
-
* $ref: '#/components/responses/ValidationError'
|
|
76
|
-
*/
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**Result:** Change your Zod schema → Swagger updates automatically! 🎉
|
|
80
|
-
|
|
81
|
-
### Previous Features (v2.1)
|
|
82
|
-
|
|
83
|
-
#### Revolutionary Repository Pattern
|
|
84
|
-
|
|
85
|
-
- **Database abstraction layer** - Switch databases without changing business logic
|
|
86
|
-
- **In-memory repository included** - Test APIs instantly without database setup
|
|
87
|
-
- **Clean separation** - Business logic stays independent of database implementation
|
|
88
|
-
- **Future-proof** - Easy migration between MongoDB, PostgreSQL, MySQL, etc.
|
|
89
|
-
|
|
90
|
-
#### Optional JWT Authentication Module
|
|
91
|
-
|
|
92
|
-
- **Complete auth system** - Register, login, logout, protected routes
|
|
93
|
-
- **JWT-based authentication** - Stateless, scalable token management
|
|
94
|
-
- **Password hashing** - Secure bcrypt password handling
|
|
95
|
-
- **Ready-to-use** - Production-ready auth APIs out of the box
|
|
96
|
-
- **Modular design** - Include/exclude during project creation
|
|
97
|
-
|
|
98
|
-
## Quick Start
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
# Create your charcole app now (with or without project name)
|
|
102
|
-
npx create-charcole@latest my-awesome-api
|
|
103
|
-
|
|
104
|
-
# OR (interactive mode)
|
|
105
|
-
npx create-charcole@latest
|
|
106
|
-
|
|
107
|
-
# Follow prompts to select:
|
|
108
|
-
# 1. Language: TypeScript or JavaScript
|
|
109
|
-
# 2. JWT Authentication: Yes/No (includes complete auth system)
|
|
110
|
-
# 3. Swagger Documentation: Yes/No (auto-generated from Zod schemas)
|
|
111
|
-
|
|
112
|
-
# Configure environment
|
|
113
|
-
cp .env.example .env
|
|
114
|
-
|
|
115
|
-
# Start development server (with auto-reload)
|
|
116
|
-
npm run dev
|
|
117
|
-
|
|
118
|
-
# Visit Swagger UI (if swagger enabled)
|
|
119
|
-
# http://localhost:3000/api-docs
|
|
120
|
-
|
|
121
|
-
# OR start production server
|
|
122
|
-
npm start
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Server runs on http://localhost:3000 by default.
|
|
126
|
-
|
|
127
|
-
## Swagger Documentation (New in v2.2)
|
|
128
|
-
|
|
129
|
-
### The Problem
|
|
130
|
-
|
|
131
|
-
Traditional API documentation requires writing the same schema twice:
|
|
132
|
-
|
|
133
|
-
1. Once in Zod for validation
|
|
134
|
-
2. Again in OpenAPI/Swagger YAML
|
|
135
|
-
|
|
136
|
-
This leads to:
|
|
137
|
-
|
|
138
|
-
- ❌ Massive duplication (76+ lines per endpoint)
|
|
139
|
-
- ❌ Out-of-sync documentation
|
|
140
|
-
- ❌ High maintenance burden
|
|
141
|
-
|
|
142
|
-
### The Solution
|
|
143
|
-
|
|
144
|
-
@charcoles/swagger automatically converts your Zod schemas to OpenAPI:
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
// Before: Register schema in swagger.config.ts
|
|
148
|
-
import { registerSchema, loginSchema } from "./schemas";
|
|
149
|
-
|
|
150
|
-
setupSwagger(app, {
|
|
151
|
-
schemas: {
|
|
152
|
-
registerSchema, // Auto-converted to OpenAPI!
|
|
153
|
-
loginSchema,
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// After: Use $ref everywhere
|
|
158
|
-
/**
|
|
159
|
-
* @swagger
|
|
160
|
-
* schema:
|
|
161
|
-
* $ref: '#/components/schemas/registerSchema'
|
|
162
|
-
*/
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Benefits
|
|
166
|
-
|
|
167
|
-
| Aspect | Before | After | Improvement |
|
|
168
|
-
| ---------------------- | --------------- | -------------- | ------------------ |
|
|
169
|
-
| **Lines per endpoint** | 45-76 lines | 10-20 lines | **60-75% less** |
|
|
170
|
-
| **Schema duplication** | 100% | 0% | **Eliminated** |
|
|
171
|
-
| **Maintenance** | Update 2 places | Update 1 place | **50% less work** |
|
|
172
|
-
| **Sync issues** | Common | Impossible | **Always in sync** |
|
|
173
|
-
|
|
174
|
-
**See complete guide:** `src/lib/swagger/SWAGGER_GUIDE.md` (when swagger is enabled)
|
|
175
|
-
|
|
176
|
-
## Repository Pattern: A Game Changer
|
|
177
|
-
|
|
178
|
-
### The Problem
|
|
179
|
-
|
|
180
|
-
Traditional apps mix database logic with business logic. Switching databases means rewriting everything.
|
|
181
|
-
|
|
182
|
-
### The Solution
|
|
183
|
-
|
|
184
|
-
Charcole introduces a Repository Pattern that abstracts database operations:
|
|
185
|
-
|
|
186
|
-
```javascript
|
|
187
|
-
// Traditional approach (tightly coupled)
|
|
188
|
-
// app.ts
|
|
189
|
-
import mongoose from 'mongoose';
|
|
190
|
-
|
|
191
|
-
async function getUser(id: string) {
|
|
192
|
-
return await UserModel.findById(id); // ❌ Direct MongoDB dependency
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Charcole v2.2 approach (abstracted)
|
|
196
|
-
// repositories/user.repo.ts
|
|
197
|
-
const users: User[] = [];
|
|
198
|
-
|
|
199
|
-
type CreateUserData = {
|
|
200
|
-
email: string;
|
|
201
|
-
name: string;
|
|
202
|
-
passwordHash: string;
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
export const userRepo = {
|
|
206
|
-
async findByEmail(email: string): Promise<User | undefined> {
|
|
207
|
-
return users.find((u) => u.email === email);
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
async create(data: CreateUserData): Promise<User> {
|
|
211
|
-
const user: User = {
|
|
212
|
-
id: randomUUID(),
|
|
213
|
-
email: data.email,
|
|
214
|
-
name: data.name,
|
|
215
|
-
passwordHash: data.passwordHash,
|
|
216
|
-
role: "user",
|
|
217
|
-
provider: "credentials",
|
|
218
|
-
isEmailVerified: false,
|
|
219
|
-
createdAt: new Date(),
|
|
220
|
-
updatedAt: new Date(),
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
users.push(user);
|
|
224
|
-
return user;
|
|
225
|
-
},
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
// controller.js
|
|
229
|
-
async login(req, res) {
|
|
230
|
-
try {
|
|
231
|
-
const result = await AuthService.login(req.body, req.app.locals.userRepo);
|
|
232
|
-
|
|
233
|
-
res.json(result);
|
|
234
|
-
} catch (err) {
|
|
235
|
-
res.status(401).json({ message: err.message });
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Benefits
|
|
241
|
-
|
|
242
|
-
- ✅ Test instantly - In-memory repository works without database setup
|
|
243
|
-
- ✅ Switch databases easily - Change MongoDB to PostgreSQL by updating one file
|
|
244
|
-
- ✅ Clean architecture - Business logic stays pure
|
|
245
|
-
- ✅ Better testing - Mock repositories for unit tests
|
|
246
|
-
- ✅ Future-proof - Adapt to any database technology
|
|
247
|
-
|
|
248
|
-
## JWT Authentication Module (Optional)
|
|
249
|
-
|
|
250
|
-
### What's Included
|
|
251
|
-
|
|
252
|
-
When you select "Yes" for authentication during project creation:
|
|
253
|
-
|
|
254
|
-
```
|
|
255
|
-
src/modules/auth/
|
|
256
|
-
│ ├── auth.controller.ts # Register, login, logout, me endpoints
|
|
257
|
-
│ ├── auth.middleware.ts # JWT verification, protected routes
|
|
258
|
-
│ ├── auth.service.ts # Business logic for authentication
|
|
259
|
-
│ ├── auth.routes.ts # Auth API routes
|
|
260
|
-
│ ├── auth.schemas.ts # Auth API Schemas (auto-documented if Swagger enabled!)
|
|
261
|
-
│ └── auth.constants.ts # Auth API constants
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### Available Endpoints
|
|
265
|
-
|
|
266
|
-
```
|
|
267
|
-
POST /api/auth/register # Create new account
|
|
268
|
-
POST /api/auth/login # Get JWT token
|
|
269
|
-
GET /api/protected/me # Get current user (protected)
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## Golden Rules (Updated for v2.2)
|
|
273
|
-
|
|
274
|
-
1. **Wrap async handlers with asyncHandler**
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
router.get("/users/:id", asyncHandler(async (req, res) => { ... }))
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
2. **Throw AppError (never use res.status().json())**
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
throw new NotFoundError("User", { id });
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
3. **Validate requests with validateRequest**
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
router.post("/users", validateRequest(schema), handler);
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
4. **Use repositories for database operations**
|
|
293
|
-
|
|
294
|
-
```typescript
|
|
295
|
-
// ❌ Direct database calls
|
|
296
|
-
const user = await UserModel.findById(id);
|
|
297
|
-
|
|
298
|
-
// ✅ Repository pattern
|
|
299
|
-
const user = await AuthService.login(req.body, req.app.locals.userRepo);
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
5. **Define schemas once in Zod (if Swagger enabled)**
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
// ✅ Single source of truth
|
|
306
|
-
const userSchema = z.object({ ... });
|
|
307
|
-
|
|
308
|
-
// Register in swagger.config.ts
|
|
309
|
-
setupSwagger(app, { schemas: { userSchema } });
|
|
310
|
-
|
|
311
|
-
// ❌ Never duplicate in JSDoc
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
## Why Choose Charcole v2.2?
|
|
315
|
-
|
|
316
|
-
### For Startups
|
|
317
|
-
|
|
318
|
-
- **Launch faster** - Production-ready API with auto-generated docs in minutes
|
|
319
|
-
- **Test without DB** - In-memory repository for rapid prototyping
|
|
320
|
-
- **Built-in auth** - User management out of the box
|
|
321
|
-
- **Clean code** - Follows best practices from day one
|
|
322
|
-
- **Free documentation** - Swagger UI generated automatically
|
|
323
|
-
|
|
324
|
-
### For Enterprises
|
|
325
|
-
|
|
326
|
-
- **Maintainable** - Repository pattern enables easy database migrations
|
|
327
|
-
- **Scalable** - Modular architecture grows with your needs
|
|
328
|
-
- **Reliable** - Battle-tested error handling
|
|
329
|
-
- **Type-safe** - Full TypeScript support reduces bugs
|
|
330
|
-
- **Always in sync** - Documentation can't get outdated
|
|
331
|
-
|
|
332
|
-
### For Developers
|
|
333
|
-
|
|
334
|
-
- **Learn best practices** - Production patterns built-in
|
|
335
|
-
- **Effortless docs** - 60-80% less documentation work
|
|
336
|
-
- **Easy to extend** - Add modules, databases, features
|
|
337
|
-
- **Great DX** - Excellent error messages and logging
|
|
338
|
-
- **Future-proof** - Designed for long-term maintenance
|
|
339
|
-
|
|
340
|
-
## 🤝 Contributing
|
|
341
|
-
|
|
342
|
-
We welcome contributions! Please:
|
|
343
|
-
|
|
344
|
-
1. Fork the repository, create new branch and raise a pull request. If it fits with the goals of **charcole** we'll merge it
|
|
345
|
-
2. Follow the repository pattern for database operations
|
|
346
|
-
3. Use TypeScript for new features
|
|
347
|
-
4. Include tests with in-memory repositories
|
|
348
|
-
5. Document new modules thoroughly
|
|
349
|
-
6. Update README.md for significant changes
|
|
350
|
-
7. If adding Swagger docs, use Zod schemas as single source of truth
|
|
351
|
-
|
|
352
|
-
## 📄 License
|
|
353
|
-
|
|
354
|
-
ISC
|
|
1
|
+
# Charcole API v2.2
|
|
2
|
+
|
|
3
|
+
> **Charcole v2.2 is a production-grade Node.js backend starter CLI that scaffolds enterprise-ready Express APIs with first-class TypeScript or JavaScript support, centralized error handling, Zod validation, structured logging, optional JWT authentication, **auto-generated Swagger documentation**, and a revolutionary repository pattern for database abstraction.**
|
|
4
|
+
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](https://expressjs.com/)
|
|
7
|
+
[](https://zod.dev/)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
## What's New in v2.2
|
|
12
|
+
|
|
13
|
+
### 🎯 Auto-Generated Swagger Documentation (@charcoles/swagger)
|
|
14
|
+
|
|
15
|
+
The game-changing feature that eliminates 60-80% of API documentation overhead:
|
|
16
|
+
|
|
17
|
+
- **Zero schema duplication** - Define Zod schemas once, auto-generate OpenAPI specs
|
|
18
|
+
- **Effortless documentation** - Minimal JSDoc comments with `$ref` to Zod schemas
|
|
19
|
+
- **Built-in response templates** - Common responses (Success, ValidationError, Unauthorized, NotFound) included
|
|
20
|
+
- **Always in sync** - Impossible for docs to drift from validation schemas
|
|
21
|
+
- **Optional module** - Include/exclude during project creation
|
|
22
|
+
- **Framework agnostic** - Works with any Express.js project via `npm install @charcoles/swagger`
|
|
23
|
+
|
|
24
|
+
**Before (76 lines of manual duplication):**
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// Zod schema for validation
|
|
28
|
+
const registerSchema = z.object({
|
|
29
|
+
email: z.string().email(),
|
|
30
|
+
password: z.string().min(8),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Manual OpenAPI schema (duplicate!)
|
|
34
|
+
/**
|
|
35
|
+
* @swagger
|
|
36
|
+
* /api/auth/register:
|
|
37
|
+
* post:
|
|
38
|
+
* requestBody:
|
|
39
|
+
* schema:
|
|
40
|
+
* type: object
|
|
41
|
+
* properties:
|
|
42
|
+
* email:
|
|
43
|
+
* type: string
|
|
44
|
+
* format: email
|
|
45
|
+
* password:
|
|
46
|
+
* type: string
|
|
47
|
+
* minLength: 8
|
|
48
|
+
* ... 60 more lines
|
|
49
|
+
*/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**After with @charcoles/swagger (20 lines, zero duplication):**
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// 1. Register schema once in swagger.config.ts
|
|
56
|
+
setupSwagger(app, {
|
|
57
|
+
schemas: { registerSchema }, // Auto-converted!
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// 2. Reference in JSDoc
|
|
61
|
+
/**
|
|
62
|
+
* @swagger
|
|
63
|
+
* /api/auth/register:
|
|
64
|
+
* post:
|
|
65
|
+
* summary: Register user
|
|
66
|
+
* requestBody:
|
|
67
|
+
* content:
|
|
68
|
+
* application/json:
|
|
69
|
+
* schema:
|
|
70
|
+
* $ref: '#/components/schemas/registerSchema'
|
|
71
|
+
* responses:
|
|
72
|
+
* 201:
|
|
73
|
+
* $ref: '#/components/responses/Success'
|
|
74
|
+
* 400:
|
|
75
|
+
* $ref: '#/components/responses/ValidationError'
|
|
76
|
+
*/
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Result:** Change your Zod schema → Swagger updates automatically! 🎉
|
|
80
|
+
|
|
81
|
+
### Previous Features (v2.1)
|
|
82
|
+
|
|
83
|
+
#### Revolutionary Repository Pattern
|
|
84
|
+
|
|
85
|
+
- **Database abstraction layer** - Switch databases without changing business logic
|
|
86
|
+
- **In-memory repository included** - Test APIs instantly without database setup
|
|
87
|
+
- **Clean separation** - Business logic stays independent of database implementation
|
|
88
|
+
- **Future-proof** - Easy migration between MongoDB, PostgreSQL, MySQL, etc.
|
|
89
|
+
|
|
90
|
+
#### Optional JWT Authentication Module
|
|
91
|
+
|
|
92
|
+
- **Complete auth system** - Register, login, logout, protected routes
|
|
93
|
+
- **JWT-based authentication** - Stateless, scalable token management
|
|
94
|
+
- **Password hashing** - Secure bcrypt password handling
|
|
95
|
+
- **Ready-to-use** - Production-ready auth APIs out of the box
|
|
96
|
+
- **Modular design** - Include/exclude during project creation
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Create your charcole app now (with or without project name)
|
|
102
|
+
npx create-charcole@latest my-awesome-api
|
|
103
|
+
|
|
104
|
+
# OR (interactive mode)
|
|
105
|
+
npx create-charcole@latest
|
|
106
|
+
|
|
107
|
+
# Follow prompts to select:
|
|
108
|
+
# 1. Language: TypeScript or JavaScript
|
|
109
|
+
# 2. JWT Authentication: Yes/No (includes complete auth system)
|
|
110
|
+
# 3. Swagger Documentation: Yes/No (auto-generated from Zod schemas)
|
|
111
|
+
|
|
112
|
+
# Configure environment
|
|
113
|
+
cp .env.example .env
|
|
114
|
+
|
|
115
|
+
# Start development server (with auto-reload)
|
|
116
|
+
npm run dev
|
|
117
|
+
|
|
118
|
+
# Visit Swagger UI (if swagger enabled)
|
|
119
|
+
# http://localhost:3000/api-docs
|
|
120
|
+
|
|
121
|
+
# OR start production server
|
|
122
|
+
npm start
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Server runs on http://localhost:3000 by default.
|
|
126
|
+
|
|
127
|
+
## Swagger Documentation (New in v2.2)
|
|
128
|
+
|
|
129
|
+
### The Problem
|
|
130
|
+
|
|
131
|
+
Traditional API documentation requires writing the same schema twice:
|
|
132
|
+
|
|
133
|
+
1. Once in Zod for validation
|
|
134
|
+
2. Again in OpenAPI/Swagger YAML
|
|
135
|
+
|
|
136
|
+
This leads to:
|
|
137
|
+
|
|
138
|
+
- ❌ Massive duplication (76+ lines per endpoint)
|
|
139
|
+
- ❌ Out-of-sync documentation
|
|
140
|
+
- ❌ High maintenance burden
|
|
141
|
+
|
|
142
|
+
### The Solution
|
|
143
|
+
|
|
144
|
+
@charcoles/swagger automatically converts your Zod schemas to OpenAPI:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// Before: Register schema in swagger.config.ts
|
|
148
|
+
import { registerSchema, loginSchema } from "./schemas";
|
|
149
|
+
|
|
150
|
+
setupSwagger(app, {
|
|
151
|
+
schemas: {
|
|
152
|
+
registerSchema, // Auto-converted to OpenAPI!
|
|
153
|
+
loginSchema,
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// After: Use $ref everywhere
|
|
158
|
+
/**
|
|
159
|
+
* @swagger
|
|
160
|
+
* schema:
|
|
161
|
+
* $ref: '#/components/schemas/registerSchema'
|
|
162
|
+
*/
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Benefits
|
|
166
|
+
|
|
167
|
+
| Aspect | Before | After | Improvement |
|
|
168
|
+
| ---------------------- | --------------- | -------------- | ------------------ |
|
|
169
|
+
| **Lines per endpoint** | 45-76 lines | 10-20 lines | **60-75% less** |
|
|
170
|
+
| **Schema duplication** | 100% | 0% | **Eliminated** |
|
|
171
|
+
| **Maintenance** | Update 2 places | Update 1 place | **50% less work** |
|
|
172
|
+
| **Sync issues** | Common | Impossible | **Always in sync** |
|
|
173
|
+
|
|
174
|
+
**See complete guide:** `src/lib/swagger/SWAGGER_GUIDE.md` (when swagger is enabled)
|
|
175
|
+
|
|
176
|
+
## Repository Pattern: A Game Changer
|
|
177
|
+
|
|
178
|
+
### The Problem
|
|
179
|
+
|
|
180
|
+
Traditional apps mix database logic with business logic. Switching databases means rewriting everything.
|
|
181
|
+
|
|
182
|
+
### The Solution
|
|
183
|
+
|
|
184
|
+
Charcole introduces a Repository Pattern that abstracts database operations:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
// Traditional approach (tightly coupled)
|
|
188
|
+
// app.ts
|
|
189
|
+
import mongoose from 'mongoose';
|
|
190
|
+
|
|
191
|
+
async function getUser(id: string) {
|
|
192
|
+
return await UserModel.findById(id); // ❌ Direct MongoDB dependency
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Charcole v2.2 approach (abstracted)
|
|
196
|
+
// repositories/user.repo.ts
|
|
197
|
+
const users: User[] = [];
|
|
198
|
+
|
|
199
|
+
type CreateUserData = {
|
|
200
|
+
email: string;
|
|
201
|
+
name: string;
|
|
202
|
+
passwordHash: string;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export const userRepo = {
|
|
206
|
+
async findByEmail(email: string): Promise<User | undefined> {
|
|
207
|
+
return users.find((u) => u.email === email);
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
async create(data: CreateUserData): Promise<User> {
|
|
211
|
+
const user: User = {
|
|
212
|
+
id: randomUUID(),
|
|
213
|
+
email: data.email,
|
|
214
|
+
name: data.name,
|
|
215
|
+
passwordHash: data.passwordHash,
|
|
216
|
+
role: "user",
|
|
217
|
+
provider: "credentials",
|
|
218
|
+
isEmailVerified: false,
|
|
219
|
+
createdAt: new Date(),
|
|
220
|
+
updatedAt: new Date(),
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
users.push(user);
|
|
224
|
+
return user;
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// controller.js
|
|
229
|
+
async login(req, res) {
|
|
230
|
+
try {
|
|
231
|
+
const result = await AuthService.login(req.body, req.app.locals.userRepo);
|
|
232
|
+
|
|
233
|
+
res.json(result);
|
|
234
|
+
} catch (err) {
|
|
235
|
+
res.status(401).json({ message: err.message });
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Benefits
|
|
241
|
+
|
|
242
|
+
- ✅ Test instantly - In-memory repository works without database setup
|
|
243
|
+
- ✅ Switch databases easily - Change MongoDB to PostgreSQL by updating one file
|
|
244
|
+
- ✅ Clean architecture - Business logic stays pure
|
|
245
|
+
- ✅ Better testing - Mock repositories for unit tests
|
|
246
|
+
- ✅ Future-proof - Adapt to any database technology
|
|
247
|
+
|
|
248
|
+
## JWT Authentication Module (Optional)
|
|
249
|
+
|
|
250
|
+
### What's Included
|
|
251
|
+
|
|
252
|
+
When you select "Yes" for authentication during project creation:
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
src/modules/auth/
|
|
256
|
+
│ ├── auth.controller.ts # Register, login, logout, me endpoints
|
|
257
|
+
│ ├── auth.middleware.ts # JWT verification, protected routes
|
|
258
|
+
│ ├── auth.service.ts # Business logic for authentication
|
|
259
|
+
│ ├── auth.routes.ts # Auth API routes
|
|
260
|
+
│ ├── auth.schemas.ts # Auth API Schemas (auto-documented if Swagger enabled!)
|
|
261
|
+
│ └── auth.constants.ts # Auth API constants
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Available Endpoints
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
POST /api/auth/register # Create new account
|
|
268
|
+
POST /api/auth/login # Get JWT token
|
|
269
|
+
GET /api/protected/me # Get current user (protected)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Golden Rules (Updated for v2.2)
|
|
273
|
+
|
|
274
|
+
1. **Wrap async handlers with asyncHandler**
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
router.get("/users/:id", asyncHandler(async (req, res) => { ... }))
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
2. **Throw AppError (never use res.status().json())**
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
throw new NotFoundError("User", { id });
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
3. **Validate requests with validateRequest**
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
router.post("/users", validateRequest(schema), handler);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
4. **Use repositories for database operations**
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// ❌ Direct database calls
|
|
296
|
+
const user = await UserModel.findById(id);
|
|
297
|
+
|
|
298
|
+
// ✅ Repository pattern
|
|
299
|
+
const user = await AuthService.login(req.body, req.app.locals.userRepo);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
5. **Define schemas once in Zod (if Swagger enabled)**
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// ✅ Single source of truth
|
|
306
|
+
const userSchema = z.object({ ... });
|
|
307
|
+
|
|
308
|
+
// Register in swagger.config.ts
|
|
309
|
+
setupSwagger(app, { schemas: { userSchema } });
|
|
310
|
+
|
|
311
|
+
// ❌ Never duplicate in JSDoc
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Why Choose Charcole v2.2?
|
|
315
|
+
|
|
316
|
+
### For Startups
|
|
317
|
+
|
|
318
|
+
- **Launch faster** - Production-ready API with auto-generated docs in minutes
|
|
319
|
+
- **Test without DB** - In-memory repository for rapid prototyping
|
|
320
|
+
- **Built-in auth** - User management out of the box
|
|
321
|
+
- **Clean code** - Follows best practices from day one
|
|
322
|
+
- **Free documentation** - Swagger UI generated automatically
|
|
323
|
+
|
|
324
|
+
### For Enterprises
|
|
325
|
+
|
|
326
|
+
- **Maintainable** - Repository pattern enables easy database migrations
|
|
327
|
+
- **Scalable** - Modular architecture grows with your needs
|
|
328
|
+
- **Reliable** - Battle-tested error handling
|
|
329
|
+
- **Type-safe** - Full TypeScript support reduces bugs
|
|
330
|
+
- **Always in sync** - Documentation can't get outdated
|
|
331
|
+
|
|
332
|
+
### For Developers
|
|
333
|
+
|
|
334
|
+
- **Learn best practices** - Production patterns built-in
|
|
335
|
+
- **Effortless docs** - 60-80% less documentation work
|
|
336
|
+
- **Easy to extend** - Add modules, databases, features
|
|
337
|
+
- **Great DX** - Excellent error messages and logging
|
|
338
|
+
- **Future-proof** - Designed for long-term maintenance
|
|
339
|
+
|
|
340
|
+
## 🤝 Contributing
|
|
341
|
+
|
|
342
|
+
We welcome contributions! Please:
|
|
343
|
+
|
|
344
|
+
1. Fork the repository, create new branch and raise a pull request. If it fits with the goals of **charcole** we'll merge it
|
|
345
|
+
2. Follow the repository pattern for database operations
|
|
346
|
+
3. Use TypeScript for new features
|
|
347
|
+
4. Include tests with in-memory repositories
|
|
348
|
+
5. Document new modules thoroughly
|
|
349
|
+
6. Update README.md for significant changes
|
|
350
|
+
7. If adding Swagger docs, use Zod schemas as single source of truth
|
|
351
|
+
|
|
352
|
+
## 📄 License
|
|
353
|
+
|
|
354
|
+
ISC
|