wynkjs 1.0.2 → 1.0.4
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/README.md +401 -112
- package/dist/database.d.ts +1 -1
- package/dist/database.js +1 -1
- package/dist/decorators/exception.advanced.d.ts +286 -18
- package/dist/decorators/exception.advanced.d.ts.map +1 -1
- package/dist/decorators/exception.advanced.js +410 -17
- package/dist/decorators/exception.decorators.d.ts +92 -2
- package/dist/decorators/exception.decorators.d.ts.map +1 -1
- package/dist/decorators/exception.decorators.js +120 -5
- package/dist/decorators/formatter.decorators.d.ts +93 -0
- package/dist/decorators/formatter.decorators.d.ts.map +1 -0
- package/dist/decorators/formatter.decorators.js +131 -0
- package/dist/decorators/guard.decorators.d.ts +2 -2
- package/dist/decorators/http.decorators.d.ts +3 -2
- package/dist/decorators/http.decorators.d.ts.map +1 -1
- package/dist/decorators/pipe.decorators.d.ts +2 -2
- package/dist/decorators/pipe.decorators.d.ts.map +1 -1
- package/dist/decorators/pipe.decorators.js +2 -2
- package/dist/dto.js +1 -1
- package/dist/factory.d.ts +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +55 -6
- package/dist/filters/exception.filters.d.ts +124 -0
- package/dist/filters/exception.filters.d.ts.map +1 -0
- package/dist/filters/exception.filters.js +208 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/pipes/validation.pipe.d.ts +3 -3
- package/dist/pipes/validation.pipe.d.ts.map +1 -1
- package/dist/pipes/validation.pipe.js +39 -11
- package/dist/schema-registry.d.ts +51 -0
- package/dist/schema-registry.d.ts.map +1 -0
- package/dist/schema-registry.js +134 -0
- package/dist/testing/index.d.ts +74 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +106 -0
- package/dist/testing/test-utils.d.ts +31 -0
- package/dist/testing/test-utils.d.ts.map +1 -0
- package/dist/testing/test-utils.js +72 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
**A high-performance TypeScript framework built on Elysia for Bun with
|
|
5
|
+
**A high-performance TypeScript framework built on Elysia for Bun with elegant decorator-based architecture**
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/wynkjs)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
9
|
[](https://www.typescriptlang.org/)
|
|
10
10
|
[](https://bun.sh/)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
_10x faster than Express/NestJs, built for modern TypeScript development on Bun_ ⚡
|
|
13
13
|
|
|
14
14
|
[Quick Start](#-quick-start) • [CLI Tools](#️-cli-tools) • [Features](#-features--examples) • [Documentation](#-documentation)
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ _20x faster than Express, easier than NestJS, built for Bun_ ⚡
|
|
|
19
19
|
|
|
20
20
|
## About
|
|
21
21
|
|
|
22
|
-
WynkJS is a modern, TypeScript-first web framework that brings
|
|
22
|
+
WynkJS is a modern, TypeScript-first web framework that brings elegant decorator-based architecture to the blazing-fast Elysia runtime built for **Bun**. It features familiar concepts—controllers, dependency injection, guards, pipes, interceptors, and exception filters—designed for building high‑performance REST APIs and backends on **Bun**. WynkJS embraces ESM, ships first-class types, and keeps things simple so you can move fast without the bloat.
|
|
23
23
|
|
|
24
24
|
**🚀 Get Started in 30 Seconds:**
|
|
25
25
|
|
|
@@ -35,16 +35,16 @@ Then generate your first API module:
|
|
|
35
35
|
wynkjs g m product # Generate complete CRUD module
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Keywords:
|
|
38
|
+
Keywords: Bun framework, Elysia framework, TypeScript decorators, dependency injection (DI), guards, pipes, interceptors, exception filters, fast web framework, REST API, backend, modern TypeScript.
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
42
|
## ✨ Why WynkJS?
|
|
43
43
|
|
|
44
|
-
WynkJS combines the **speed of Elysia** with
|
|
44
|
+
WynkJS combines the **speed of Elysia** with an **elegant decorator-based architecture**, giving you the best of both worlds:
|
|
45
45
|
|
|
46
46
|
- 🚀 **20x Faster** - Built on Elysia, one of the fastest web frameworks for Bun
|
|
47
|
-
- 🎨 **Decorator-Based** -
|
|
47
|
+
- 🎨 **Decorator-Based** - Clean, intuitive decorator syntax for TypeScript
|
|
48
48
|
- 💉 **Dependency Injection** - Built-in DI (no need to import reflect-metadata!)
|
|
49
49
|
- 🔒 **TypeScript First** - TypeScript is mandatory, not optional. Full type safety and IntelliSense support
|
|
50
50
|
- 🎯 **Simple & Clean** - Easy to learn, powerful to use
|
|
@@ -349,34 +349,31 @@ bun add -D wynkjs-cli
|
|
|
349
349
|
|
|
350
350
|
```bash
|
|
351
351
|
# Generate complete CRUD module (controller + service + DTO)
|
|
352
|
-
wynkjs generate module product
|
|
353
|
-
# or short: wynkjs g m product
|
|
352
|
+
wynkjs-cli generate module product
|
|
353
|
+
# or short: wynkjs-cli g m product
|
|
354
354
|
|
|
355
355
|
# Generate controller only (all HTTP methods)
|
|
356
|
-
wynkjs generate controller user
|
|
357
|
-
# or short: wynkjs g c user
|
|
356
|
+
wynkjs-cli generate controller user
|
|
357
|
+
# or short: wynkjs-cli g c user
|
|
358
358
|
|
|
359
359
|
# Generate service only (all CRUD methods)
|
|
360
|
-
wynkjs generate service order
|
|
361
|
-
# or short: wynkjs g s order
|
|
360
|
+
wynkjs-cli generate service order
|
|
361
|
+
# or short: wynkjs-cli g s order
|
|
362
362
|
|
|
363
363
|
# Generate DTO only (Create, Update, ID DTOs)
|
|
364
|
-
wynkjs generate dto payment
|
|
365
|
-
# or short: wynkjs g d payment
|
|
364
|
+
wynkjs-cli generate dto payment
|
|
365
|
+
# or short: wynkjs-cli g d payment
|
|
366
366
|
```
|
|
367
367
|
|
|
368
368
|
**What it generates:**
|
|
369
369
|
|
|
370
370
|
```bash
|
|
371
|
-
wynkjs g m product
|
|
371
|
+
wynkjs-cli g m product
|
|
372
372
|
# Creates:
|
|
373
373
|
# src/modules/product/
|
|
374
|
-
# ├──
|
|
375
|
-
#
|
|
376
|
-
#
|
|
377
|
-
# │ └── product.service.ts # All CRUD methods
|
|
378
|
-
# └── dto/
|
|
379
|
-
# └── product.dto.ts # Validation schemas
|
|
374
|
+
# ├── product.controller.ts # Full CRUD controller
|
|
375
|
+
# ├── product.service.ts # All CRUD methods
|
|
376
|
+
# └── product.dto.ts # Validation schemas
|
|
380
377
|
```
|
|
381
378
|
|
|
382
379
|
**Auto-imports:** Controllers are automatically imported and added to `src/index.ts`!
|
|
@@ -597,8 +594,6 @@ export class UserService {
|
|
|
597
594
|
|
|
598
595
|
WynkJS provides automatic request validation with **full IntelliSense support** and customizable error formats:
|
|
599
596
|
|
|
600
|
-
> 💡 **New in v1.0.2**: Type `DTO.` and get full autocomplete! See [INTELLISENSE_GUIDE.md](./docs/INTELLISENSE_GUIDE.md)
|
|
601
|
-
|
|
602
597
|
```typescript
|
|
603
598
|
// user.dto.ts
|
|
604
599
|
import { DTO, CommonDTO } from "wynkjs";
|
|
@@ -664,45 +659,147 @@ export class UserController {
|
|
|
664
659
|
|
|
665
660
|
**Customize validation error format:**
|
|
666
661
|
|
|
662
|
+
WynkJS provides three built-in **formatters** for validation errors:
|
|
663
|
+
|
|
667
664
|
```typescript
|
|
668
|
-
import {
|
|
665
|
+
import {
|
|
666
|
+
WynkFactory,
|
|
667
|
+
FormatErrorFormatter, // Object-based { field: ["messages"] }
|
|
668
|
+
SimpleErrorFormatter, // Simple array ["message1", "message2"]
|
|
669
|
+
DetailedErrorFormatter, // Detailed with field info
|
|
670
|
+
} from "wynkjs";
|
|
669
671
|
|
|
670
672
|
const app = WynkFactory.create({
|
|
671
673
|
controllers: [UserController],
|
|
672
674
|
// Choose your validation error format
|
|
673
|
-
validationErrorFormatter: new
|
|
674
|
-
// validationErrorFormatter: new SimpleErrorFormatter(), // Simple array
|
|
675
|
-
// validationErrorFormatter: new DetailedErrorFormatter(), // Detailed with paths
|
|
675
|
+
validationErrorFormatter: new DetailedErrorFormatter(), // ✅ Recommended
|
|
676
676
|
});
|
|
677
|
+
```
|
|
677
678
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
679
|
+
**Available formatters:**
|
|
680
|
+
|
|
681
|
+
1. **FormatErrorFormatter** (Object-based):
|
|
682
|
+
|
|
683
|
+
```json
|
|
684
|
+
{
|
|
685
|
+
"statusCode": 400,
|
|
686
|
+
"message": "Validation failed",
|
|
687
|
+
"errors": {
|
|
688
|
+
"email": ["Invalid email address"],
|
|
689
|
+
"age": ["Must be at least 18"]
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
2. **SimpleErrorFormatter** (Simple array):
|
|
695
|
+
|
|
696
|
+
```json
|
|
697
|
+
{
|
|
698
|
+
"statusCode": 400,
|
|
699
|
+
"message": "Validation failed",
|
|
700
|
+
"errors": ["Invalid email address", "Must be at least 18"]
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
3. **DetailedErrorFormatter** (Detailed):
|
|
705
|
+
```json
|
|
706
|
+
{
|
|
707
|
+
"statusCode": 400,
|
|
708
|
+
"message": "Validation failed",
|
|
709
|
+
"errors": [
|
|
710
|
+
{
|
|
711
|
+
"field": "email",
|
|
712
|
+
"message": "Invalid email address",
|
|
713
|
+
"value": "invalid-email"
|
|
714
|
+
}
|
|
715
|
+
]
|
|
716
|
+
}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Note:** Formatters are for **validation errors only** (from DTO validation). For runtime exception handling, use **exception filters** - see [Exception Handling](#-exception-handling) section.
|
|
720
|
+
|
|
721
|
+
**See [docs-wynkjs/VALIDATION_FORMATTERS.md](./docs-wynkjs/VALIDATION_FORMATTERS.md) for all available error formats**
|
|
722
|
+
|
|
723
|
+
### ✨ Custom Validation Error Messages
|
|
724
|
+
|
|
725
|
+
WynkJS supports custom error messages at the DTO level using the `error` or `errorMessage` property. This allows you to provide user-friendly error messages instead of the default TypeBox validation messages:
|
|
689
726
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
727
|
+
```typescript
|
|
728
|
+
// user.dto.ts
|
|
729
|
+
import { DTO, CommonDTO } from "wynkjs";
|
|
730
|
+
|
|
731
|
+
export const CreateUserDTO = DTO.Strict({
|
|
732
|
+
name: DTO.String({
|
|
733
|
+
minLength: 2,
|
|
734
|
+
maxLength: 50,
|
|
735
|
+
error: "Name must be between 2 and 50 characters", // ✨ Custom message
|
|
736
|
+
}),
|
|
737
|
+
email: CommonDTO.Email({
|
|
738
|
+
error: "Invalid email address", // ✨ Custom message
|
|
739
|
+
}),
|
|
740
|
+
mobile: DTO.String({
|
|
741
|
+
pattern: "^[6-9]{1}[0-9]{9}$",
|
|
742
|
+
error: "Invalid mobile number", // ✨ Custom message
|
|
743
|
+
}),
|
|
744
|
+
age: DTO.Number({
|
|
745
|
+
minimum: 18,
|
|
746
|
+
error: "You must be at least 18 years old", // ✨ Custom message
|
|
747
|
+
}),
|
|
699
748
|
});
|
|
700
749
|
```
|
|
701
750
|
|
|
702
|
-
**
|
|
751
|
+
**Example response with invalid data:**
|
|
752
|
+
|
|
753
|
+
```bash
|
|
754
|
+
curl -X POST http://localhost:3000/users \
|
|
755
|
+
-H "Content-Type: application/json" \
|
|
756
|
+
-d '{"name":"A","email":"invalid","mobile":"1234567890","age":15}'
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
**Response:**
|
|
760
|
+
|
|
761
|
+
```json
|
|
762
|
+
{
|
|
763
|
+
"statusCode": 400,
|
|
764
|
+
"message": "Validation failed",
|
|
765
|
+
"errors": [
|
|
766
|
+
{ "field": "name", "message": "Name must be between 2 and 50 characters" },
|
|
767
|
+
{ "field": "email", "message": "Invalid email address" },
|
|
768
|
+
{ "field": "mobile", "message": "Invalid mobile number" },
|
|
769
|
+
{ "field": "age", "message": "You must be at least 18 years old" }
|
|
770
|
+
]
|
|
771
|
+
}
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
**Without custom messages, you would get generic TypeBox messages:**
|
|
775
|
+
|
|
776
|
+
```json
|
|
777
|
+
{
|
|
778
|
+
"errors": [
|
|
779
|
+
{
|
|
780
|
+
"field": "name",
|
|
781
|
+
"message": "Expected string length greater or equal to 2"
|
|
782
|
+
},
|
|
783
|
+
{ "field": "email", "message": "Expected string to match email format" },
|
|
784
|
+
{
|
|
785
|
+
"field": "mobile",
|
|
786
|
+
"message": "Expected string to match '^[6-9]{1}[0-9]{9}$'"
|
|
787
|
+
},
|
|
788
|
+
{ "field": "age", "message": "Expected number greater or equal to 18" }
|
|
789
|
+
]
|
|
790
|
+
}
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
**Note:** You can use either `error` or `errorMessage` property - both work the same way.
|
|
703
794
|
|
|
704
795
|
### 🚫 Exception Handling
|
|
705
796
|
|
|
797
|
+
WynkJS provides a powerful exception handling system with **formatters** for validation errors and **filters** for runtime exceptions.
|
|
798
|
+
|
|
799
|
+
#### Exception Classes
|
|
800
|
+
|
|
801
|
+
Throw HTTP exceptions anywhere in your code:
|
|
802
|
+
|
|
706
803
|
```typescript
|
|
707
804
|
import { Controller, Get, Param, NotFoundException } from "wynkjs";
|
|
708
805
|
|
|
@@ -726,7 +823,101 @@ export class UserController {
|
|
|
726
823
|
- `UnauthorizedException` - 401
|
|
727
824
|
- `ForbiddenException` - 403
|
|
728
825
|
- `NotFoundException` - 404
|
|
826
|
+
- `ConflictException` - 409
|
|
729
827
|
- `InternalServerErrorException` - 500
|
|
828
|
+
- And many more...
|
|
829
|
+
|
|
830
|
+
#### Validation Error Formatting
|
|
831
|
+
|
|
832
|
+
Format validation errors using **formatters** (passed to factory options):
|
|
833
|
+
|
|
834
|
+
```typescript
|
|
835
|
+
import { WynkFactory, DetailedErrorFormatter } from "wynkjs";
|
|
836
|
+
|
|
837
|
+
const app = WynkFactory.create({
|
|
838
|
+
controllers: [UserController],
|
|
839
|
+
validationErrorFormatter: new DetailedErrorFormatter(), // ✅ For validation
|
|
840
|
+
});
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
**Available formatters:**
|
|
844
|
+
|
|
845
|
+
- `FormatErrorFormatter` - Object format `{ field: ["messages"] }`
|
|
846
|
+
- `SimpleErrorFormatter` - Simple array `["message1", "message2"]`
|
|
847
|
+
- `DetailedErrorFormatter` - Detailed with field info
|
|
848
|
+
|
|
849
|
+
#### Global Exception Filters
|
|
850
|
+
|
|
851
|
+
Handle runtime exceptions using **global filters**:
|
|
852
|
+
|
|
853
|
+
```typescript
|
|
854
|
+
import {
|
|
855
|
+
WynkFactory,
|
|
856
|
+
DatabaseExceptionFilter,
|
|
857
|
+
NotFoundExceptionFilter,
|
|
858
|
+
GlobalExceptionFilter,
|
|
859
|
+
} from "wynkjs";
|
|
860
|
+
|
|
861
|
+
const app = WynkFactory.create({
|
|
862
|
+
controllers: [UserController],
|
|
863
|
+
validationErrorFormatter: new DetailedErrorFormatter(),
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
// Register global exception filters
|
|
867
|
+
app.useGlobalFilters(
|
|
868
|
+
new DatabaseExceptionFilter(), // Handles database errors
|
|
869
|
+
new NotFoundExceptionFilter(), // Smart 404 handling with response data checking
|
|
870
|
+
new GlobalExceptionFilter() // Catch-all for other exceptions
|
|
871
|
+
);
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
**Available global filters:**
|
|
875
|
+
|
|
876
|
+
- `DatabaseExceptionFilter` - Catches database errors (unique constraints, foreign keys, etc.)
|
|
877
|
+
- `NotFoundExceptionFilter` - Smart filter that only formats truly empty 404 responses
|
|
878
|
+
- `FileUploadExceptionFilter` - Handles file upload errors
|
|
879
|
+
- `GlobalExceptionFilter` - Catch-all for unhandled exceptions
|
|
880
|
+
|
|
881
|
+
**What's the difference?**
|
|
882
|
+
|
|
883
|
+
| Feature | Formatters | Filters |
|
|
884
|
+
| ---------------- | -------------------------------------------------- | -------------------------- |
|
|
885
|
+
| **Purpose** | Format validation errors | Handle runtime exceptions |
|
|
886
|
+
| **When?** | During request validation (TypeBox/Elysia) | When exceptions are thrown |
|
|
887
|
+
| **Registration** | `WynkFactory.create({ validationErrorFormatter })` | `app.useGlobalFilters()` |
|
|
888
|
+
| **Example** | `FormatErrorFormatter` | `DatabaseExceptionFilter` |
|
|
889
|
+
|
|
890
|
+
#### Custom Exception Filters
|
|
891
|
+
|
|
892
|
+
Create your own filters for specific routes:
|
|
893
|
+
|
|
894
|
+
```typescript
|
|
895
|
+
import { WynkExceptionFilter, ExecutionContext, Catch } from "wynkjs";
|
|
896
|
+
|
|
897
|
+
@Catch() // Catches all exceptions
|
|
898
|
+
export class CustomExceptionFilter implements WynkExceptionFilter {
|
|
899
|
+
catch(exception: any, context: ExecutionContext) {
|
|
900
|
+
const request = context.getRequest();
|
|
901
|
+
|
|
902
|
+
return {
|
|
903
|
+
statusCode: exception.statusCode || 500,
|
|
904
|
+
message: exception.message,
|
|
905
|
+
timestamp: new Date().toISOString(),
|
|
906
|
+
path: request.url,
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// Use globally
|
|
912
|
+
app.useGlobalFilters(new CustomExceptionFilter());
|
|
913
|
+
|
|
914
|
+
// Or on specific controllers/routes
|
|
915
|
+
@UseFilters(CustomExceptionFilter)
|
|
916
|
+
@Controller("/api")
|
|
917
|
+
export class ApiController {}
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
**See [ARCHITECTURE.md](./ARCHITECTURE.md) for complete architecture details**
|
|
730
921
|
|
|
731
922
|
### 🔄 Multiple Params and Query Validation
|
|
732
923
|
|
|
@@ -792,22 +983,38 @@ export class ApiController {
|
|
|
792
983
|
|
|
793
984
|
## 🏗️ Project Structure
|
|
794
985
|
|
|
986
|
+
Recommended project structure for WynkJS applications:
|
|
987
|
+
|
|
795
988
|
```
|
|
796
989
|
my-wynk-app/
|
|
797
990
|
├── src/
|
|
798
|
-
│ ├──
|
|
799
|
-
│ │
|
|
800
|
-
│ ├──
|
|
801
|
-
│ │
|
|
802
|
-
│
|
|
803
|
-
│ │ └──
|
|
991
|
+
│ ├── modules/
|
|
992
|
+
│ │ ├── user/
|
|
993
|
+
│ │ │ ├── user.controller.ts
|
|
994
|
+
│ │ │ ├── user.service.ts
|
|
995
|
+
│ │ │ └── user.dto.ts
|
|
996
|
+
│ │ └── product/
|
|
997
|
+
│ │ ├── product.controller.ts
|
|
998
|
+
│ │ ├── product.service.ts
|
|
999
|
+
│ │ └── product.dto.ts
|
|
804
1000
|
│ ├── exceptions/
|
|
805
|
-
│ │ └──
|
|
1001
|
+
│ │ └── custom.exceptions.ts
|
|
1002
|
+
│ ├── guards/
|
|
1003
|
+
│ │ └── auth.guard.ts
|
|
1004
|
+
│ ├── filters/
|
|
1005
|
+
│ │ └── http-exception.filter.ts
|
|
806
1006
|
│ └── index.ts
|
|
807
1007
|
├── package.json
|
|
808
1008
|
└── tsconfig.json
|
|
809
1009
|
```
|
|
810
1010
|
|
|
1011
|
+
**Module-based Organization:**
|
|
1012
|
+
|
|
1013
|
+
- Each feature/domain lives in its own module folder
|
|
1014
|
+
- Controllers, services, and DTOs are co-located
|
|
1015
|
+
- Easy to navigate and maintain
|
|
1016
|
+
- Generated automatically by `wynkjs-cli`
|
|
1017
|
+
|
|
811
1018
|
---
|
|
812
1019
|
|
|
813
1020
|
## 🎨 Complete Working Example
|
|
@@ -901,13 +1108,25 @@ export class UserController {
|
|
|
901
1108
|
}
|
|
902
1109
|
|
|
903
1110
|
// index.ts
|
|
904
|
-
import {
|
|
1111
|
+
import {
|
|
1112
|
+
WynkFactory,
|
|
1113
|
+
DetailedErrorFormatter,
|
|
1114
|
+
GlobalExceptionFilter,
|
|
1115
|
+
DatabaseExceptionFilter,
|
|
1116
|
+
} from "wynkjs";
|
|
905
1117
|
import { UserController } from "./controllers/user.controller";
|
|
906
1118
|
|
|
907
1119
|
const app = WynkFactory.create({
|
|
908
1120
|
controllers: [UserController],
|
|
1121
|
+
validationErrorFormatter: new DetailedErrorFormatter(), // ✅ Format validation errors
|
|
909
1122
|
});
|
|
910
1123
|
|
|
1124
|
+
// Register global exception filters
|
|
1125
|
+
app.useGlobalFilters(
|
|
1126
|
+
new DatabaseExceptionFilter(), // Handles database errors
|
|
1127
|
+
new GlobalExceptionFilter() // Catch-all for other exceptions
|
|
1128
|
+
);
|
|
1129
|
+
|
|
911
1130
|
await app.listen(3000);
|
|
912
1131
|
console.log("🚀 Server running on http://localhost:3000");
|
|
913
1132
|
```
|
|
@@ -1049,12 +1268,11 @@ npx create-wynkjs
|
|
|
1049
1268
|
```
|
|
1050
1269
|
my-wynkjs-app/
|
|
1051
1270
|
├── src/
|
|
1052
|
-
│ ├──
|
|
1053
|
-
│ │ └── user
|
|
1054
|
-
│ ├──
|
|
1055
|
-
│ │
|
|
1056
|
-
│
|
|
1057
|
-
│ │ └── user.dto.ts
|
|
1271
|
+
│ ├── modules/
|
|
1272
|
+
│ │ └── user/
|
|
1273
|
+
│ │ ├── user.controller.ts
|
|
1274
|
+
│ │ ├── user.service.ts
|
|
1275
|
+
│ │ └── user.dto.ts
|
|
1058
1276
|
│ └── index.ts
|
|
1059
1277
|
├── .eslintrc.json
|
|
1060
1278
|
├── .prettierrc
|
|
@@ -1074,12 +1292,13 @@ my-wynkjs-app/
|
|
|
1074
1292
|
|
|
1075
1293
|
---
|
|
1076
1294
|
|
|
1077
|
-
##
|
|
1295
|
+
## 🔗 Resources
|
|
1078
1296
|
|
|
1079
1297
|
- 📚 [Full Documentation](https://github.com/wynkjs/wynkjs-core)
|
|
1298
|
+
- 🏗️ [Architecture Guide](./ARCHITECTURE.md) - **NEW!** Complete guide to formatters vs filters
|
|
1299
|
+
- 🔄 [Migration Guide](./MIGRATION.md) - Upgrading from older versions
|
|
1080
1300
|
- 🚀 [CLI Tool (create-wynkjs)](./packages/create-wynkjs/README.md)
|
|
1081
|
-
-
|
|
1082
|
-
- 🎨 [Validation Formatters](./VALIDATION_FORMATTERS.md)
|
|
1301
|
+
- 🎨 [Validation Formatters](./docs-wynkjs/VALIDATION_FORMATTERS.md)
|
|
1083
1302
|
- 📝 [Changelog](./CHANGELOG.md)
|
|
1084
1303
|
- 🐛 [Report Issues](https://github.com/wynkjs/wynkjs-core/issues)
|
|
1085
1304
|
|
|
@@ -1087,83 +1306,153 @@ my-wynkjs-app/
|
|
|
1087
1306
|
|
|
1088
1307
|
## 🤝 Contributing
|
|
1089
1308
|
|
|
1090
|
-
|
|
1309
|
+
We welcome contributions from the community! Whether you're fixing bugs, improving documentation, or proposing new features, your help is appreciated.
|
|
1091
1310
|
|
|
1092
|
-
|
|
1311
|
+
### 🐛 Reporting Issues
|
|
1093
1312
|
|
|
1094
|
-
|
|
1313
|
+
If you find a bug or have a feature request:
|
|
1095
1314
|
|
|
1096
|
-
|
|
1315
|
+
1. **Check existing issues** to avoid duplicates
|
|
1316
|
+
2. **Create a new issue** with a clear title and description
|
|
1317
|
+
3. **Provide details**: Steps to reproduce, expected behavior, actual behavior
|
|
1318
|
+
4. **Include environment info**: Bun version, OS, WynkJS version
|
|
1097
1319
|
|
|
1098
|
-
|
|
1320
|
+
[Report an issue →](https://github.com/wynkjs/wynkjs-core/issues)
|
|
1099
1321
|
|
|
1100
|
-
|
|
1322
|
+
### 💡 Contributing Code
|
|
1101
1323
|
|
|
1102
|
-
|
|
1103
|
-
- `globalGuards?: Array<Guard>` - Global guards (optional)
|
|
1104
|
-
- `globalInterceptors?: Array<Interceptor>` - Global interceptors (optional)
|
|
1105
|
-
- `globalPipes?: Array<Pipe>` - Global pipes (optional)
|
|
1106
|
-
- `globalFilters?: Array<Filter>` - Global exception filters (optional)
|
|
1324
|
+
#### Getting Started
|
|
1107
1325
|
|
|
1108
|
-
**
|
|
1326
|
+
1. **Fork the repository**
|
|
1109
1327
|
|
|
1110
|
-
|
|
1328
|
+
```bash
|
|
1329
|
+
# Fork on GitHub, then clone your fork
|
|
1330
|
+
git clone https://github.com/YOUR_USERNAME/wynkjs-core.git
|
|
1331
|
+
cd wynkjs-core
|
|
1332
|
+
```
|
|
1111
1333
|
|
|
1112
|
-
|
|
1334
|
+
2. **Install dependencies**
|
|
1113
1335
|
|
|
1114
|
-
|
|
1336
|
+
```bash
|
|
1337
|
+
bun install
|
|
1338
|
+
```
|
|
1115
1339
|
|
|
1116
|
-
|
|
1340
|
+
3. **Build the packages**
|
|
1117
1341
|
|
|
1118
|
-
|
|
1342
|
+
```bash
|
|
1343
|
+
# Build main framework
|
|
1344
|
+
bun run build
|
|
1119
1345
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
| Fastify | ~45,000 | ~2.2ms |
|
|
1125
|
-
| Express | ~12,000 | ~8.3ms |
|
|
1346
|
+
# Build CLI tools
|
|
1347
|
+
cd packages/create-wynkjs && bun run build
|
|
1348
|
+
cd ../wynkjs-cli && bun run build
|
|
1349
|
+
```
|
|
1126
1350
|
|
|
1127
|
-
|
|
1351
|
+
4. **Create a branch**
|
|
1352
|
+
```bash
|
|
1353
|
+
git checkout -b feature/your-feature-name
|
|
1354
|
+
# or
|
|
1355
|
+
git checkout -b fix/bug-description
|
|
1356
|
+
```
|
|
1128
1357
|
|
|
1129
|
-
|
|
1358
|
+
#### Development Workflow
|
|
1130
1359
|
|
|
1131
|
-
|
|
1360
|
+
1. **Make your changes** in the appropriate package:
|
|
1132
1361
|
|
|
1133
|
-
|
|
1362
|
+
- `core/` - Core framework decorators and utilities
|
|
1363
|
+
- `packages/create-wynkjs/` - Project scaffolding CLI
|
|
1364
|
+
- `packages/wynkjs-cli/` - Code generator CLI
|
|
1134
1365
|
|
|
1135
|
-
|
|
1366
|
+
2. **Test your changes**
|
|
1136
1367
|
|
|
1137
|
-
|
|
1368
|
+
```bash
|
|
1369
|
+
# Test in the example project
|
|
1370
|
+
cd example
|
|
1371
|
+
bun run dev
|
|
1138
1372
|
|
|
1139
|
-
|
|
1373
|
+
# Test CLI generation
|
|
1374
|
+
cd /tmp && bunx /path/to/wynkjs-core/packages/create-wynkjs
|
|
1375
|
+
```
|
|
1140
1376
|
|
|
1141
|
-
|
|
1377
|
+
3. **Build all packages**
|
|
1142
1378
|
|
|
1143
|
-
|
|
1379
|
+
```bash
|
|
1380
|
+
# From project root
|
|
1381
|
+
bun run build
|
|
1382
|
+
cd packages/create-wynkjs && bun run build
|
|
1383
|
+
cd ../wynkjs-cli && bun run build
|
|
1384
|
+
```
|
|
1144
1385
|
|
|
1145
|
-
|
|
1146
|
-
- [Issue Tracker](https://github.com/alamjamal/wynkjs/issues)
|
|
1147
|
-
- [Elysia Documentation](https://elysiajs.com/)
|
|
1148
|
-
- [TypeScript Decorators](https://www.typescriptlang.org/docs/handbook/decorators.html)
|
|
1386
|
+
4. **Commit your changes**
|
|
1149
1387
|
|
|
1150
|
-
|
|
1388
|
+
```bash
|
|
1389
|
+
git add .
|
|
1390
|
+
git commit -m "feat: add new feature"
|
|
1391
|
+
# or
|
|
1392
|
+
git commit -m "fix: resolve issue with decorators"
|
|
1393
|
+
```
|
|
1151
1394
|
|
|
1152
|
-
|
|
1395
|
+
**Commit Convention:**
|
|
1153
1396
|
|
|
1154
|
-
|
|
1397
|
+
- `feat:` - New feature
|
|
1398
|
+
- `fix:` - Bug fix
|
|
1399
|
+
- `docs:` - Documentation changes
|
|
1400
|
+
- `refactor:` - Code refactoring
|
|
1401
|
+
- `test:` - Adding tests
|
|
1402
|
+
- `chore:` - Maintenance tasks
|
|
1155
1403
|
|
|
1156
|
-
|
|
1157
|
-
- [tsyringe](https://github.com/microsoft/tsyringe) - Dependency injection
|
|
1158
|
-
- [TypeScript](https://www.typescriptlang.org/) - Type safety
|
|
1404
|
+
5. **Push and create a Pull Request**
|
|
1159
1405
|
|
|
1160
|
-
|
|
1406
|
+
```bash
|
|
1407
|
+
git push origin feature/your-feature-name
|
|
1408
|
+
```
|
|
1161
1409
|
|
|
1162
|
-
|
|
1410
|
+
Then open a Pull Request on GitHub with:
|
|
1163
1411
|
|
|
1164
|
-
|
|
1412
|
+
- Clear description of changes
|
|
1413
|
+
- Link to related issues
|
|
1414
|
+
- Screenshots/examples if applicable
|
|
1165
1415
|
|
|
1166
|
-
|
|
1416
|
+
#### Code Style
|
|
1417
|
+
|
|
1418
|
+
- **TypeScript**: Strict mode enabled
|
|
1419
|
+
- **Formatting**: Use Prettier (run `bun run format` if available)
|
|
1420
|
+
- **Linting**: Follow ESLint rules
|
|
1421
|
+
- **Naming**:
|
|
1422
|
+
- PascalCase for classes and interfaces
|
|
1423
|
+
- camelCase for functions and variables
|
|
1424
|
+
- kebab-case for file names
|
|
1425
|
+
|
|
1426
|
+
#### Testing Guidelines
|
|
1427
|
+
|
|
1428
|
+
- Test your changes in the `example/` directory
|
|
1429
|
+
- Ensure existing examples still work
|
|
1430
|
+
- Add new examples for new features
|
|
1431
|
+
- Test CLI tools in a fresh directory
|
|
1432
|
+
|
|
1433
|
+
### 📝 Documentation
|
|
1434
|
+
|
|
1435
|
+
Documentation improvements are always welcome!
|
|
1436
|
+
|
|
1437
|
+
- **README updates**: Keep examples current and clear
|
|
1438
|
+
- **Code comments**: Add JSDoc comments for public APIs
|
|
1439
|
+
- **Guides**: Create helpful guides in `docs-wynkjs/`
|
|
1440
|
+
- **Examples**: Add real-world usage examples
|
|
1441
|
+
|
|
1442
|
+
### 💬 Community
|
|
1443
|
+
|
|
1444
|
+
- **GitHub Discussions**: Ask questions and share ideas
|
|
1445
|
+
- **Discord**: (Coming soon) Join our community chat
|
|
1446
|
+
- **Twitter**: Follow [@wynkjs](https://twitter.com/wynkjs) for updates
|
|
1447
|
+
|
|
1448
|
+
### 📜 License
|
|
1449
|
+
|
|
1450
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
1451
|
+
|
|
1452
|
+
---
|
|
1453
|
+
|
|
1454
|
+
**Thank you for contributing to WynkJS! 🎉**
|
|
1455
|
+
|
|
1456
|
+
```
|
|
1167
1457
|
|
|
1168
|
-
</div>
|
|
1169
1458
|
```
|