@zenofolio/hyper-decor 1.0.4 → 1.0.8

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 (189) hide show
  1. package/.agent/rules/philosophy.md +103 -0
  2. package/.agent/rules/writing.md +32 -0
  3. package/README.md +107 -142
  4. package/dist/__internals/constants.d.ts +1 -58
  5. package/dist/__internals/constants.js +3 -65
  6. package/dist/__internals/helpers/lifecycle.helper.d.ts +3 -0
  7. package/dist/__internals/helpers/lifecycle.helper.js +25 -0
  8. package/dist/__internals/helpers/merge-metadata.d.ts +2 -3
  9. package/dist/__internals/helpers/merge-metadata.js +43 -23
  10. package/dist/__internals/helpers/prepare.helper.d.ts +5 -0
  11. package/dist/__internals/helpers/prepare.helper.js +392 -0
  12. package/dist/__internals/stores/hyper.store.d.ts +5 -0
  13. package/dist/__internals/stores/hyper.store.js +5 -0
  14. package/dist/__internals/stores/index.d.ts +4 -15
  15. package/dist/__internals/stores/index.js +18 -35
  16. package/dist/__internals/stores/meta.store.d.ts +34 -0
  17. package/dist/__internals/stores/meta.store.js +107 -0
  18. package/dist/__internals/stores/scope.store.d.ts +14 -0
  19. package/dist/__internals/stores/scope.store.js +29 -0
  20. package/dist/__internals/stores/serivces.store.d.ts +1 -0
  21. package/dist/__internals/stores/{store.interface.js → serivces.store.js} +2 -0
  22. package/dist/__internals/transform/middleware.transform.d.ts +3 -0
  23. package/dist/__internals/transform/middleware.transform.js +19 -0
  24. package/dist/__internals/transform/role.transform.d.ts +1 -1
  25. package/dist/__internals/transform/role.transform.js +10 -7
  26. package/dist/__internals/transform/scope.transfrom.d.ts +5 -7
  27. package/dist/__internals/transform/scope.transfrom.js +53 -39
  28. package/dist/__internals/transform/transform.registry.d.ts +33 -0
  29. package/dist/__internals/transform/transform.registry.js +59 -0
  30. package/dist/__internals/types.d.ts +53 -4
  31. package/dist/__internals/utils/function.util.d.ts +1 -4
  32. package/dist/__internals/utils/function.util.js +22 -10
  33. package/dist/common/bootstrap.d.ts +6 -2
  34. package/dist/common/bootstrap.js +51 -8
  35. package/dist/common/helpers/index.d.ts +1 -0
  36. package/dist/common/helpers/index.js +1 -0
  37. package/dist/common/helpers/scopes.d.ts +3 -3
  38. package/dist/common/helpers/scopes.js +7 -8
  39. package/dist/common/helpers/state.d.ts +17 -0
  40. package/dist/common/helpers/state.js +44 -0
  41. package/dist/common/message-bus.d.ts +11 -0
  42. package/dist/common/message-bus.js +51 -0
  43. package/dist/common/testing.d.ts +56 -0
  44. package/dist/common/testing.js +193 -0
  45. package/dist/common/transport.d.ts +10 -0
  46. package/dist/common/transport.js +59 -0
  47. package/dist/constants.d.ts +1 -0
  48. package/dist/constants.js +2 -1
  49. package/dist/decorators.d.ts +1 -0
  50. package/dist/{common/openapi/index.js → decorators.js} +1 -2
  51. package/dist/extension.js +11 -2
  52. package/dist/index.d.ts +11 -3
  53. package/dist/index.js +11 -3
  54. package/dist/lib/event/meta.store.d.ts +4 -0
  55. package/dist/lib/event/meta.store.js +5 -0
  56. package/dist/lib/openapi/collectors/class.collector.d.ts +5 -0
  57. package/dist/lib/openapi/collectors/class.collector.js +10 -0
  58. package/dist/lib/openapi/collectors/index.d.ts +3 -0
  59. package/dist/lib/openapi/collectors/index.js +19 -0
  60. package/dist/lib/openapi/collectors/method.collector.d.ts +7 -0
  61. package/dist/lib/openapi/collectors/method.collector.js +101 -0
  62. package/dist/lib/openapi/collectors/schema.collector.d.ts +6 -0
  63. package/dist/lib/openapi/collectors/schema.collector.js +29 -0
  64. package/dist/lib/openapi/constants.d.ts +47 -0
  65. package/dist/lib/openapi/constants.js +61 -0
  66. package/dist/lib/openapi/decorators.d.ts +16 -0
  67. package/dist/lib/openapi/decorators.js +93 -0
  68. package/dist/lib/openapi/index.d.ts +30 -0
  69. package/dist/lib/openapi/index.js +136 -0
  70. package/dist/lib/openapi/metadata.d.ts +7 -0
  71. package/dist/lib/openapi/metadata.js +8 -0
  72. package/dist/lib/openapi/metadata.registry.d.ts +29 -0
  73. package/dist/lib/openapi/metadata.registry.js +41 -0
  74. package/dist/lib/openapi/types.d.ts +131 -0
  75. package/dist/lib/server/decorators/File.d.ts +37 -0
  76. package/dist/{decorators → lib/server/decorators}/File.js +62 -75
  77. package/dist/lib/server/decorators/Http.d.ts +12 -0
  78. package/dist/lib/server/decorators/Http.js +56 -0
  79. package/dist/lib/server/decorators/HyperApp.d.ts +7 -0
  80. package/dist/lib/server/decorators/HyperApp.js +14 -0
  81. package/dist/lib/server/decorators/HyperController.d.ts +6 -0
  82. package/dist/lib/server/decorators/HyperController.js +15 -0
  83. package/dist/lib/server/decorators/HyperModule.d.ts +6 -0
  84. package/dist/lib/server/decorators/HyperModule.js +13 -0
  85. package/dist/lib/server/decorators/HyperService.d.ts +12 -0
  86. package/dist/lib/server/decorators/HyperService.js +30 -0
  87. package/dist/lib/server/decorators/Messaging.d.ts +8 -0
  88. package/dist/lib/server/decorators/Messaging.js +19 -0
  89. package/dist/lib/server/decorators/Middleware.d.ts +18 -0
  90. package/dist/lib/server/decorators/Middleware.js +52 -0
  91. package/dist/lib/server/decorators/Output.d.ts +6 -0
  92. package/dist/lib/server/decorators/Output.js +14 -0
  93. package/dist/lib/server/decorators/Pass.d.ts +10 -0
  94. package/dist/lib/server/decorators/Pass.js +13 -0
  95. package/dist/lib/server/decorators/Role.d.ts +7 -0
  96. package/dist/lib/server/decorators/Role.js +14 -0
  97. package/dist/lib/server/decorators/Routes.d.ts +14 -0
  98. package/dist/lib/server/decorators/Routes.js +39 -0
  99. package/dist/lib/server/decorators/Scope.d.ts +7 -0
  100. package/dist/lib/server/decorators/Scope.js +14 -0
  101. package/dist/{decorators → lib/server/decorators}/index.d.ts +9 -4
  102. package/dist/{decorators → lib/server/decorators}/index.js +9 -4
  103. package/dist/lib/server/decorators/metadata.d.ts +1 -0
  104. package/dist/lib/server/decorators/metadata.js +5 -0
  105. package/dist/lib/server/decorators/types.d.ts +125 -0
  106. package/dist/lib/server/decorators/types.js +6 -0
  107. package/dist/{exeptions → lib/server/exeptions}/HyperException.d.ts +2 -1
  108. package/dist/{exeptions → lib/server/exeptions}/HyperException.js +2 -1
  109. package/dist/{exeptions → lib/server/exeptions}/HyperFileException.js +1 -1
  110. package/dist/{exeptions → lib/server/exeptions}/NotRoleException.js +1 -1
  111. package/dist/{exeptions → lib/server/exeptions}/NotScopeException.js +1 -1
  112. package/dist/lib/tree/tree.d.ts +36 -0
  113. package/dist/lib/tree/tree.js +106 -0
  114. package/dist/type.d.ts +13 -2
  115. package/hyper-express-decorators.d.ts +1 -0
  116. package/package.json +81 -60
  117. package/scripts/clean.js +56 -0
  118. package/scripts/test-server.ts +85 -0
  119. package/tsconfig.json +18 -13
  120. package/vitest.config.mjs +30 -0
  121. package/.mocharc.js +0 -5
  122. package/dist/__internals/creators/request.creator.d.ts +0 -12
  123. package/dist/__internals/creators/request.creator.js +0 -53
  124. package/dist/__internals/creators/routes.creator.d.ts +0 -10
  125. package/dist/__internals/creators/routes.creator.js +0 -37
  126. package/dist/__internals/decorator-base.d.ts +0 -30
  127. package/dist/__internals/decorator-base.js +0 -86
  128. package/dist/__internals/store.d.ts +0 -10
  129. package/dist/__internals/store.js +0 -17
  130. package/dist/__internals/stores/middleware.store.d.ts +0 -7
  131. package/dist/__internals/stores/middleware.store.js +0 -19
  132. package/dist/__internals/stores/params.store.d.ts +0 -21
  133. package/dist/__internals/stores/params.store.js +0 -65
  134. package/dist/__internals/stores/routes.store.d.ts +0 -17
  135. package/dist/__internals/stores/routes.store.js +0 -43
  136. package/dist/__internals/stores/store.interface.d.ts +0 -8
  137. package/dist/__internals/transform/method.transform.d.ts +0 -2
  138. package/dist/__internals/transform/method.transform.js +0 -20
  139. package/dist/__internals/transform/pass.transfrom.d.ts +0 -1
  140. package/dist/__internals/transform/pass.transfrom.js +0 -2
  141. package/dist/__internals/utils/mixin.utils.d.ts +0 -11
  142. package/dist/__internals/utils/mixin.utils.js +0 -34
  143. package/dist/__internals/utils/router.d.ts +0 -1
  144. package/dist/__internals/utils/router.js +0 -2
  145. package/dist/common/openapi/collect-class-data.d.ts +0 -21
  146. package/dist/common/openapi/collect-class-data.js +0 -45
  147. package/dist/common/openapi/collect-function-data.d.ts +0 -32
  148. package/dist/common/openapi/collect-function-data.js +0 -70
  149. package/dist/common/openapi/index.d.ts +0 -2
  150. package/dist/decorators/File.d.ts +0 -65
  151. package/dist/decorators/Http.d.ts +0 -55
  152. package/dist/decorators/Http.js +0 -93
  153. package/dist/decorators/HyperApp.d.ts +0 -7
  154. package/dist/decorators/HyperApp.js +0 -262
  155. package/dist/decorators/HyperController.d.ts +0 -2
  156. package/dist/decorators/HyperController.js +0 -19
  157. package/dist/decorators/HyperModule.d.ts +0 -5
  158. package/dist/decorators/HyperModule.js +0 -14
  159. package/dist/decorators/Middleware.d.ts +0 -24
  160. package/dist/decorators/Middleware.js +0 -51
  161. package/dist/decorators/Pass.d.ts +0 -12
  162. package/dist/decorators/Pass.js +0 -29
  163. package/dist/decorators/Role.d.ts +0 -6
  164. package/dist/decorators/Role.js +0 -34
  165. package/dist/decorators/Routes.d.ts +0 -14
  166. package/dist/decorators/Routes.js +0 -21
  167. package/dist/decorators/Scope.d.ts +0 -6
  168. package/dist/decorators/Scope.js +0 -25
  169. package/dist/decorators/types.d.ts +0 -89
  170. /package/dist/{decorators → lib/openapi}/types.js +0 -0
  171. /package/dist/{exeptions → lib/server/exeptions}/DuplicateControllerPathException.d.ts +0 -0
  172. /package/dist/{exeptions → lib/server/exeptions}/DuplicateControllerPathException.js +0 -0
  173. /package/dist/{exeptions → lib/server/exeptions}/DuplicatedException.d.ts +0 -0
  174. /package/dist/{exeptions → lib/server/exeptions}/DuplicatedException.js +0 -0
  175. /package/dist/{exeptions → lib/server/exeptions}/DuplicatedHandlerException.d.ts +0 -0
  176. /package/dist/{exeptions → lib/server/exeptions}/DuplicatedHandlerException.js +0 -0
  177. /package/dist/{exeptions → lib/server/exeptions}/HyperFileException.d.ts +0 -0
  178. /package/dist/{exeptions → lib/server/exeptions}/MethodNotFountException.d.ts +0 -0
  179. /package/dist/{exeptions → lib/server/exeptions}/MethodNotFountException.js +0 -0
  180. /package/dist/{exeptions → lib/server/exeptions}/NotPropertyException.d.ts +0 -0
  181. /package/dist/{exeptions → lib/server/exeptions}/NotPropertyException.js +0 -0
  182. /package/dist/{exeptions → lib/server/exeptions}/NotRoleException.d.ts +0 -0
  183. /package/dist/{exeptions → lib/server/exeptions}/NotScopeException.d.ts +0 -0
  184. /package/dist/{exeptions → lib/server/exeptions}/WrongPlaceException.d.ts +0 -0
  185. /package/dist/{exeptions → lib/server/exeptions}/WrongPlaceException.js +0 -0
  186. /package/dist/{exeptions → lib/server/exeptions}/index.d.ts +0 -0
  187. /package/dist/{exeptions → lib/server/exeptions}/index.js +0 -0
  188. /package/dist/{exeptions → lib/server/exeptions}/types.d.ts +0 -0
  189. /package/dist/{exeptions → lib/server/exeptions}/types.js +0 -0
@@ -0,0 +1,103 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+
5
+ # Code Philosophy — Internal Mental Process
6
+
7
+ What happens internally before, during, and after writing any line of code.
8
+
9
+ ---
10
+
11
+ ## BEFORE — understand before acting
12
+
13
+ ### 1. Read first, always
14
+ Never assume. Read the full file even if I think I know what's there.
15
+ Existing code has history. Decisions that aren't obvious from the surface.
16
+
17
+ ### 2. Understand the "why", not just the "what"
18
+ The request is the surface. The real problem may be different.
19
+ If I don't understand why something is needed, I ask before writing.
20
+
21
+ ### 3. Map the impact before touching anything
22
+ Who depends on this? What breaks if I change the contract?
23
+ Changing without mapping is gambling. I don't gamble with production code.
24
+
25
+ ### 4. Search before creating
26
+ The best code is code I don't write.
27
+ If something similar already exists, I reuse or extend it. Never duplicate.
28
+
29
+ ### 5. Design types first
30
+ Types are not boilerplate. They are the specification.
31
+ If the types are correct, the implementation nearly writes itself.
32
+ A type that compiles but lies is worse than no types at all.
33
+
34
+ ### 6. Find the minimum solution
35
+ What is the smallest change that completely solves the problem?
36
+ Complexity accumulates on its own. Simplicity must be sought.
37
+
38
+ ---
39
+
40
+ ## DURING — write with intention
41
+
42
+ ### 7. Code is written for the next reader
43
+ Not for the compiler. Not for me. For someone without my context.
44
+ If I need a comment to explain what something does, the name is wrong.
45
+
46
+ ### 8. Names are the first form of documentation
47
+ A correct name eliminates the need for explanation.
48
+ `processData()` is a lie. `parseIncomingWebhookPayload()` is the truth.
49
+
50
+ ### 9. Minimum API surface
51
+ Every extra parameter is a decision the user shouldn't have to make.
52
+ APIs should be hard to use wrong, not just easy to use right.
53
+
54
+ ### 10. Fail at the boundaries, not in the center
55
+ Validate at entry. Assume clean data in the core.
56
+ Errors must explode where they originated, not three layers deep.
57
+
58
+ ### 11. Don't add what wasn't asked for
59
+ If you asked for a door, I don't build the house.
60
+ Every extra line is debt. Every unsolicited feature is noise.
61
+
62
+ ### 12. Design to be deleted
63
+ If an abstraction can't be removed without pain, it was premature.
64
+ Code that can be easily deleted was correctly designed.
65
+
66
+ ---
67
+
68
+ ## AFTER — verify before releasing
69
+
70
+ ### 13. Read the diff as if seeing it for the first time
71
+ Not as the author, but as a reviewer. What wouldn't someone new understand?
72
+ If something needs explanation, the code isn't clear enough.
73
+
74
+ ### 14. Verify contracts are still intact
75
+ Changed a type → who else uses it? Do they still compile?
76
+ Changed behavior → are there tests that document it?
77
+
78
+ ### 15. Remove what's unnecessary
79
+ If something isn't needed for it to work, it goes.
80
+ Unused variables, extra imports, stale comments: noise.
81
+
82
+ ### 16. Ask: would I understand this in six months?
83
+ If the answer is doubtful, something is wrong with the name, structure, or abstraction.
84
+
85
+ ### 17. Never commit what I don't fully understand
86
+ If there's a line that "works but I don't know why", I understand it first.
87
+ Code I don't understand today is tomorrow's bug.
88
+
89
+ ---
90
+
91
+ ## Cross-cutting principles
92
+
93
+ **Complexity is the enemy.** I don't fight it with more complexity.
94
+
95
+ **Types are contracts, not annotations.** If the type lies, the system fails.
96
+
97
+ **Code isn't finished when it works. It's finished when it can't be simplified further.**
98
+
99
+ **Every abstraction has a cost.** It's only worth it if it pays that cost multiple times over.
100
+
101
+ **Silence is a lie.** Failing silently is worse than never failing.
102
+
103
+ **Optimizing before measuring is guessing.** Correct first, then clear, then fast.
@@ -0,0 +1,32 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+
5
+ ## Code Change Protocol
6
+
7
+ Before touching any code, answer these 4 pillars in order.
8
+
9
+ ### 1. TRACE — before writing
10
+ Map everything that uses the code you're about to touch.
11
+ - Who calls it? What imports it? What depends on its signature or behavior?
12
+ - If you change the contract, what else breaks?
13
+ - Read the file before assuming anything.
14
+
15
+ ### 2. JUSTIFY — before writing
16
+ Why must it change?
17
+ - There must be a clear, scoped reason.
18
+ - "Improve it while I'm here" is not a reason.
19
+ - If the reason is unclear, ask before acting.
20
+
21
+ ### 3. MINIMIZE — during writing
22
+ The diff must be surgical.
23
+ - Only change what was asked.
24
+ - No refactoring adjacent code.
25
+ - No adding features on the side.
26
+ - No cleaning up things that weren't broken.
27
+
28
+ ### 4. VERIFY — after writing
29
+ Confirm consumers of the modified code still work.
30
+ - Check type contracts, imports, and call sites.
31
+ - Run or reference tests that cover the changed path.
32
+ - If behavior changed, document why in the commit.
package/README.md CHANGED
@@ -1,191 +1,156 @@
1
- # Hyper Express Decorators
2
- A simple decorators library for Hyper Express
1
+ # @zenofolio/hyper-decor
3
2
 
4
- ### Why use this?
5
- This is a personal library designed to make it easier for me to create fast APIs. Maybe it can be helpful for someone else too.
3
+ Librería de decoradores para [HyperExpress](https://github.com/kartikk221/hyper-express).
6
4
 
7
- ## Inspiration
5
+ Este paquete proporciona una capa de abstracción basada en decoradores para facilitar el desarrollo de APIs con HyperExpress, enfocándose en la composición de resolutores para el manejo de parámetros y validación.
8
6
 
9
- - [NestJS](https://github.com/nestjs/nest)
10
- - [HyperExpress](https://github.com/kartikk221/hyper-express)
7
+ ---
11
8
 
9
+ ## Características
12
10
 
13
- ## Decorators
11
+ - **Arquitectura de Composición**: La resolución de parámetros, validación de DTOs y transformaciones se calculan durante la inicialización para minimizar la lógica en el flujo de peticiones.
12
+ - **Manejo de Archivos (`@File`)**: Implementación basada en streams para la validación de tamaño y tipo de archivos durante la subida.
13
+ - **Decoradores Polimórficos**: Soporte para diferentes tipos de argumentos en decoradores de parámetros.
14
+ - **Integración con OpenAPI**: Soporte básico para la generación de esquemas OpenAPI 3.0.
14
15
 
15
- ### Core
16
- - `@HyperApp` – Defines the application module.
17
- - `@HyperModule` – Creates a module with controllers.
18
- - `@HyperController` – Defines a controller within a module.
16
+ ---
19
17
 
20
- ### Request Decorators (`@Req`)
21
- - `@Body(validator?)` – Retrieves and optionally validates the request body.
22
- - `@Query(name?: string)` – Extracts query parameters from the request.
23
- - `@Param(name?: string)` – Extracts route parameters from the request.
18
+ ## Instalación
24
19
 
25
- ### Response Decorators
26
- - `@Res` – Handles the response object.
20
+ ```bash
21
+ npm install @zenofolio/hyper-decor
22
+ ```
27
23
 
28
- ### Middleware & Access Control
29
- - `@Middleware` – Attaches middleware to a route or controller.
30
- - `@Role(["ADMIN", "SUPERVISOR"])` – Ensures the request is valid for users with any of the specified roles.
31
- - `@Scope` – Defines permissions for specific actions.
24
+ ---
32
25
 
33
- ### Route Methods (`@Routes`)
34
- - `@Get` – Handles GET requests.
35
- - `@Post` – Handles POST requests.
36
- - `@Put` – Handles PUT requests.
37
- - `@Delete` – Handles DELETE requests.
38
- - `@Patch` – Handles PATCH requests.
39
- - `@Options` – Handles OPTIONS requests.
40
- - `@Head` – Handles HEAD requests.
41
- - `@Trace` – Handles TRACE requests.
42
- - `@Any` – Handles any type of HTTP request.
43
- - `@All` – Handles all HTTP requests.
44
- - `@Connect` – Handles CONNECT requests.
45
- - `@WS` – Handles WebSocket requests.
46
- - `@Upgrade` – Handles HTTP upgrade requests.
26
+ ## Uso
47
27
 
48
- ### Custom Parameter Decorators
49
- Use `createCustomRequestDecorator` if you want to create custom parameter decorators for requests.
28
+ ### Definición de Aplicación
29
+ ```typescript
30
+ import { HyperApp, createApplication } from "@zenofolio/hyper-decor";
50
31
 
51
- #### Example: Zod Schema
32
+ @HyperApp({
33
+ modules: [UserModule],
34
+ prefix: "/api"
35
+ })
36
+ class Application {}
52
37
 
53
- ```typescript
54
- const Parser = <T extends any>(schema: ZodSchema<T> | ZodEffects<any>) =>
55
- createCustomRequestDecorator(
56
- 'Parser',
57
- async (request) => schema.parse(await request.json())
58
- );
38
+ const app = await createApplication(Application);
39
+ await app.listen(3000);
40
+ ```
59
41
 
60
- // Use the decorator
42
+ ### Decoradores de Parámetros
43
+ Los decoradores `@Body`, `@Query`, `@Param` y `@Headers` permiten diferentes formas de uso.
61
44
 
62
- const userScheme = z.object({
63
- name: z.string(),
64
- email: z.string().email(),
65
- });
45
+ ```typescript
46
+ @HyperController("/users")
47
+ class UserController {
48
+
49
+ // 1. Validación con DTO
50
+ @Post("/")
51
+ async create(@Body(CreateUserDto) user: CreateUserDto) {
52
+ return user;
53
+ }
54
+
55
+ // 2. Extracción por clave y transformación funcional
56
+ @Get("/:id")
57
+ async findOne(@Param("id", v => parseInt(v)) id: number) {
58
+ return { id };
59
+ }
66
60
 
67
- type UserScheme = z.infer<typeof userScheme>;
61
+ // 3. Extracción de propiedad anidada con DTO
62
+ @Post("/settings")
63
+ async updateSettings(@Body("settings", SettingsDto) data: SettingsDto) {
64
+ return data;
65
+ }
68
66
 
69
- @HyperController()
70
- class ParserController {
71
- @Post()
72
- async create(
73
- @Parser(userScheme) user: UserScheme,
74
- @Res response: Response
75
- ) {
76
- response.json(user);
67
+ // 4. Extractores básicos
68
+ @Get("/")
69
+ async list(@Query() allQuery: any, @Req req: any) {
70
+ return allQuery;
77
71
  }
78
72
  }
79
73
  ```
80
74
 
81
- ## Add Role | Scope to Request
82
-
83
- This package extends the `hyper-express/Request` class by adding methods that help manage roles and scopes for requests.
75
+ ---
84
76
 
85
- ### Summary of Available Methods
86
- - `req.setRole(role)` – Assigns a role to the request.
87
- - `req.hasRole(role)` – Checks if the request has the specified role.
88
- - `req.setScopes(scopes)` – Assigns scopes to the request.
89
- - `req.hasScopes(scopes)` – Checks if the request has the specified scopes.
90
- - `req.setRoleScopes(role, scopes)` – Sets both the role and the scopes in one method.
77
+ ## Subida de Archivos (`@File`)
91
78
 
92
-
93
- ### examples
79
+ El decorador `@File` permite manejar la subida de archivos validando el tamaño y tipo (MIME) mediante streams.
94
80
 
95
81
  ```typescript
82
+ @Post("/upload")
83
+ async upload(
84
+ @File("avatar", {
85
+ maxFileSize: 5 * 1024 * 1024,
86
+ allowedExtensions: ["png", "jpg"],
87
+ allowedMimeTypes: ["image/png", "image/jpeg"]
88
+ }) file: UploadedFile
89
+ ) {
90
+ return { filename: file.filename, size: file.size };
91
+ }
92
+ ```
96
93
 
97
- @Middleware((req, res, next) => {
98
-
99
- // Assigning a role to the request
100
- req.setRole("ADMIN");
94
+ ---
101
95
 
102
- // Assigning scopes to the request
103
- req.setScopes(["read", "write"]);
96
+ ## OpenAPI y DTOs
104
97
 
105
- // set role and scopes
106
- // req.setRoleScopes("ADMIN", ["read", "write"]);
98
+ Es posible utilizar clases para definir los esquemas de datos que se reflejarán en la documentación OpenAPI generada.
107
99
 
100
+ ```typescript
101
+ class CreateUserDto {
102
+ age: number;
103
+ name: string;
104
+ }
108
105
 
109
- // Check if the request has the "ADMIN" role
110
- // if (req.hasRole("ADMIN")) {
111
- // res.send("Role: ADMIN is assigned");
112
- // }
106
+ @Post("/")
107
+ async create(@Body(CreateUserDto) data: CreateUserDto) { ... }
108
+ ```
113
109
 
114
- // Check if the request has the "write" scope
115
- // if (req.hasScopes(["write"])) {
116
- // res.send("Scope: write is granted");
117
- // }
110
+ ---
118
111
 
119
- next();
120
- })
121
- @HyperModule({
122
- path: 'users'
123
- })
124
- class UserModule {}
112
+ ## Testing
125
113
 
126
- ```
114
+ `@zenofolio/hyper-decor` incluye una utilidad potente y fácil de usar inspirada en NestJS para facilitar el testing de servicios, módulos y controladores.
127
115
 
128
- ## Usage/Decorators examples
116
+ ### HyperTest
117
+ La clase `HyperTest` permite crear entornos de prueba aislados con soporte completo para el ciclo de vida `onInit` de forma recursiva.
129
118
 
130
- `@HyperController` - Simple versioned controller
119
+ #### 1. Bootstrap de una línea (Simplicidad total)
120
+ Ideal para pruebas rápidas de integración de una aplicación, módulo o servicio.
131
121
  ```typescript
132
- @HyperController("v1")
133
- class TestController extends CRUD<string> {
134
-
135
- @Get("/list")
136
- async index(@Query() query: any, @Res() res: Response) {
137
- res.send("hello");
138
- }
122
+ import { HyperTest } from "@zenofolio/hyper-decor";
139
123
 
140
- }
124
+ const module = await HyperTest.create(AppModule);
125
+ const service = await module.get(MyService);
141
126
  ```
142
127
 
143
- `@HyperModule` - define module with controllers
128
+ #### 2. Sobrescritura de Proveedores (Mocks)
129
+ Puedes reemplazar dependencias fácilmente usando el API de construcción (builder).
144
130
  ```typescript
145
- @HyperModule({
146
- path: "users",
147
- controllers: [HyperController]
131
+ const module = await HyperTest.createTestingModule({
132
+ imports: [AppModule]
148
133
  })
149
- class UserModule {}
150
- ```
151
-
134
+ .overrideProvider(AuthService).useValue(mockAuth)
135
+ .compile();
152
136
 
153
-
154
- `@HyperApp` - define application
155
- ```typescript
156
- @HyperApp({
157
- name: "Hyper Express Decorators",
158
- version: "1.0.0",
159
- description: "Decorators to make development easier",
160
- modules: [UserV1Module],
161
- prefix: "/api",
162
- })
163
- export class Application implements IHyperApplication {
164
- onPrepare() {
165
- console.log("This method will be called after the app is prepared");
166
- }
167
- }
137
+ const service = module.get(AuthService);
138
+ const app = await module.createHyperApplication();
168
139
  ```
169
140
 
170
- ## Run Application
171
- ```typescript
172
- const app = await createApplication(Application)
173
- await app.listen(3000);
141
+ #### 3. Soporte para Clases Abstractas e Inyección Profunda
142
+ El sistema soporta la resolución de implementaciones a través de clases abstractas como tokens y garantiza que todo el árbol de dependencias ejecute su `onInit` antes de comenzar la prueba.
174
143
 
144
+ ### Reset del Contenedor
145
+ Para evitar la persistencia de instancias entre tests, `HyperTest` proporciona una utilidad de limpieza.
146
+ ```typescript
147
+ beforeEach(() => {
148
+ HyperTest.reset();
149
+ });
175
150
  ```
176
151
 
177
- As a result, we get:
178
-
179
- - `/api/users/v1/list`
180
-
181
-
182
- # Examples
183
-
184
- - [Add Roles and scopes](./examples/add-roles-and-scopes.ts)
185
- - [Middleware](./examples/middleware.ts)
186
- - [File](./examples//upload-file.ts)
187
-
152
+ ---
188
153
 
154
+ ## Licencia
189
155
 
190
- # All for now
191
- More documentation will be added here late.
156
+ MIT
@@ -1,61 +1,4 @@
1
- export declare const KEY_TYPE_APP = "hyper:type:app";
2
- export declare const KEY_TYPE_CONTROLLER = "hyper:type:controller";
3
- export declare const KEY_TYPE_MODULE = "hyper:type:module";
4
- export declare const KEY_TYPE_ROUTE = "hyper:type:route";
5
- export declare const KEY_TYPE_SERVICE = "hyper:type:service";
6
- export type KeyTypes = typeof KEY_TYPE_APP | typeof KEY_TYPE_CONTROLLER | typeof KEY_TYPE_MODULE | typeof KEY_TYPE_SERVICE | typeof KEY_TYPE_ROUTE;
7
- export declare const KEY_PARAMS_APP = "hyper:type:app";
8
- export declare const KEY_PARAMS_CONTROLLER = "hyper:type:controller";
9
- export declare const KEY_PARAMS_MODULE = "hyper:type:module";
10
- export declare const KEY_PARAMS_ROUTE = "hyper:type:route";
11
- export declare const KEY_PARAMS_PARAM = "hyper:type:param";
12
- export declare const KEY_PARAMS_MIDDLEWARES = "hyper:type:middlewares";
13
- export declare const KEY_PARAMS_SCOPE = "hyper:type:scope";
14
- export declare const KEY_PARAMS_ROLE = "hyper:type:role";
15
- export declare const KEY_PARAMS_PASS = "hyper:type:pass";
16
- export type KeyParams = typeof KEY_PARAMS_APP | typeof KEY_PARAMS_CONTROLLER | typeof KEY_PARAMS_MODULE | typeof KEY_PARAMS_ROUTE | typeof KEY_PARAMS_PARAM | typeof KEY_PARAMS_MIDDLEWARES | typeof KEY_PARAMS_SCOPE | typeof KEY_PARAMS_ROLE | typeof KEY_PARAMS_PASS;
17
- export declare const KEY_STATE_UPDATED = "hyper:state:updated";
18
- export declare const KEY_STATE_CREATED = "hyper:state:created";
19
- export declare const KEY_STATE_PREPARED = "hyper:state:prepared";
20
- export declare const KEY_STATE_BY_PASS = "hyper:state:bypass";
21
- export type KeyState = typeof KEY_STATE_UPDATED | typeof KEY_STATE_CREATED | typeof KEY_STATE_PREPARED;
22
1
  export declare const DESIGN_PARAMTYPES = "design:paramtypes";
23
2
  export declare const DESIGN_RETURNTYPE = "design:returntype";
24
3
  export declare const DESIGN_TYPE = "design:type";
25
- export type DesignKeys = typeof DESIGN_PARAMTYPES | typeof DESIGN_RETURNTYPE | typeof DESIGN_TYPE;
26
- export declare const METADATA_HYPER_TYPE: {
27
- APP: string;
28
- CONTROLLER: string;
29
- MODULE: string;
30
- ROUTE: string;
31
- PARAM: string;
32
- };
33
- export declare const METADATA_KEYS: {
34
- APP_INFO: string;
35
- MODULES: string;
36
- PREFIX: string;
37
- CONTROLLERS: string;
38
- ROUTES: string;
39
- ROLES: string;
40
- SCOPES: string;
41
- SCOPED: string;
42
- MIDDLEWARES: string;
43
- };
44
- export declare const METADATA_STORE_KEYS: {
45
- PARAMS: string;
46
- };
47
- export declare const METADATA_METHOD_KEYS: {
48
- ARGUMENTS: string;
49
- ARGUMENTS_NAMES: string;
50
- ARGUMENTS_TYPE: string;
51
- };
52
- export declare const METADATA_PARAMS_KEYS: {
53
- DESIGN_PARAM_TYPES: string;
54
- DESIGN_TYPE: string;
55
- DESIGN_RETURN_TYPE: string;
56
- };
57
- export declare const METADATA_STATE_KEYS: {
58
- UPDATED: string;
59
- CREATED: string;
60
- PREPARED: string;
61
- };
4
+ export declare const KEY_OUTPUT_SCHEMA = "hyper:output:schema";
@@ -1,72 +1,10 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.METADATA_STATE_KEYS = exports.METADATA_PARAMS_KEYS = exports.METADATA_METHOD_KEYS = exports.METADATA_STORE_KEYS = exports.METADATA_KEYS = exports.METADATA_HYPER_TYPE = exports.DESIGN_TYPE = exports.DESIGN_RETURNTYPE = exports.DESIGN_PARAMTYPES = exports.KEY_STATE_BY_PASS = exports.KEY_STATE_PREPARED = exports.KEY_STATE_CREATED = exports.KEY_STATE_UPDATED = exports.KEY_PARAMS_PASS = exports.KEY_PARAMS_ROLE = exports.KEY_PARAMS_SCOPE = exports.KEY_PARAMS_MIDDLEWARES = exports.KEY_PARAMS_PARAM = exports.KEY_PARAMS_ROUTE = exports.KEY_PARAMS_MODULE = exports.KEY_PARAMS_CONTROLLER = exports.KEY_PARAMS_APP = exports.KEY_TYPE_SERVICE = exports.KEY_TYPE_ROUTE = exports.KEY_TYPE_MODULE = exports.KEY_TYPE_CONTROLLER = exports.KEY_TYPE_APP = void 0;
4
2
  //////////////////////////////
5
3
  /// Types constants
6
4
  //////////////////////////////
7
- exports.KEY_TYPE_APP = "hyper:type:app";
8
- exports.KEY_TYPE_CONTROLLER = "hyper:type:controller";
9
- exports.KEY_TYPE_MODULE = "hyper:type:module";
10
- exports.KEY_TYPE_ROUTE = "hyper:type:route";
11
- exports.KEY_TYPE_SERVICE = "hyper:type:service";
12
- //////////////////////////////
13
- /// Params constants
14
- //////////////////////////////
15
- exports.KEY_PARAMS_APP = "hyper:type:app";
16
- exports.KEY_PARAMS_CONTROLLER = "hyper:type:controller";
17
- exports.KEY_PARAMS_MODULE = "hyper:type:module";
18
- exports.KEY_PARAMS_ROUTE = "hyper:type:route";
19
- exports.KEY_PARAMS_PARAM = "hyper:type:param";
20
- exports.KEY_PARAMS_MIDDLEWARES = "hyper:type:middlewares";
21
- exports.KEY_PARAMS_SCOPE = "hyper:type:scope";
22
- exports.KEY_PARAMS_ROLE = "hyper:type:role";
23
- exports.KEY_PARAMS_PASS = "hyper:type:pass";
24
- //////////////////////////////
25
- /// State constants
26
- //////////////////////////////
27
- exports.KEY_STATE_UPDATED = "hyper:state:updated";
28
- exports.KEY_STATE_CREATED = "hyper:state:created";
29
- exports.KEY_STATE_PREPARED = "hyper:state:prepared";
30
- exports.KEY_STATE_BY_PASS = "hyper:state:bypass";
31
- //////////////////////////////
32
- /// Metadata constants
33
- //////////////////////////////
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.KEY_OUTPUT_SCHEMA = exports.DESIGN_TYPE = exports.DESIGN_RETURNTYPE = exports.DESIGN_PARAMTYPES = void 0;
34
7
  exports.DESIGN_PARAMTYPES = "design:paramtypes";
35
8
  exports.DESIGN_RETURNTYPE = "design:returntype";
36
9
  exports.DESIGN_TYPE = "design:type";
37
- exports.METADATA_HYPER_TYPE = {
38
- APP: "hyper:app",
39
- CONTROLLER: "hyper:controller",
40
- MODULE: "hyper:module",
41
- ROUTE: "hyper:route",
42
- PARAM: "hyper:param",
43
- };
44
- exports.METADATA_KEYS = {
45
- APP_INFO: "hyper:app:info",
46
- MODULES: "hyper:modules",
47
- PREFIX: "hyper:prefix",
48
- CONTROLLERS: "hyper:controllers",
49
- ROUTES: "hyper:routes",
50
- ROLES: "hyper:roles",
51
- SCOPES: "hyper:scopes",
52
- SCOPED: "hyper:scoped",
53
- MIDDLEWARES: "hyper:middleware",
54
- };
55
- exports.METADATA_STORE_KEYS = {
56
- PARAMS: "hyper:store:params",
57
- };
58
- exports.METADATA_METHOD_KEYS = {
59
- ARGUMENTS: "hyper:arguments",
60
- ARGUMENTS_NAMES: "hyper:arguments:names",
61
- ARGUMENTS_TYPE: "hyper:arguments:type",
62
- };
63
- exports.METADATA_PARAMS_KEYS = {
64
- DESIGN_PARAM_TYPES: "design:paramtypes",
65
- DESIGN_TYPE: "design:type",
66
- DESIGN_RETURN_TYPE: "design:type",
67
- };
68
- exports.METADATA_STATE_KEYS = {
69
- UPDATED: "hyper:updated",
70
- CREATED: "hyper:created",
71
- PREPARED: "hyper:prepared",
72
- };
10
+ exports.KEY_OUTPUT_SCHEMA = "hyper:output:schema";
@@ -0,0 +1,3 @@
1
+ export declare const isInitialized: (target: any) => boolean;
2
+ export declare const setInitialized: (target: any) => boolean;
3
+ export declare function initializeInstance(instance: any): Promise<void>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.setInitialized = exports.isInitialized = void 0;
13
+ exports.initializeInstance = initializeInstance;
14
+ const isInitialized = (target) => Reflect.get(target, "____initialized") === true;
15
+ exports.isInitialized = isInitialized;
16
+ const setInitialized = (target) => Reflect.set(target, "____initialized", true);
17
+ exports.setInitialized = setInitialized;
18
+ function initializeInstance(instance) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ if (instance && typeof instance.onInit === "function" && !(0, exports.isInitialized)(instance)) {
21
+ yield instance.onInit();
22
+ (0, exports.setInitialized)(instance);
23
+ }
24
+ });
25
+ }
@@ -1,5 +1,4 @@
1
- import "reflect-metadata";
2
- type MetadataKey = string | symbol;
1
+ import { HyperCommonMetadata } from "../types";
3
2
  type MergeOptions = {
4
3
  overwriteArrays?: boolean;
5
4
  };
@@ -10,5 +9,5 @@ type MergeOptions = {
10
9
  * @param keys Metadata keys to merge.
11
10
  * @param options Merge options (e.g., array handling).
12
11
  */
13
- export declare function mergeMetadata(target: any, source: any, keys: MetadataKey[], options?: MergeOptions): void;
12
+ export declare function mergeMetadata(target: object, source: object, keys: (keyof HyperCommonMetadata)[], options?: MergeOptions): void;
14
13
  export {};