@starklabs/forge 1.0.1 → 1.1.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/dist/js/auth/forgotPassword.d.ts.map +1 -1
- package/dist/js/auth/forgotPassword.js +2 -5
- package/dist/js/auth/forgotPassword.js.map +1 -1
- package/dist/js/auth/login.d.ts.map +1 -1
- package/dist/js/auth/login.js +2 -5
- package/dist/js/auth/login.js.map +1 -1
- package/dist/js/auth/resendOTP.d.ts.map +1 -1
- package/dist/js/auth/resendOTP.js +2 -5
- package/dist/js/auth/resendOTP.js.map +1 -1
- package/dist/js/auth/resetPassword.d.ts.map +1 -1
- package/dist/js/auth/resetPassword.js +2 -5
- package/dist/js/auth/resetPassword.js.map +1 -1
- package/dist/js/auth/signup.d.ts.map +1 -1
- package/dist/js/auth/signup.js +3 -10
- package/dist/js/auth/signup.js.map +1 -1
- package/dist/js/auth/utils/authenticateUser.d.ts.map +1 -1
- package/dist/js/auth/utils/authenticateUser.js +3 -6
- package/dist/js/auth/utils/authenticateUser.js.map +1 -1
- package/dist/js/auth/utils/createOTPUser.d.ts.map +1 -1
- package/dist/js/auth/utils/createOTPUser.js +2 -5
- package/dist/js/auth/utils/createOTPUser.js.map +1 -1
- package/dist/js/auth/utils/createUser.js +1 -1
- package/dist/js/auth/utils/createUser.js.map +1 -1
- package/dist/js/auth/utils/handleIsVerified.d.ts.map +1 -1
- package/dist/js/auth/utils/handleIsVerified.js +2 -5
- package/dist/js/auth/utils/handleIsVerified.js.map +1 -1
- package/dist/js/auth/verifyOTP.d.ts.map +1 -1
- package/dist/js/auth/verifyOTP.js +6 -25
- package/dist/js/auth/verifyOTP.js.map +1 -1
- package/dist/js/config/defaultConfig.d.ts +2 -2
- package/dist/js/config/defaultConfig.d.ts.map +1 -1
- package/dist/js/config/defaultConfig.js +1 -0
- package/dist/js/config/defaultConfig.js.map +1 -1
- package/dist/js/config/envs.d.ts +4 -4
- package/dist/js/config/envs.d.ts.map +1 -1
- package/dist/js/config/envs.js.map +1 -1
- package/dist/js/crud/create.d.ts.map +1 -1
- package/dist/js/crud/create.js +4 -11
- package/dist/js/crud/create.js.map +1 -1
- package/dist/js/crud/createBulk.js +1 -1
- package/dist/js/crud/createBulk.js.map +1 -1
- package/dist/js/crud/handleUploads/file.add.d.ts.map +1 -1
- package/dist/js/crud/handleUploads/file.add.js +2 -5
- package/dist/js/crud/handleUploads/file.add.js.map +1 -1
- package/dist/js/crud/index.d.ts.map +1 -1
- package/dist/js/crud/index.js +2 -5
- package/dist/js/crud/index.js.map +1 -1
- package/dist/js/crud/read.d.ts.map +1 -1
- package/dist/js/crud/read.js +0 -1
- package/dist/js/crud/read.js.map +1 -1
- package/dist/js/crud/readAll.d.ts.map +1 -1
- package/dist/js/crud/readAll.js +0 -1
- package/dist/js/crud/readAll.js.map +1 -1
- package/dist/js/crud/removeAll.d.ts.map +1 -1
- package/dist/js/crud/removeAll.js +2 -5
- package/dist/js/crud/removeAll.js.map +1 -1
- package/dist/js/crud/update.js +1 -1
- package/dist/js/crud/update.js.map +1 -1
- package/dist/js/crud/utils/getItem.d.ts.map +1 -1
- package/dist/js/crud/utils/getItem.js +29 -24
- package/dist/js/crud/utils/getItem.js.map +1 -1
- package/dist/js/middleware/auth.middleware.js.map +1 -1
- package/dist/js/types/Collection.d.ts +4 -0
- package/dist/js/types/Collection.d.ts.map +1 -1
- package/dist/js/types/Constructor.d.ts +3 -1
- package/dist/js/types/Constructor.d.ts.map +1 -1
- package/dist/js/upload/create.d.ts.map +1 -1
- package/dist/js/upload/create.js +2 -5
- package/dist/js/upload/create.js.map +1 -1
- package/dist/js/utils/sanitize.d.ts +3 -2
- package/dist/js/utils/sanitize.d.ts.map +1 -1
- package/dist/js/utils/sanitize.js +8 -9
- package/dist/js/utils/sanitize.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +1476 -0
package/readme.md
ADDED
|
@@ -0,0 +1,1476 @@
|
|
|
1
|
+
<!-- ========================================================= -->
|
|
2
|
+
<!-- STARKLABS FORGE -->
|
|
3
|
+
<!-- ========================================================= -->
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
|
|
7
|
+
# ⚒️ StarkLabs Forge
|
|
8
|
+
|
|
9
|
+
### **Build your backend, not your boilerplate.**
|
|
10
|
+
|
|
11
|
+
*A modern, opinionated backend framework that eliminates repetitive Express development so you can focus on building your product.*
|
|
12
|
+
|
|
13
|
+
<br>
|
|
14
|
+
|
|
15
|
+
[](#)
|
|
16
|
+
[](#)
|
|
17
|
+
[](#)
|
|
18
|
+
[](#)
|
|
19
|
+
[](#)
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Why Forge?
|
|
26
|
+
|
|
27
|
+
Every Express backend starts the same way.
|
|
28
|
+
|
|
29
|
+
You create folders.
|
|
30
|
+
|
|
31
|
+
You create routers.
|
|
32
|
+
|
|
33
|
+
You create controllers.
|
|
34
|
+
|
|
35
|
+
You create models.
|
|
36
|
+
|
|
37
|
+
You create validation schemas.
|
|
38
|
+
|
|
39
|
+
You configure authentication.
|
|
40
|
+
|
|
41
|
+
You wire middleware.
|
|
42
|
+
|
|
43
|
+
You implement CRUD operations.
|
|
44
|
+
|
|
45
|
+
You handle uploads.
|
|
46
|
+
|
|
47
|
+
You write error handling.
|
|
48
|
+
|
|
49
|
+
You repeat the exact same architecture for every new project.
|
|
50
|
+
|
|
51
|
+
None of that is unique to your application.
|
|
52
|
+
|
|
53
|
+
It's infrastructure.
|
|
54
|
+
|
|
55
|
+
Yet every backend developer spends hours rebuilding it.
|
|
56
|
+
|
|
57
|
+
**Forge exists to eliminate that repetition.**
|
|
58
|
+
|
|
59
|
+
Instead of writing hundreds of lines of repetitive backend code, Forge lets you describe your application through simple configuration objects while the framework handles the implementation behind the scenes.
|
|
60
|
+
|
|
61
|
+
You focus on your business logic.
|
|
62
|
+
|
|
63
|
+
Forge takes care of the plumbing.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
# Philosophy
|
|
68
|
+
|
|
69
|
+
Forge is built around one simple belief:
|
|
70
|
+
|
|
71
|
+
> **Software engineers should spend their time solving business problems—not rewriting infrastructure.**
|
|
72
|
+
|
|
73
|
+
Modern backend applications share an enormous amount of common functionality.
|
|
74
|
+
|
|
75
|
+
Authentication.
|
|
76
|
+
|
|
77
|
+
Authorization.
|
|
78
|
+
|
|
79
|
+
Validation.
|
|
80
|
+
|
|
81
|
+
CRUD.
|
|
82
|
+
|
|
83
|
+
Health checks.
|
|
84
|
+
|
|
85
|
+
Uploads.
|
|
86
|
+
|
|
87
|
+
Database models.
|
|
88
|
+
|
|
89
|
+
Routing.
|
|
90
|
+
|
|
91
|
+
Error handling.
|
|
92
|
+
|
|
93
|
+
Permissions.
|
|
94
|
+
|
|
95
|
+
Most projects implement these almost identically.
|
|
96
|
+
|
|
97
|
+
Forge recognizes those patterns and automates them.
|
|
98
|
+
|
|
99
|
+
Instead of manually wiring everything together, developers simply describe their resources and let Forge generate the repetitive layers automatically.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# What Makes Forge Different?
|
|
104
|
+
|
|
105
|
+
Forge is **not** an Express starter template.
|
|
106
|
+
|
|
107
|
+
It is **not** a code generator.
|
|
108
|
+
|
|
109
|
+
It is **not** another collection of helper utilities.
|
|
110
|
+
|
|
111
|
+
Forge is a **backend engineering framework**.
|
|
112
|
+
|
|
113
|
+
Express runs internally.
|
|
114
|
+
|
|
115
|
+
Mongoose runs internally.
|
|
116
|
+
|
|
117
|
+
Validation runs internally.
|
|
118
|
+
|
|
119
|
+
Authentication runs internally.
|
|
120
|
+
|
|
121
|
+
Developers interact with **Forge**, not with the low-level implementation.
|
|
122
|
+
|
|
123
|
+
This allows Forge to enforce consistency, reduce boilerplate, and dramatically improve developer productivity.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
# The Problem
|
|
128
|
+
|
|
129
|
+
Consider a typical Express backend.
|
|
130
|
+
|
|
131
|
+
For every new resource you usually create:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
controllers/
|
|
135
|
+
models/
|
|
136
|
+
routes/
|
|
137
|
+
validators/
|
|
138
|
+
middlewares/
|
|
139
|
+
services/
|
|
140
|
+
utilities/
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Then you write:
|
|
144
|
+
|
|
145
|
+
- Route definitions
|
|
146
|
+
- Controller methods
|
|
147
|
+
- CRUD logic
|
|
148
|
+
- Validation middleware
|
|
149
|
+
- Authorization middleware
|
|
150
|
+
- Owner verification
|
|
151
|
+
- Model creation
|
|
152
|
+
- Error handling
|
|
153
|
+
- Response formatting
|
|
154
|
+
|
|
155
|
+
Again.
|
|
156
|
+
|
|
157
|
+
And again.
|
|
158
|
+
|
|
159
|
+
And again.
|
|
160
|
+
|
|
161
|
+
After a few projects you realize something:
|
|
162
|
+
|
|
163
|
+
You're no longer building products.
|
|
164
|
+
|
|
165
|
+
You're rebuilding your backend architecture.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
# The Forge Solution
|
|
170
|
+
|
|
171
|
+
Instead of writing six different files full of repetitive logic...
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
controllers/
|
|
175
|
+
models/
|
|
176
|
+
routes/
|
|
177
|
+
validators/
|
|
178
|
+
middlewares/
|
|
179
|
+
services/
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Forge lets you define your backend like this:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
collection({
|
|
186
|
+
reqType: "crud",
|
|
187
|
+
routeName: "expenses",
|
|
188
|
+
modelName: "Expense",
|
|
189
|
+
routesArray: routes,
|
|
190
|
+
mongooseSchemaObj: schema,
|
|
191
|
+
validationsObj: validation,
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
That's it.
|
|
196
|
+
|
|
197
|
+
Forge dynamically creates:
|
|
198
|
+
|
|
199
|
+
- Models
|
|
200
|
+
- Routes
|
|
201
|
+
- CRUD handlers
|
|
202
|
+
- Validation
|
|
203
|
+
- Authentication
|
|
204
|
+
- Authorization
|
|
205
|
+
- Owner protection
|
|
206
|
+
- Upload handling
|
|
207
|
+
- Error responses
|
|
208
|
+
- Database operations
|
|
209
|
+
|
|
210
|
+
You describe **what** your backend should do.
|
|
211
|
+
|
|
212
|
+
Forge handles **how** it gets done.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
# Design Goals
|
|
217
|
+
|
|
218
|
+
Forge was designed around five core principles.
|
|
219
|
+
|
|
220
|
+
## 1. Convention over Configuration
|
|
221
|
+
|
|
222
|
+
If 90% of applications solve a problem the same way, Forge should solve it automatically.
|
|
223
|
+
|
|
224
|
+
Developers shouldn't repeatedly configure infrastructure that rarely changes.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 2. Business Logic over Boilerplate
|
|
229
|
+
|
|
230
|
+
Your application is unique.
|
|
231
|
+
|
|
232
|
+
CRUD isn't.
|
|
233
|
+
|
|
234
|
+
Authentication isn't.
|
|
235
|
+
|
|
236
|
+
Validation isn't.
|
|
237
|
+
|
|
238
|
+
Routing isn't.
|
|
239
|
+
|
|
240
|
+
Forge removes repetitive engineering work so developers can invest more time in solving real product problems.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 3. Secure by Default
|
|
245
|
+
|
|
246
|
+
Security shouldn't depend on whether a developer remembered to install the right middleware.
|
|
247
|
+
|
|
248
|
+
Authentication.
|
|
249
|
+
|
|
250
|
+
Authorization.
|
|
251
|
+
|
|
252
|
+
Validation.
|
|
253
|
+
|
|
254
|
+
Cookies.
|
|
255
|
+
|
|
256
|
+
Password hashing.
|
|
257
|
+
|
|
258
|
+
Error handling.
|
|
259
|
+
|
|
260
|
+
Forge includes these as first-class citizens rather than optional examples.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 4. Progressive Complexity
|
|
265
|
+
|
|
266
|
+
A beginner should be able to create a production-ready backend quickly.
|
|
267
|
+
|
|
268
|
+
An experienced engineer should still have enough flexibility to build larger systems without fighting the framework.
|
|
269
|
+
|
|
270
|
+
Forge starts simple and grows with your application.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 5. Developer Experience First
|
|
275
|
+
|
|
276
|
+
Forge optimizes for:
|
|
277
|
+
|
|
278
|
+
- Readability
|
|
279
|
+
- Maintainability
|
|
280
|
+
- Consistency
|
|
281
|
+
- Excellent error messages
|
|
282
|
+
- Strong TypeScript support
|
|
283
|
+
- Minimal repetition
|
|
284
|
+
|
|
285
|
+
Because developers shouldn't have to fight their tools.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
# Core Principles
|
|
290
|
+
|
|
291
|
+
Forge asks one question before every new feature is added:
|
|
292
|
+
|
|
293
|
+
> **Does this remove repetitive work for most backend developers without sacrificing maintainability?**
|
|
294
|
+
|
|
295
|
+
If the answer is yes...
|
|
296
|
+
|
|
297
|
+
It belongs in Forge.
|
|
298
|
+
|
|
299
|
+
If the answer is no...
|
|
300
|
+
|
|
301
|
+
It probably belongs in the application instead.
|
|
302
|
+
|
|
303
|
+
This philosophy keeps Forge focused on infrastructure rather than business logic.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
# Architecture at a Glance
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
Developer
|
|
311
|
+
│
|
|
312
|
+
│
|
|
313
|
+
▼
|
|
314
|
+
Configuration Objects
|
|
315
|
+
│
|
|
316
|
+
▼
|
|
317
|
+
┌──────────────────────────────┐
|
|
318
|
+
│ Forge Core │
|
|
319
|
+
│ │
|
|
320
|
+
│ • Routing │
|
|
321
|
+
│ • Models │
|
|
322
|
+
│ • CRUD Engine │
|
|
323
|
+
│ • Authentication │
|
|
324
|
+
│ • Authorization │
|
|
325
|
+
│ • Validation │
|
|
326
|
+
│ • Upload Engine │
|
|
327
|
+
│ • Error Handling │
|
|
328
|
+
│ • Response Formatting │
|
|
329
|
+
└──────────────────────────────┘
|
|
330
|
+
│
|
|
331
|
+
▼
|
|
332
|
+
Express + Mongoose + Node.js
|
|
333
|
+
│
|
|
334
|
+
▼
|
|
335
|
+
MongoDB
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Notice something important.
|
|
339
|
+
|
|
340
|
+
Developers never interact directly with Express.
|
|
341
|
+
|
|
342
|
+
Forge becomes the abstraction layer between application code and backend infrastructure.
|
|
343
|
+
|
|
344
|
+
This allows the framework to evolve internally without forcing users to rewrite their applications.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
# Build Less Infrastructure.
|
|
349
|
+
|
|
350
|
+
## Build More Product.
|
|
351
|
+
|
|
352
|
+
Forge exists so your next backend starts with your ideas—not your boilerplate.
|
|
353
|
+
|
|
354
|
+
# Features
|
|
355
|
+
|
|
356
|
+
Forge is designed to eliminate repetitive backend engineering while remaining scalable for production applications.
|
|
357
|
+
|
|
358
|
+
## Current Features (v1)
|
|
359
|
+
|
|
360
|
+
### Core
|
|
361
|
+
|
|
362
|
+
- Convention-based backend architecture
|
|
363
|
+
- Dynamic route generation
|
|
364
|
+
- Automatic Mongoose model creation
|
|
365
|
+
- Built-in CRUD engine
|
|
366
|
+
- Zero controller boilerplate
|
|
367
|
+
- Zero router boilerplate
|
|
368
|
+
- Minimal project structure
|
|
369
|
+
- Opinionated architecture
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### Authentication
|
|
374
|
+
|
|
375
|
+
- Credentials-based authentication
|
|
376
|
+
- JWT authentication
|
|
377
|
+
- HTTP-only Cookie support
|
|
378
|
+
- Email OTP verification
|
|
379
|
+
- Login
|
|
380
|
+
- Logout
|
|
381
|
+
- Forgot Password
|
|
382
|
+
- Reset Password
|
|
383
|
+
- Protected routes
|
|
384
|
+
- Public routes
|
|
385
|
+
- Admin routes
|
|
386
|
+
- Owner-based authorization
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
### Validation
|
|
391
|
+
|
|
392
|
+
- Built-in Zod validation
|
|
393
|
+
- Automatic request validation
|
|
394
|
+
- Type-safe validation objects
|
|
395
|
+
- Zero middleware setup
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
### Database
|
|
400
|
+
|
|
401
|
+
- Automatic Mongoose schema generation
|
|
402
|
+
- Automatic model registration
|
|
403
|
+
- Population support
|
|
404
|
+
- Hidden field support
|
|
405
|
+
- Owner references
|
|
406
|
+
- Timestamp support
|
|
407
|
+
- CRUD abstraction
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### Uploads
|
|
412
|
+
|
|
413
|
+
- Route-based upload configuration
|
|
414
|
+
- Integrated CRUD uploads
|
|
415
|
+
- File creation
|
|
416
|
+
- File updates
|
|
417
|
+
- File deletion
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### Error Handling
|
|
422
|
+
|
|
423
|
+
Forge provides structured, developer-friendly errors.
|
|
424
|
+
|
|
425
|
+
Every error includes:
|
|
426
|
+
|
|
427
|
+
- Message
|
|
428
|
+
- Error Code
|
|
429
|
+
- HTTP Status Code
|
|
430
|
+
- Helpful Hint
|
|
431
|
+
- Technical Details
|
|
432
|
+
|
|
433
|
+
Example:
|
|
434
|
+
|
|
435
|
+
```json
|
|
436
|
+
{
|
|
437
|
+
"success": false,
|
|
438
|
+
"message": "Validation failed.",
|
|
439
|
+
"code": "VALIDATION_ERROR",
|
|
440
|
+
"statusCode": 400,
|
|
441
|
+
"hint": "The 'merchant' field is required.",
|
|
442
|
+
"details": {
|
|
443
|
+
"field": "merchant"
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
### TypeScript
|
|
451
|
+
|
|
452
|
+
Forge is written in TypeScript.
|
|
453
|
+
|
|
454
|
+
You get:
|
|
455
|
+
|
|
456
|
+
- Autocomplete
|
|
457
|
+
- IntelliSense
|
|
458
|
+
- Type Safety
|
|
459
|
+
- Better Developer Experience
|
|
460
|
+
|
|
461
|
+
JavaScript developers can use Forge without any additional configuration.
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
# Installation
|
|
466
|
+
|
|
467
|
+
Install Forge using npm.
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
npm install @starklabs/forge
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
or
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
pnpm add @starklabs/forge
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
or
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
yarn add @starklabs/forge
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
# Your First Resource
|
|
488
|
+
|
|
489
|
+
Every backend resource in Forge follows the same structure.
|
|
490
|
+
|
|
491
|
+
```
|
|
492
|
+
expenses/
|
|
493
|
+
|
|
494
|
+
├── expenses.collection.js
|
|
495
|
+
├── expenses.routes.js
|
|
496
|
+
├── expenses.schema.js
|
|
497
|
+
└── expenses.validation.js
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
Only four small files.
|
|
501
|
+
|
|
502
|
+
No controllers.
|
|
503
|
+
|
|
504
|
+
No routers.
|
|
505
|
+
|
|
506
|
+
No models.
|
|
507
|
+
|
|
508
|
+
No middleware.
|
|
509
|
+
|
|
510
|
+
Forge generates them internally.
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
# Creating a Resource
|
|
515
|
+
|
|
516
|
+
Every resource starts with a collection.
|
|
517
|
+
|
|
518
|
+
```ts
|
|
519
|
+
collection({
|
|
520
|
+
reqType: "crud",
|
|
521
|
+
routeName: "expenses",
|
|
522
|
+
modelName: "Expense",
|
|
523
|
+
routesArray: routes,
|
|
524
|
+
mongooseSchemaObj: schema,
|
|
525
|
+
validationsObj: validation,
|
|
526
|
+
});
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
That's the entry point for the entire resource.
|
|
530
|
+
|
|
531
|
+
Forge uses this configuration to dynamically build everything required for your backend.
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
# Define Your Schema
|
|
536
|
+
|
|
537
|
+
Instead of writing verbose Mongoose schemas...
|
|
538
|
+
|
|
539
|
+
```ts
|
|
540
|
+
{
|
|
541
|
+
merchant: {
|
|
542
|
+
type: String,
|
|
543
|
+
required: true
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Forge lets you write
|
|
549
|
+
|
|
550
|
+
```ts
|
|
551
|
+
const schema = {
|
|
552
|
+
merchant: mongooseFields.requiredString,
|
|
553
|
+
category: mongooseFields.requiredString,
|
|
554
|
+
amount: mongooseFields.requiredNumber,
|
|
555
|
+
date: mongooseFields.optionalString,
|
|
556
|
+
isUpdated: mongooseFields.booleanFalse,
|
|
557
|
+
owner: mongooseFields.userRef
|
|
558
|
+
};
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
Forge converts this into a complete Mongoose schema internally.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
# Define Validation
|
|
566
|
+
|
|
567
|
+
Validation follows the same philosophy.
|
|
568
|
+
|
|
569
|
+
```ts
|
|
570
|
+
const validation = {
|
|
571
|
+
|
|
572
|
+
create: {
|
|
573
|
+
|
|
574
|
+
merchant: zodFields.requiredString,
|
|
575
|
+
|
|
576
|
+
category: zodFields.requiredString,
|
|
577
|
+
|
|
578
|
+
amount: zodFields.requiredNumber,
|
|
579
|
+
|
|
580
|
+
date: zodFields.optionalString
|
|
581
|
+
|
|
582
|
+
},
|
|
583
|
+
|
|
584
|
+
update: {
|
|
585
|
+
|
|
586
|
+
isUpdated: zodFields.booleanTrue
|
|
587
|
+
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
};
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
Each object represents a reusable validation schema.
|
|
594
|
+
|
|
595
|
+
Routes simply reference the validation by name.
|
|
596
|
+
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
# Define Routes
|
|
600
|
+
|
|
601
|
+
Routes are declarative.
|
|
602
|
+
|
|
603
|
+
Instead of writing Express routers, middleware, controllers, authentication and validation manually...
|
|
604
|
+
|
|
605
|
+
You simply describe the route.
|
|
606
|
+
|
|
607
|
+
```ts
|
|
608
|
+
{
|
|
609
|
+
authRole: "authenticated",
|
|
610
|
+
handler: "create",
|
|
611
|
+
method: "post",
|
|
612
|
+
path: "/",
|
|
613
|
+
validationKey: "create"
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Forge handles the rest.
|
|
618
|
+
|
|
619
|
+
A complete CRUD resource can be expressed in only a handful of route objects.
|
|
620
|
+
|
|
621
|
+
Example:
|
|
622
|
+
|
|
623
|
+
```ts
|
|
624
|
+
const routes = [
|
|
625
|
+
|
|
626
|
+
{
|
|
627
|
+
authRole: "authenticated",
|
|
628
|
+
handler: "create",
|
|
629
|
+
method: "post",
|
|
630
|
+
path: "/",
|
|
631
|
+
validationKey: "create"
|
|
632
|
+
},
|
|
633
|
+
|
|
634
|
+
{
|
|
635
|
+
authRole: "public",
|
|
636
|
+
handler: "readAll",
|
|
637
|
+
method: "get",
|
|
638
|
+
path: "/",
|
|
639
|
+
validationKey: false
|
|
640
|
+
},
|
|
641
|
+
|
|
642
|
+
{
|
|
643
|
+
authRole: "public",
|
|
644
|
+
handler: "read",
|
|
645
|
+
method: "get",
|
|
646
|
+
path: "/:id",
|
|
647
|
+
validationKey: false
|
|
648
|
+
},
|
|
649
|
+
|
|
650
|
+
{
|
|
651
|
+
authRole: "adminOrOwner",
|
|
652
|
+
handler: "update",
|
|
653
|
+
method: "patch",
|
|
654
|
+
path: "/:id",
|
|
655
|
+
validationKey: "update"
|
|
656
|
+
},
|
|
657
|
+
|
|
658
|
+
{
|
|
659
|
+
authRole: "adminOrOwner",
|
|
660
|
+
handler: "remove",
|
|
661
|
+
method: "delete",
|
|
662
|
+
path: "/:id",
|
|
663
|
+
validationKey: false
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
];
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
Notice what isn't here.
|
|
670
|
+
|
|
671
|
+
- No controllers
|
|
672
|
+
- No routers
|
|
673
|
+
- No middleware
|
|
674
|
+
- No auth imports
|
|
675
|
+
- No validation middleware
|
|
676
|
+
- No CRUD logic
|
|
677
|
+
|
|
678
|
+
Forge generates those automatically.
|
|
679
|
+
|
|
680
|
+
---
|
|
681
|
+
|
|
682
|
+
# Built-in Handlers
|
|
683
|
+
|
|
684
|
+
Forge ships with production-ready handlers.
|
|
685
|
+
|
|
686
|
+
### Authentication
|
|
687
|
+
|
|
688
|
+
- signup
|
|
689
|
+
- login
|
|
690
|
+
- logout
|
|
691
|
+
- verifyOTP
|
|
692
|
+
- resendOTP
|
|
693
|
+
- forgotPassword
|
|
694
|
+
- resetPassword
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
### CRUD
|
|
699
|
+
|
|
700
|
+
- create
|
|
701
|
+
- createBulk
|
|
702
|
+
- read
|
|
703
|
+
- readAll
|
|
704
|
+
- update
|
|
705
|
+
- remove
|
|
706
|
+
- removeAll
|
|
707
|
+
- addFile
|
|
708
|
+
- updateFile
|
|
709
|
+
- deleteFile
|
|
710
|
+
|
|
711
|
+
---
|
|
712
|
+
|
|
713
|
+
### Health
|
|
714
|
+
|
|
715
|
+
- healthGet
|
|
716
|
+
- healthPost
|
|
717
|
+
- healthPut
|
|
718
|
+
- healthPatch
|
|
719
|
+
- healthDelete
|
|
720
|
+
|
|
721
|
+
No controller implementation required.
|
|
722
|
+
|
|
723
|
+
Simply reference the handler name inside your route.
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
# Authorization
|
|
728
|
+
|
|
729
|
+
Authorization is intentionally simple.
|
|
730
|
+
|
|
731
|
+
```ts
|
|
732
|
+
authRole: "public"
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
```ts
|
|
736
|
+
authRole: "authenticated"
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
```ts
|
|
740
|
+
authRole: "admin"
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
```ts
|
|
744
|
+
authRole: "adminOrOwner"
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
Forge applies the appropriate middleware automatically.
|
|
748
|
+
|
|
749
|
+
No imports.
|
|
750
|
+
|
|
751
|
+
No route protection boilerplate.
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
# Uploads
|
|
756
|
+
|
|
757
|
+
Uploads are configured per route.
|
|
758
|
+
|
|
759
|
+
Only routes that need uploads should configure uploads.
|
|
760
|
+
|
|
761
|
+
This keeps the framework lightweight while allowing complete flexibility.
|
|
762
|
+
|
|
763
|
+
```ts
|
|
764
|
+
{
|
|
765
|
+
handler: "create",
|
|
766
|
+
|
|
767
|
+
uploadArray: [
|
|
768
|
+
|
|
769
|
+
{
|
|
770
|
+
fieldName: "avatar",
|
|
771
|
+
|
|
772
|
+
provider: "cloudinary",
|
|
773
|
+
|
|
774
|
+
uploadType: "image"
|
|
775
|
+
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
]
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
The CRUD engine automatically integrates upload processing with database operations.
|
|
783
|
+
|
|
784
|
+
No manual upload controller required.
|
|
785
|
+
|
|
786
|
+
---
|
|
787
|
+
|
|
788
|
+
# Philosophy in Practice
|
|
789
|
+
|
|
790
|
+
Forge is designed around one idea:
|
|
791
|
+
|
|
792
|
+
Describe your backend.
|
|
793
|
+
|
|
794
|
+
Don't build its infrastructure.
|
|
795
|
+
|
|
796
|
+
# Architecture
|
|
797
|
+
|
|
798
|
+
Forge is built around a simple architectural idea:
|
|
799
|
+
|
|
800
|
+
> **Applications should describe backend resources, not implement backend infrastructure.**
|
|
801
|
+
|
|
802
|
+
Instead of exposing low-level framework internals, Forge provides a declarative layer that sits between your application and the underlying runtime.
|
|
803
|
+
|
|
804
|
+
```
|
|
805
|
+
Your Application
|
|
806
|
+
│
|
|
807
|
+
▼
|
|
808
|
+
Configuration Objects (Resources)
|
|
809
|
+
│
|
|
810
|
+
▼
|
|
811
|
+
┌───────────────────────┐
|
|
812
|
+
│ Forge Core │
|
|
813
|
+
│ │
|
|
814
|
+
│ • Route Builder │
|
|
815
|
+
│ • CRUD Engine │
|
|
816
|
+
│ • Auth Engine │
|
|
817
|
+
│ • Validation Engine │
|
|
818
|
+
│ • Upload Engine │
|
|
819
|
+
│ • Error Engine │
|
|
820
|
+
│ • Model Generator │
|
|
821
|
+
└───────────────────────┘
|
|
822
|
+
│
|
|
823
|
+
▼
|
|
824
|
+
Express + Mongoose
|
|
825
|
+
│
|
|
826
|
+
▼
|
|
827
|
+
MongoDB
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
Your application communicates with Forge.
|
|
831
|
+
|
|
832
|
+
Forge communicates with Express.
|
|
833
|
+
|
|
834
|
+
Express communicates with Node.js.
|
|
835
|
+
|
|
836
|
+
This separation allows the framework to evolve internally while keeping application code clean and stable.
|
|
837
|
+
|
|
838
|
+
---
|
|
839
|
+
|
|
840
|
+
# Internal Request Lifecycle
|
|
841
|
+
|
|
842
|
+
Every request follows the same predictable pipeline.
|
|
843
|
+
|
|
844
|
+
```
|
|
845
|
+
Incoming Request
|
|
846
|
+
│
|
|
847
|
+
▼
|
|
848
|
+
Route Match
|
|
849
|
+
│
|
|
850
|
+
▼
|
|
851
|
+
Authentication
|
|
852
|
+
│
|
|
853
|
+
▼
|
|
854
|
+
Authorization
|
|
855
|
+
│
|
|
856
|
+
▼
|
|
857
|
+
Validation
|
|
858
|
+
│
|
|
859
|
+
▼
|
|
860
|
+
Upload Processing (Optional)
|
|
861
|
+
│
|
|
862
|
+
▼
|
|
863
|
+
CRUD / Auth Handler
|
|
864
|
+
│
|
|
865
|
+
▼
|
|
866
|
+
Database Operation
|
|
867
|
+
│
|
|
868
|
+
▼
|
|
869
|
+
Response Formatter
|
|
870
|
+
│
|
|
871
|
+
▼
|
|
872
|
+
Client
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
Because every request passes through the same pipeline, applications remain consistent regardless of project size.
|
|
876
|
+
|
|
877
|
+
---
|
|
878
|
+
|
|
879
|
+
# Convention over Configuration
|
|
880
|
+
|
|
881
|
+
Forge intentionally follows a convention-first architecture.
|
|
882
|
+
|
|
883
|
+
Instead of asking developers to configure every layer manually, Forge provides sensible defaults for common backend patterns.
|
|
884
|
+
|
|
885
|
+
For example:
|
|
886
|
+
|
|
887
|
+
Instead of writing:
|
|
888
|
+
|
|
889
|
+
- Routes
|
|
890
|
+
- Controllers
|
|
891
|
+
- Middleware
|
|
892
|
+
- Validation
|
|
893
|
+
- Models
|
|
894
|
+
|
|
895
|
+
every time...
|
|
896
|
+
|
|
897
|
+
Developers simply define a resource.
|
|
898
|
+
|
|
899
|
+
Everything else is generated automatically.
|
|
900
|
+
|
|
901
|
+
This dramatically reduces duplicated code while keeping projects easy to understand.
|
|
902
|
+
|
|
903
|
+
---
|
|
904
|
+
|
|
905
|
+
# Why Express is Hidden
|
|
906
|
+
|
|
907
|
+
Express is one of the most popular backend frameworks in the Node.js ecosystem.
|
|
908
|
+
|
|
909
|
+
It is also extremely repetitive.
|
|
910
|
+
|
|
911
|
+
Every application recreates the same structure:
|
|
912
|
+
|
|
913
|
+
- Routers
|
|
914
|
+
- Controllers
|
|
915
|
+
- Middleware
|
|
916
|
+
- CRUD
|
|
917
|
+
- Validation
|
|
918
|
+
- Error handling
|
|
919
|
+
|
|
920
|
+
The framework gives developers complete freedom.
|
|
921
|
+
|
|
922
|
+
That flexibility is valuable.
|
|
923
|
+
|
|
924
|
+
But it also means every project spends time rebuilding the same infrastructure.
|
|
925
|
+
|
|
926
|
+
Forge intentionally hides Express because most applications do not benefit from repeatedly implementing these layers.
|
|
927
|
+
|
|
928
|
+
Instead, Forge exposes a higher-level API focused on application development rather than framework wiring.
|
|
929
|
+
|
|
930
|
+
Developers work with business concepts.
|
|
931
|
+
|
|
932
|
+
Forge works with Express.
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
# Why Controllers Don't Exist
|
|
937
|
+
|
|
938
|
+
Traditional Express applications usually organize logic like this.
|
|
939
|
+
|
|
940
|
+
```
|
|
941
|
+
Route
|
|
942
|
+
│
|
|
943
|
+
▼
|
|
944
|
+
Controller
|
|
945
|
+
│
|
|
946
|
+
▼
|
|
947
|
+
Service
|
|
948
|
+
│
|
|
949
|
+
▼
|
|
950
|
+
Database
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
Controllers often become repetitive.
|
|
954
|
+
|
|
955
|
+
Many controller methods only perform operations like:
|
|
956
|
+
|
|
957
|
+
- validate request
|
|
958
|
+
- call model
|
|
959
|
+
- send response
|
|
960
|
+
|
|
961
|
+
The controller exists simply because Express expects one.
|
|
962
|
+
|
|
963
|
+
Forge removes this layer.
|
|
964
|
+
|
|
965
|
+
Instead of writing controller functions that contain no unique logic, developers declare their intent.
|
|
966
|
+
|
|
967
|
+
```
|
|
968
|
+
{
|
|
969
|
+
handler: "create"
|
|
970
|
+
}
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
Forge executes the appropriate internal handler automatically.
|
|
974
|
+
|
|
975
|
+
Business logic belongs inside the application.
|
|
976
|
+
|
|
977
|
+
Infrastructure belongs inside the framework.
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
# Opinionated by Design
|
|
982
|
+
|
|
983
|
+
Forge is intentionally opinionated.
|
|
984
|
+
|
|
985
|
+
This is a deliberate architectural decision.
|
|
986
|
+
|
|
987
|
+
Opinionated frameworks create consistency.
|
|
988
|
+
|
|
989
|
+
Consistency improves:
|
|
990
|
+
|
|
991
|
+
- Readability
|
|
992
|
+
- Maintainability
|
|
993
|
+
- Team collaboration
|
|
994
|
+
- Long-term scalability
|
|
995
|
+
|
|
996
|
+
Instead of allowing ten different ways to solve the same problem, Forge encourages one well-tested approach.
|
|
997
|
+
|
|
998
|
+
This reduces decision fatigue while making projects easier to navigate.
|
|
999
|
+
|
|
1000
|
+
---
|
|
1001
|
+
|
|
1002
|
+
# Design Tradeoffs
|
|
1003
|
+
|
|
1004
|
+
Every framework makes compromises.
|
|
1005
|
+
|
|
1006
|
+
Forge is no exception.
|
|
1007
|
+
|
|
1008
|
+
Understanding these tradeoffs is important.
|
|
1009
|
+
|
|
1010
|
+
## Less Flexibility
|
|
1011
|
+
|
|
1012
|
+
Forge intentionally limits low-level customization.
|
|
1013
|
+
|
|
1014
|
+
This allows the framework to automate repetitive work while keeping projects consistent.
|
|
1015
|
+
|
|
1016
|
+
If complete control over Express internals is required, using Express directly may be the better choice.
|
|
1017
|
+
|
|
1018
|
+
Forge optimizes for productivity—not unlimited customization.
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
## More Conventions
|
|
1023
|
+
|
|
1024
|
+
Forge expects projects to follow its architecture.
|
|
1025
|
+
|
|
1026
|
+
In return, developers write significantly less infrastructure code.
|
|
1027
|
+
|
|
1028
|
+
Consistency becomes an advantage instead of a restriction.
|
|
1029
|
+
|
|
1030
|
+
---
|
|
1031
|
+
|
|
1032
|
+
## Higher Abstraction
|
|
1033
|
+
|
|
1034
|
+
Forge introduces another abstraction layer.
|
|
1035
|
+
|
|
1036
|
+
The framework hides implementation details that developers would otherwise write manually.
|
|
1037
|
+
|
|
1038
|
+
This slightly increases abstraction while dramatically reducing repetitive engineering work.
|
|
1039
|
+
|
|
1040
|
+
---
|
|
1041
|
+
|
|
1042
|
+
## Framework Responsibility
|
|
1043
|
+
|
|
1044
|
+
Traditional Express projects ask every application to solve the same infrastructure problems.
|
|
1045
|
+
|
|
1046
|
+
Forge moves those responsibilities into the framework itself.
|
|
1047
|
+
|
|
1048
|
+
Applications become smaller.
|
|
1049
|
+
|
|
1050
|
+
The framework becomes smarter.
|
|
1051
|
+
|
|
1052
|
+
---
|
|
1053
|
+
|
|
1054
|
+
# Error Philosophy
|
|
1055
|
+
|
|
1056
|
+
Errors should help developers fix problems.
|
|
1057
|
+
|
|
1058
|
+
Not merely report them.
|
|
1059
|
+
|
|
1060
|
+
Every Forge error is designed to answer five questions.
|
|
1061
|
+
|
|
1062
|
+
1. What happened?
|
|
1063
|
+
2. Why did it happen?
|
|
1064
|
+
3. Which HTTP status should be returned?
|
|
1065
|
+
4. How can it be fixed?
|
|
1066
|
+
5. What technical details are useful for debugging?
|
|
1067
|
+
|
|
1068
|
+
Instead of vague messages like:
|
|
1069
|
+
|
|
1070
|
+
```
|
|
1071
|
+
Validation failed
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
Forge aims to provide structured errors such as:
|
|
1075
|
+
|
|
1076
|
+
```json
|
|
1077
|
+
{
|
|
1078
|
+
"message": "Validation failed.",
|
|
1079
|
+
"code": "VALIDATION_ERROR",
|
|
1080
|
+
"statusCode": 400,
|
|
1081
|
+
"hint": "The 'merchant' field is required.",
|
|
1082
|
+
"details": {
|
|
1083
|
+
"field": "merchant"
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
```
|
|
1087
|
+
|
|
1088
|
+
Good error messages reduce debugging time.
|
|
1089
|
+
|
|
1090
|
+
Great error messages reduce frustration.
|
|
1091
|
+
|
|
1092
|
+
---
|
|
1093
|
+
|
|
1094
|
+
# Security Philosophy
|
|
1095
|
+
|
|
1096
|
+
Security should not depend on whether developers remembered to install the correct middleware.
|
|
1097
|
+
|
|
1098
|
+
Forge includes security as part of the framework itself.
|
|
1099
|
+
|
|
1100
|
+
Authentication.
|
|
1101
|
+
|
|
1102
|
+
Authorization.
|
|
1103
|
+
|
|
1104
|
+
Validation.
|
|
1105
|
+
|
|
1106
|
+
Cookie handling.
|
|
1107
|
+
|
|
1108
|
+
Protected routes.
|
|
1109
|
+
|
|
1110
|
+
Owner verification.
|
|
1111
|
+
|
|
1112
|
+
These are built into the request lifecycle instead of being optional examples copied from documentation.
|
|
1113
|
+
|
|
1114
|
+
Applications become safer by default.
|
|
1115
|
+
|
|
1116
|
+
---
|
|
1117
|
+
|
|
1118
|
+
# Why Configuration Instead of Code?
|
|
1119
|
+
|
|
1120
|
+
Imagine two resources.
|
|
1121
|
+
|
|
1122
|
+
Products.
|
|
1123
|
+
|
|
1124
|
+
Expenses.
|
|
1125
|
+
|
|
1126
|
+
The infrastructure behind them is almost identical.
|
|
1127
|
+
|
|
1128
|
+
Only the data changes.
|
|
1129
|
+
|
|
1130
|
+
Forge embraces this observation.
|
|
1131
|
+
|
|
1132
|
+
Instead of writing new infrastructure for every resource, developers simply describe the resource.
|
|
1133
|
+
|
|
1134
|
+
The framework generates the repetitive implementation.
|
|
1135
|
+
|
|
1136
|
+
Configuration becomes the source of truth.
|
|
1137
|
+
|
|
1138
|
+
---
|
|
1139
|
+
|
|
1140
|
+
# Scalability
|
|
1141
|
+
|
|
1142
|
+
Forge is designed to scale in two different directions.
|
|
1143
|
+
|
|
1144
|
+
### Application Scale
|
|
1145
|
+
|
|
1146
|
+
As applications grow, backend resources remain consistent because every resource follows the same conventions.
|
|
1147
|
+
|
|
1148
|
+
Developers spend less time navigating different architectural styles across projects.
|
|
1149
|
+
|
|
1150
|
+
---
|
|
1151
|
+
|
|
1152
|
+
### Framework Scale
|
|
1153
|
+
|
|
1154
|
+
Forge itself is modular.
|
|
1155
|
+
|
|
1156
|
+
New capabilities can be added without changing existing applications.
|
|
1157
|
+
|
|
1158
|
+
Examples include:
|
|
1159
|
+
|
|
1160
|
+
- PostgreSQL
|
|
1161
|
+
- Redis
|
|
1162
|
+
- OAuth
|
|
1163
|
+
- Magic Links
|
|
1164
|
+
- Refresh Tokens
|
|
1165
|
+
- Additional upload providers
|
|
1166
|
+
- New authentication strategies
|
|
1167
|
+
|
|
1168
|
+
Applications remain stable while the framework evolves.
|
|
1169
|
+
|
|
1170
|
+
---
|
|
1171
|
+
|
|
1172
|
+
# Future Vision
|
|
1173
|
+
|
|
1174
|
+
Forge is still in its first generation.
|
|
1175
|
+
|
|
1176
|
+
The long-term vision is much larger.
|
|
1177
|
+
|
|
1178
|
+
Future releases aim to provide optional support for:
|
|
1179
|
+
|
|
1180
|
+
- PostgreSQL
|
|
1181
|
+
- Redis
|
|
1182
|
+
- Multiple authentication providers
|
|
1183
|
+
- OAuth
|
|
1184
|
+
- Magic Links
|
|
1185
|
+
- Refresh Tokens
|
|
1186
|
+
- Advanced querying
|
|
1187
|
+
- Pagination
|
|
1188
|
+
- Filtering
|
|
1189
|
+
- Search
|
|
1190
|
+
- Caching
|
|
1191
|
+
- Background jobs
|
|
1192
|
+
- Event-driven workflows
|
|
1193
|
+
|
|
1194
|
+
Each feature will follow the same philosophy that defines Forge today:
|
|
1195
|
+
|
|
1196
|
+
> **Reduce repetitive engineering without sacrificing maintainability.**
|
|
1197
|
+
|
|
1198
|
+
---
|
|
1199
|
+
|
|
1200
|
+
# One Goal
|
|
1201
|
+
|
|
1202
|
+
Forge does not aim to replace backend engineers.
|
|
1203
|
+
|
|
1204
|
+
It aims to replace repetitive backend engineering.
|
|
1205
|
+
|
|
1206
|
+
Because your application deserves your creativity.
|
|
1207
|
+
|
|
1208
|
+
Not your boilerplate.
|
|
1209
|
+
|
|
1210
|
+
# Why Forge?
|
|
1211
|
+
|
|
1212
|
+
There are already many excellent backend frameworks.
|
|
1213
|
+
|
|
1214
|
+
Express.
|
|
1215
|
+
|
|
1216
|
+
NestJS.
|
|
1217
|
+
|
|
1218
|
+
Fastify.
|
|
1219
|
+
|
|
1220
|
+
Hono.
|
|
1221
|
+
|
|
1222
|
+
AdonisJS.
|
|
1223
|
+
|
|
1224
|
+
Each solves a different problem.
|
|
1225
|
+
|
|
1226
|
+
Forge was created to solve a very specific one:
|
|
1227
|
+
|
|
1228
|
+
> **Backend infrastructure is repetitive.**
|
|
1229
|
+
|
|
1230
|
+
Forge does not attempt to replace Express.
|
|
1231
|
+
|
|
1232
|
+
It builds upon years of proven ecosystem stability while removing the repetitive engineering work that every project starts with.
|
|
1233
|
+
|
|
1234
|
+
---
|
|
1235
|
+
|
|
1236
|
+
# Forge vs Traditional Express
|
|
1237
|
+
|
|
1238
|
+
| Feature | Express | Forge |
|
|
1239
|
+
|----------|---------|--------|
|
|
1240
|
+
| Manual Routes | ✅ | ❌ |
|
|
1241
|
+
| Manual Controllers | ✅ | ❌ |
|
|
1242
|
+
| Manual CRUD | ✅ | ❌ |
|
|
1243
|
+
| Manual Model Registration | ✅ | ❌ |
|
|
1244
|
+
| Validation Wiring | ✅ | ❌ |
|
|
1245
|
+
| Auth Middleware Wiring | ✅ | ❌ |
|
|
1246
|
+
| Owner Verification | ✅ | ❌ |
|
|
1247
|
+
| Route Configuration | ⚠️ Manual | ✅ Declarative |
|
|
1248
|
+
| Boilerplate | High | Minimal |
|
|
1249
|
+
| TypeScript Support | Optional | Built-in |
|
|
1250
|
+
| Developer Experience | Depends on project | Consistent |
|
|
1251
|
+
|
|
1252
|
+
Forge intentionally removes infrastructure code so developers can spend more time building product features.
|
|
1253
|
+
|
|
1254
|
+
---
|
|
1255
|
+
|
|
1256
|
+
# Why Not NestJS?
|
|
1257
|
+
|
|
1258
|
+
NestJS is an excellent framework.
|
|
1259
|
+
|
|
1260
|
+
It provides dependency injection, decorators, modules, and enterprise architecture.
|
|
1261
|
+
|
|
1262
|
+
Forge has a different philosophy.
|
|
1263
|
+
|
|
1264
|
+
NestJS asks developers to build applications using a structured architecture.
|
|
1265
|
+
|
|
1266
|
+
Forge asks developers to describe backend resources and lets the framework generate the repetitive implementation automatically.
|
|
1267
|
+
|
|
1268
|
+
Both approaches are valid.
|
|
1269
|
+
|
|
1270
|
+
Forge simply optimizes for a different developer experience.
|
|
1271
|
+
|
|
1272
|
+
---
|
|
1273
|
+
|
|
1274
|
+
# Why Not Build Directly With Express?
|
|
1275
|
+
|
|
1276
|
+
Express gives developers complete freedom.
|
|
1277
|
+
|
|
1278
|
+
That freedom comes with responsibility.
|
|
1279
|
+
|
|
1280
|
+
Every project must solve:
|
|
1281
|
+
|
|
1282
|
+
- Routing
|
|
1283
|
+
- Validation
|
|
1284
|
+
- Authentication
|
|
1285
|
+
- Authorization
|
|
1286
|
+
- CRUD
|
|
1287
|
+
- Uploads
|
|
1288
|
+
- Error handling
|
|
1289
|
+
- Folder structure
|
|
1290
|
+
- Model registration
|
|
1291
|
+
|
|
1292
|
+
again and again.
|
|
1293
|
+
|
|
1294
|
+
Forge treats these as solved infrastructure problems.
|
|
1295
|
+
|
|
1296
|
+
Applications should not need to rebuild them.
|
|
1297
|
+
|
|
1298
|
+
---
|
|
1299
|
+
|
|
1300
|
+
# Folder Structure
|
|
1301
|
+
|
|
1302
|
+
A typical Forge application remains intentionally small.
|
|
1303
|
+
|
|
1304
|
+
```text
|
|
1305
|
+
src/
|
|
1306
|
+
│
|
|
1307
|
+
├── app.js
|
|
1308
|
+
├── server.js
|
|
1309
|
+
│
|
|
1310
|
+
├── config/
|
|
1311
|
+
│
|
|
1312
|
+
├── collections/
|
|
1313
|
+
│ ├── users/
|
|
1314
|
+
│ ├── expenses/
|
|
1315
|
+
│ ├── products/
|
|
1316
|
+
│ └── invoices/
|
|
1317
|
+
│
|
|
1318
|
+
└── utilities/
|
|
1319
|
+
```
|
|
1320
|
+
|
|
1321
|
+
Each collection contains only the configuration necessary to describe the resource.
|
|
1322
|
+
|
|
1323
|
+
The framework generates the infrastructure.
|
|
1324
|
+
|
|
1325
|
+
---
|
|
1326
|
+
|
|
1327
|
+
# Project Philosophy
|
|
1328
|
+
|
|
1329
|
+
Forge follows a simple engineering rule.
|
|
1330
|
+
|
|
1331
|
+
> **If every backend writes the same code, that code belongs inside the framework—not inside every application.**
|
|
1332
|
+
|
|
1333
|
+
This principle guides every architectural decision.
|
|
1334
|
+
|
|
1335
|
+
Before a feature becomes part of Forge, one question is asked:
|
|
1336
|
+
|
|
1337
|
+
> Will this eliminate repetitive engineering for most backend developers?
|
|
1338
|
+
|
|
1339
|
+
If the answer is yes...
|
|
1340
|
+
|
|
1341
|
+
It belongs in the framework.
|
|
1342
|
+
|
|
1343
|
+
Otherwise...
|
|
1344
|
+
|
|
1345
|
+
It belongs inside the application.
|
|
1346
|
+
|
|
1347
|
+
---
|
|
1348
|
+
|
|
1349
|
+
# Roadmap
|
|
1350
|
+
|
|
1351
|
+
Forge is actively evolving.
|
|
1352
|
+
|
|
1353
|
+
The vision extends far beyond CRUD generation.
|
|
1354
|
+
|
|
1355
|
+
## Version 1
|
|
1356
|
+
|
|
1357
|
+
- Dynamic CRUD
|
|
1358
|
+
- Authentication
|
|
1359
|
+
- Authorization
|
|
1360
|
+
- Health Routes
|
|
1361
|
+
- Upload Engine
|
|
1362
|
+
- Validation
|
|
1363
|
+
- TypeScript Support
|
|
1364
|
+
- MongoDB
|
|
1365
|
+
- Structured Errors
|
|
1366
|
+
|
|
1367
|
+
---
|
|
1368
|
+
|
|
1369
|
+
## Version 2
|
|
1370
|
+
|
|
1371
|
+
- PostgreSQL Support
|
|
1372
|
+
- Redis Integration
|
|
1373
|
+
- Pagination
|
|
1374
|
+
- Filtering
|
|
1375
|
+
- Search
|
|
1376
|
+
- Sorting
|
|
1377
|
+
- Better Query Engine
|
|
1378
|
+
- Multiple Upload Providers
|
|
1379
|
+
|
|
1380
|
+
---
|
|
1381
|
+
|
|
1382
|
+
## Version 3
|
|
1383
|
+
|
|
1384
|
+
- OAuth Providers
|
|
1385
|
+
- Magic Links
|
|
1386
|
+
- Refresh Tokens
|
|
1387
|
+
- Background Jobs
|
|
1388
|
+
- Event System
|
|
1389
|
+
- Queue Integration
|
|
1390
|
+
- Caching
|
|
1391
|
+
- Real-time Features
|
|
1392
|
+
|
|
1393
|
+
---
|
|
1394
|
+
|
|
1395
|
+
## Future
|
|
1396
|
+
|
|
1397
|
+
Forge aims to become a complete backend engineering platform.
|
|
1398
|
+
|
|
1399
|
+
One framework.
|
|
1400
|
+
|
|
1401
|
+
Multiple databases.
|
|
1402
|
+
|
|
1403
|
+
Multiple authentication providers.
|
|
1404
|
+
|
|
1405
|
+
Production-ready infrastructure.
|
|
1406
|
+
|
|
1407
|
+
Minimal boilerplate.
|
|
1408
|
+
|
|
1409
|
+
Maximum productivity.
|
|
1410
|
+
|
|
1411
|
+
---
|
|
1412
|
+
|
|
1413
|
+
# Contributing
|
|
1414
|
+
|
|
1415
|
+
Contributions are welcome.
|
|
1416
|
+
|
|
1417
|
+
Whether it's:
|
|
1418
|
+
|
|
1419
|
+
- Bug reports
|
|
1420
|
+
- Feature requests
|
|
1421
|
+
- Documentation improvements
|
|
1422
|
+
- Performance optimizations
|
|
1423
|
+
- New ideas
|
|
1424
|
+
|
|
1425
|
+
Every contribution helps improve Forge.
|
|
1426
|
+
|
|
1427
|
+
Please open an issue before making significant architectural changes so discussions can happen early.
|
|
1428
|
+
|
|
1429
|
+
---
|
|
1430
|
+
|
|
1431
|
+
# Found a Bug?
|
|
1432
|
+
|
|
1433
|
+
If something isn't working as expected:
|
|
1434
|
+
|
|
1435
|
+
1. Check the documentation.
|
|
1436
|
+
2. Search existing issues.
|
|
1437
|
+
3. Create a reproducible example.
|
|
1438
|
+
4. Open a GitHub issue.
|
|
1439
|
+
|
|
1440
|
+
Bug reports with reproduction steps are greatly appreciated.
|
|
1441
|
+
|
|
1442
|
+
---
|
|
1443
|
+
|
|
1444
|
+
# Philosophy in One Sentence
|
|
1445
|
+
|
|
1446
|
+
> **Backend development should be about building products—not rebuilding infrastructure.**
|
|
1447
|
+
|
|
1448
|
+
Everything Forge does exists to support that belief.
|
|
1449
|
+
|
|
1450
|
+
---
|
|
1451
|
+
|
|
1452
|
+
# Credits
|
|
1453
|
+
|
|
1454
|
+
Forge is developed and maintained by **StarkLabs**.
|
|
1455
|
+
|
|
1456
|
+
Built with ❤️ for developers who would rather solve business problems than write the same backend twice.
|
|
1457
|
+
|
|
1458
|
+
---
|
|
1459
|
+
|
|
1460
|
+
# License
|
|
1461
|
+
|
|
1462
|
+
MIT License
|
|
1463
|
+
|
|
1464
|
+
Feel free to use Forge in personal, educational, and commercial projects.
|
|
1465
|
+
|
|
1466
|
+
---
|
|
1467
|
+
|
|
1468
|
+
<div align="center">
|
|
1469
|
+
|
|
1470
|
+
## Build your backend.
|
|
1471
|
+
|
|
1472
|
+
### Not your boilerplate.
|
|
1473
|
+
|
|
1474
|
+
**Forge** ⚒️
|
|
1475
|
+
|
|
1476
|
+
</div>
|