wynkjs 1.0.3 → 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.
Files changed (37) hide show
  1. package/README.md +252 -55
  2. package/dist/database.d.ts +1 -1
  3. package/dist/database.js +1 -1
  4. package/dist/decorators/exception.advanced.d.ts +286 -18
  5. package/dist/decorators/exception.advanced.d.ts.map +1 -1
  6. package/dist/decorators/exception.advanced.js +410 -17
  7. package/dist/decorators/exception.decorators.d.ts +92 -2
  8. package/dist/decorators/exception.decorators.d.ts.map +1 -1
  9. package/dist/decorators/exception.decorators.js +120 -5
  10. package/dist/decorators/formatter.decorators.d.ts +93 -0
  11. package/dist/decorators/formatter.decorators.d.ts.map +1 -0
  12. package/dist/decorators/formatter.decorators.js +131 -0
  13. package/dist/decorators/guard.decorators.d.ts +2 -2
  14. package/dist/decorators/http.decorators.d.ts +3 -2
  15. package/dist/decorators/http.decorators.d.ts.map +1 -1
  16. package/dist/decorators/pipe.decorators.d.ts +2 -2
  17. package/dist/decorators/pipe.decorators.d.ts.map +1 -1
  18. package/dist/decorators/pipe.decorators.js +2 -2
  19. package/dist/dto.js +1 -1
  20. package/dist/factory.d.ts +1 -1
  21. package/dist/factory.d.ts.map +1 -1
  22. package/dist/factory.js +55 -6
  23. package/dist/filters/exception.filters.d.ts +124 -0
  24. package/dist/filters/exception.filters.d.ts.map +1 -0
  25. package/dist/filters/exception.filters.js +208 -0
  26. package/dist/index.d.ts +3 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -1
  29. package/dist/pipes/validation.pipe.d.ts +3 -3
  30. package/dist/pipes/validation.pipe.d.ts.map +1 -1
  31. package/dist/pipes/validation.pipe.js +39 -11
  32. package/dist/schema-registry.d.ts +51 -0
  33. package/dist/schema-registry.d.ts.map +1 -0
  34. package/dist/schema-registry.js +134 -0
  35. package/dist/testing/index.d.ts +2 -2
  36. package/dist/testing/index.js +2 -2
  37. 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 NestJS-style decorators**
5
+ **A high-performance TypeScript framework built on Elysia for Bun with elegant decorator-based architecture**
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/wynkjs.svg)](https://www.npmjs.com/package/wynkjs)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
10
10
  [![Bun](https://img.shields.io/badge/Bun-1.0+-black.svg)](https://bun.sh/)
11
11
 
12
- _20x faster than Express, easier than NestJS, built for Bun_ ⚡
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 NestJS-style decorators to the blazing-fast Elysia runtime built for **Bun**. It's a lightweight NestJS alternative with 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.
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: NestJS alternative, Elysia framework, Bun framework, TypeScript decorators, dependency injection (DI), guards, pipes, interceptors, exception filters, fast web framework, REST API, backend.
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 the **elegant decorator syntax of NestJS**, giving you the best of both worlds:
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** - Familiar NestJS-style decorators
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,26 +349,26 @@ 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
374
  # ├── product.controller.ts # Full CRUD controller
@@ -659,45 +659,147 @@ export class UserController {
659
659
 
660
660
  **Customize validation error format:**
661
661
 
662
+ WynkJS provides three built-in **formatters** for validation errors:
663
+
662
664
  ```typescript
663
- import { WynkFactory, FormatErrorFormatter } from "wynkjs";
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";
664
671
 
665
672
  const app = WynkFactory.create({
666
673
  controllers: [UserController],
667
674
  // Choose your validation error format
668
- validationErrorFormatter: new FormatErrorFormatter(), // NestJS-style (recommended)
669
- // validationErrorFormatter: new SimpleErrorFormatter(), // Simple array
670
- // validationErrorFormatter: new DetailedErrorFormatter(), // Detailed with paths
675
+ validationErrorFormatter: new DetailedErrorFormatter(), // Recommended
671
676
  });
677
+ ```
672
678
 
673
- @Controller("/users")
674
- export class UserController {
675
- @Post({
676
- path: "/",
677
- body: CreateUserDTO,
678
- })
679
- async create(@Body() body: any) {
680
- // Body is automatically validated!
681
- return { message: "User created", data: body };
682
- }
683
- }
679
+ **Available formatters:**
684
680
 
685
- // Choose your validation error format
686
- const app = WynkFactory.create({
687
- controllers: [UserController],
688
- // Option 1: Default format (recommended)
689
- // validationErrorFormatter: new FormatErrorFormatter(), // NestJS-style
690
- // Option 2: Simple array format
691
- // validationErrorFormatter: new SimpleErrorFormatter(),
692
- // Option 3: Detailed format with field info
693
- // validationErrorFormatter: new DetailedErrorFormatter(),
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:
726
+
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
+ }),
694
748
  });
695
749
  ```
696
750
 
697
- **See [VALIDATION_FORMATTERS.md](./docs-wynkjs/VALIDATION_FORMATTERS.md) for all available error formats**
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.
698
794
 
699
795
  ### 🚫 Exception Handling
700
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
+
701
803
  ```typescript
702
804
  import { Controller, Get, Param, NotFoundException } from "wynkjs";
703
805
 
@@ -721,7 +823,101 @@ export class UserController {
721
823
  - `UnauthorizedException` - 401
722
824
  - `ForbiddenException` - 403
723
825
  - `NotFoundException` - 404
826
+ - `ConflictException` - 409
724
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**
725
921
 
726
922
  ### 🔄 Multiple Params and Query Validation
727
923
 
@@ -912,13 +1108,25 @@ export class UserController {
912
1108
  }
913
1109
 
914
1110
  // index.ts
915
- import { WynkFactory } from "wynkjs";
1111
+ import {
1112
+ WynkFactory,
1113
+ DetailedErrorFormatter,
1114
+ GlobalExceptionFilter,
1115
+ DatabaseExceptionFilter,
1116
+ } from "wynkjs";
916
1117
  import { UserController } from "./controllers/user.controller";
917
1118
 
918
1119
  const app = WynkFactory.create({
919
1120
  controllers: [UserController],
1121
+ validationErrorFormatter: new DetailedErrorFormatter(), // ✅ Format validation errors
920
1122
  });
921
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
+
922
1130
  await app.listen(3000);
923
1131
  console.log("🚀 Server running on http://localhost:3000");
924
1132
  ```
@@ -1084,9 +1292,11 @@ my-wynkjs-app/
1084
1292
 
1085
1293
  ---
1086
1294
 
1087
- ## �🔗 Resources
1295
+ ## 🔗 Resources
1088
1296
 
1089
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
1090
1300
  - 🚀 [CLI Tool (create-wynkjs)](./packages/create-wynkjs/README.md)
1091
1301
  - 🎨 [Validation Formatters](./docs-wynkjs/VALIDATION_FORMATTERS.md)
1092
1302
  - 📝 [Changelog](./CHANGELOG.md)
@@ -1229,19 +1439,6 @@ Documentation improvements are always welcome!
1229
1439
  - **Guides**: Create helpful guides in `docs-wynkjs/`
1230
1440
  - **Examples**: Add real-world usage examples
1231
1441
 
1232
- ### 🚀 Release Process (Maintainers)
1233
-
1234
- 1. Update `CHANGELOG.md` with changes
1235
- 2. Bump version in `package.json` files
1236
- 3. Build all packages
1237
- 4. Commit and tag the release
1238
- 5. Publish to npm:
1239
- ```bash
1240
- npm publish --access public
1241
- cd packages/create-wynkjs && npm publish --access public
1242
- cd ../wynkjs-cli && npm publish --access public
1243
- ```
1244
-
1245
1442
  ### 💬 Community
1246
1443
 
1247
1444
  - **GitHub Discussions**: Ask questions and share ideas
@@ -5,7 +5,7 @@
5
5
  * It's just an example pattern you can COPY to your project and customize.
6
6
  *
7
7
  * WHY NOT INCLUDED IN CORE?
8
- * - Keeps WynkJS lightweight and fast (20x faster than NestJS!)
8
+ * - Keeps WynkJS lightweight and fast (built on Elysia's performance)
9
9
  * - Gives you freedom to use ANY database library (Drizzle, Prisma, TypeORM, Mongoose, etc.)
10
10
  * - No vendor lock-in
11
11
  * - No unnecessary dependencies
package/dist/database.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * It's just an example pattern you can COPY to your project and customize.
6
6
  *
7
7
  * WHY NOT INCLUDED IN CORE?
8
- * - Keeps WynkJS lightweight and fast (20x faster than NestJS!)
8
+ * - Keeps WynkJS lightweight and fast (built on Elysia's performance)
9
9
  * - Gives you freedom to use ANY database library (Drizzle, Prisma, TypeORM, Mongoose, etc.)
10
10
  * - No vendor lock-in
11
11
  * - No unnecessary dependencies