@zenofolio/hyper-decor 1.0.75 → 1.0.81
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 +42 -0
- package/dist/__internals/helpers/prepare.helper.js +15 -6
- package/dist/common/testing.d.ts +56 -0
- package/dist/common/testing.js +193 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/server/decorators/HyperService.d.ts +2 -1
- package/dist/lib/server/decorators/types.d.ts +1 -1
- package/package.json +5 -1
- package/dist/__internals/creators/request.creator.d.ts +0 -2
- package/dist/__internals/creators/request.creator.js +0 -173
- package/dist/__internals/creators/routes.creator.d.ts +0 -9
- package/dist/__internals/creators/routes.creator.js +0 -39
- package/dist/__internals/decorator-base.d.ts +0 -30
- package/dist/__internals/decorator-base.js +0 -122
- package/dist/__internals/helpers/imports.helper.d.ts +0 -8
- package/dist/__internals/helpers/imports.helper.js +0 -92
- package/dist/__internals/helpers/tree.helper.d.ts +0 -36
- package/dist/__internals/helpers/tree.helper.js +0 -81
- package/dist/__internals/stores/metadata.store.d.ts +0 -15
- package/dist/__internals/stores/metadata.store.js +0 -37
- package/dist/__internals/stores/service.store.d.ts +0 -1
- package/dist/__internals/stores/service.store.js +0 -4
- package/dist/decorators/File.d.ts +0 -37
- package/dist/decorators/File.js +0 -167
- package/dist/decorators/Http.d.ts +0 -22
- package/dist/decorators/Http.js +0 -45
- package/dist/decorators/HyperApp.d.ts +0 -3
- package/dist/decorators/HyperApp.js +0 -96
- package/dist/decorators/HyperController.d.ts +0 -2
- package/dist/decorators/HyperController.js +0 -20
- package/dist/decorators/HyperModule.d.ts +0 -5
- package/dist/decorators/HyperModule.js +0 -14
- package/dist/decorators/HyperService.d.ts +0 -15
- package/dist/decorators/HyperService.js +0 -29
- package/dist/decorators/Messaging.d.ts +0 -10
- package/dist/decorators/Messaging.js +0 -22
- package/dist/decorators/Middleware.d.ts +0 -25
- package/dist/decorators/Middleware.js +0 -65
- package/dist/decorators/Output.d.ts +0 -9
- package/dist/decorators/Output.js +0 -18
- package/dist/decorators/Pass.d.ts +0 -15
- package/dist/decorators/Pass.js +0 -32
- package/dist/decorators/Role.d.ts +0 -6
- package/dist/decorators/Role.js +0 -34
- package/dist/decorators/Routes.d.ts +0 -15
- package/dist/decorators/Routes.js +0 -21
- package/dist/decorators/Scope.d.ts +0 -6
- package/dist/decorators/Scope.js +0 -25
- package/dist/decorators/Transform.d.ts +0 -14
- package/dist/decorators/Transform.js +0 -18
- package/dist/decorators/index.d.ts +0 -14
- package/dist/decorators/index.js +0 -30
- package/dist/decorators/types.d.ts +0 -124
- package/dist/decorators/types.js +0 -6
- package/dist/exeptions/DuplicateControllerPathException.d.ts +0 -14
- package/dist/exeptions/DuplicateControllerPathException.js +0 -12
- package/dist/exeptions/DuplicatedException.d.ts +0 -8
- package/dist/exeptions/DuplicatedException.js +0 -12
- package/dist/exeptions/DuplicatedHandlerException.d.ts +0 -4
- package/dist/exeptions/DuplicatedHandlerException.js +0 -12
- package/dist/exeptions/HyperException.d.ts +0 -8
- package/dist/exeptions/HyperException.js +0 -14
- package/dist/exeptions/HyperFileException.d.ts +0 -4
- package/dist/exeptions/HyperFileException.js +0 -12
- package/dist/exeptions/MethodNotFountException.d.ts +0 -4
- package/dist/exeptions/MethodNotFountException.js +0 -12
- package/dist/exeptions/NotPropertyException.d.ts +0 -6
- package/dist/exeptions/NotPropertyException.js +0 -16
- package/dist/exeptions/NotRoleException.d.ts +0 -6
- package/dist/exeptions/NotRoleException.js +0 -17
- package/dist/exeptions/NotScopeException.d.ts +0 -7
- package/dist/exeptions/NotScopeException.js +0 -18
- package/dist/exeptions/WrongPlaceException.d.ts +0 -8
- package/dist/exeptions/WrongPlaceException.js +0 -21
- package/dist/exeptions/index.d.ts +0 -8
- package/dist/exeptions/index.js +0 -18
- package/dist/exeptions/types.d.ts +0 -1
- package/dist/exeptions/types.js +0 -2
- package/dist/lib/openapi/collectors/param.collector.d.ts +0 -2
- package/dist/lib/openapi/collectors/param.collector.js +0 -64
- package/dist/lib/openapi/decorators/api-bearer-auth.decorator.d.ts +0 -2
- package/dist/lib/openapi/decorators/api-bearer-auth.decorator.js +0 -10
- package/dist/lib/openapi/decorators/api-method.decorator.d.ts +0 -3
- package/dist/lib/openapi/decorators/api-method.decorator.js +0 -11
- package/dist/lib/openapi/decorators/api-parameter.decorator.d.ts +0 -3
- package/dist/lib/openapi/decorators/api-parameter.decorator.js +0 -10
- package/dist/lib/openapi/decorators/api-request-body.decorator.d.ts +0 -3
- package/dist/lib/openapi/decorators/api-request-body.decorator.js +0 -10
- package/dist/lib/openapi/decorators/api-response.decorator.d.ts +0 -3
- package/dist/lib/openapi/decorators/api-response.decorator.js +0 -10
- package/dist/lib/openapi/decorators/api-security.decorator.d.ts +0 -3
- package/dist/lib/openapi/decorators/api-security.decorator.js +0 -10
- package/dist/lib/openapi/decorators/api-tag.decorator.d.ts +0 -3
- package/dist/lib/openapi/decorators/api-tag.decorator.js +0 -13
- package/dist/lib/openapi/decorators/index.d.ts +0 -7
- package/dist/lib/openapi/decorators/index.js +0 -23
- package/dist/lib/openapi/helpers/index.d.ts +0 -7
- package/dist/lib/openapi/helpers/index.js +0 -23
- package/dist/lib/openapi/helpers/method.helper.d.ts +0 -3
- package/dist/lib/openapi/helpers/method.helper.js +0 -20
- package/dist/lib/openapi/helpers/openapi.helper.d.ts +0 -7
- package/dist/lib/openapi/helpers/openapi.helper.js +0 -51
- package/dist/lib/openapi/helpers/parameter.helper.d.ts +0 -3
- package/dist/lib/openapi/helpers/parameter.helper.js +0 -16
- package/dist/lib/openapi/helpers/request-body.helper.d.ts +0 -3
- package/dist/lib/openapi/helpers/request-body.helper.js +0 -9
- package/dist/lib/openapi/helpers/response.helper.d.ts +0 -3
- package/dist/lib/openapi/helpers/response.helper.js +0 -18
- package/dist/lib/openapi/helpers/security.helper.d.ts +0 -3
- package/dist/lib/openapi/helpers/security.helper.js +0 -17
- package/dist/lib/openapi/helpers/tag.helper.d.ts +0 -3
- package/dist/lib/openapi/helpers/tag.helper.js +0 -10
- package/dist/stores/index.d.ts +0 -1
- package/dist/stores/index.js +0 -17
- package/dist/stores/scope.store.d.ts +0 -14
- package/dist/stores/scope.store.js +0 -29
package/README.md
CHANGED
|
@@ -109,6 +109,48 @@ async create(@Body(CreateUserDto) data: CreateUserDto) { ... }
|
|
|
109
109
|
|
|
110
110
|
---
|
|
111
111
|
|
|
112
|
+
## Testing
|
|
113
|
+
|
|
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.
|
|
115
|
+
|
|
116
|
+
### HyperTest
|
|
117
|
+
La clase `HyperTest` permite crear entornos de prueba aislados con soporte completo para el ciclo de vida `onInit` de forma recursiva.
|
|
118
|
+
|
|
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.
|
|
121
|
+
```typescript
|
|
122
|
+
import { HyperTest } from "@zenofolio/hyper-decor";
|
|
123
|
+
|
|
124
|
+
const module = await HyperTest.create(AppModule);
|
|
125
|
+
const service = await module.get(MyService);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### 2. Sobrescritura de Proveedores (Mocks)
|
|
129
|
+
Puedes reemplazar dependencias fácilmente usando el API de construcción (builder).
|
|
130
|
+
```typescript
|
|
131
|
+
const module = await HyperTest.createTestingModule({
|
|
132
|
+
imports: [AppModule]
|
|
133
|
+
})
|
|
134
|
+
.overrideProvider(AuthService).useValue(mockAuth)
|
|
135
|
+
.compile();
|
|
136
|
+
|
|
137
|
+
const service = module.get(AuthService);
|
|
138
|
+
const app = await module.createHyperApplication();
|
|
139
|
+
```
|
|
140
|
+
|
|
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.
|
|
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
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
112
154
|
## Licencia
|
|
113
155
|
|
|
114
156
|
MIT
|
|
@@ -275,6 +275,16 @@ function ensureResolvable(target) {
|
|
|
275
275
|
tsyringe_1.container.register(target, target);
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
|
+
function registerRoutes(target, instance, router, namespace, log) {
|
|
279
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
280
|
+
const methods = getMethodMetadataMap(target);
|
|
281
|
+
for (const key of Object.keys(methods)) {
|
|
282
|
+
const route = methods[key].route;
|
|
283
|
+
if (route)
|
|
284
|
+
yield prepareRoute(target, router, route, instance, namespace, log);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
278
288
|
function prepareController(descriptor, context, log) {
|
|
279
289
|
return __awaiter(this, void 0, void 0, function* () {
|
|
280
290
|
var _a;
|
|
@@ -285,12 +295,7 @@ function prepareController(descriptor, context, log) {
|
|
|
285
295
|
yield prepareImportsInternal((_a = metadata.imports) !== null && _a !== void 0 ? _a : [], context, log);
|
|
286
296
|
yield registerInstanceHandlers(instance, target, context.namespace, log);
|
|
287
297
|
applyCommonPipeline(target.name, { use: (...args) => router.use(...args) }, data, log);
|
|
288
|
-
|
|
289
|
-
for (const key of Object.keys(methods)) {
|
|
290
|
-
const route = methods[key].route;
|
|
291
|
-
if (route)
|
|
292
|
-
yield prepareRoute(target, router, route, instance, context.namespace, log);
|
|
293
|
-
}
|
|
298
|
+
yield registerRoutes(target, instance, router, context.namespace, log);
|
|
294
299
|
context.parentRouter.use(context.prefix, router);
|
|
295
300
|
});
|
|
296
301
|
}
|
|
@@ -319,6 +324,8 @@ function prepareModule(descriptor, context, log) {
|
|
|
319
324
|
}, log);
|
|
320
325
|
}
|
|
321
326
|
}
|
|
327
|
+
// Direct routes on module
|
|
328
|
+
yield registerRoutes(target, instance, router, context.namespace, log);
|
|
322
329
|
// Controllers
|
|
323
330
|
if ((_c = metadata.controllers) === null || _c === void 0 ? void 0 : _c.length) {
|
|
324
331
|
for (const c of metadata.controllers) {
|
|
@@ -364,6 +371,8 @@ function prepareApplication(options, Target, log) {
|
|
|
364
371
|
yield prepareImportsInternal((_b = options.imports) !== null && _b !== void 0 ? _b : [], context, log);
|
|
365
372
|
yield registerInstanceHandlers(appInstance, Target, context.namespace, log);
|
|
366
373
|
applyCommonPipeline(Target.name, { use: (...args) => appServer.use(...args) }, data, log);
|
|
374
|
+
// Direct routes on app
|
|
375
|
+
yield registerRoutes(Target, appInstance, appServer, context.namespace, log);
|
|
367
376
|
if ((_c = options.modules) === null || _c === void 0 ? void 0 : _c.length) {
|
|
368
377
|
for (const m of options.modules) {
|
|
369
378
|
const mData = getData(m).metadata;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { InjectionToken } from "tsyringe";
|
|
3
|
+
import { Constructor, HyperAppMetadata, ImportType } from "../lib/server/decorators/types";
|
|
4
|
+
export type Token<T = any> = InjectionToken<T> | Constructor<T> | string | (abstract new (...args: any[]) => T);
|
|
5
|
+
/**
|
|
6
|
+
* 🧪 TestingModule
|
|
7
|
+
* Holds the context of a compiled test environment.
|
|
8
|
+
*/
|
|
9
|
+
export declare class TestingModule {
|
|
10
|
+
private target?;
|
|
11
|
+
constructor(target?: Constructor | undefined);
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a dependency from the container and ensures it's initialized.
|
|
14
|
+
*/
|
|
15
|
+
resolve<T>(token: Token<T>): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Shortcut for resolve (consistent with NestJS)
|
|
18
|
+
*/
|
|
19
|
+
get<T>(token: Token<T>): Promise<T>;
|
|
20
|
+
/**
|
|
21
|
+
* Creates the full HyperExpress application proxy.
|
|
22
|
+
*/
|
|
23
|
+
createHyperApplication(): Promise<any>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 🛠️ TestingModuleBuilder
|
|
27
|
+
* Fluent API for configuring the testing module.
|
|
28
|
+
*/
|
|
29
|
+
export declare class TestingModuleBuilder {
|
|
30
|
+
private metadata;
|
|
31
|
+
constructor(metadata: Partial<HyperAppMetadata>);
|
|
32
|
+
overrideProvider(token: Token): any;
|
|
33
|
+
compile(): Promise<TestingModule>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 🚀 HyperTest
|
|
37
|
+
* Entry point for creating testing environments.
|
|
38
|
+
*/
|
|
39
|
+
export declare class HyperTest {
|
|
40
|
+
/**
|
|
41
|
+
* Ultra-simple one-liner to boot a module or app.
|
|
42
|
+
* const module = await HyperTest.create(AppModule);
|
|
43
|
+
*/
|
|
44
|
+
static create(Target: Constructor, options?: {
|
|
45
|
+
providers?: ImportType[];
|
|
46
|
+
}): Promise<TestingModule>;
|
|
47
|
+
/**
|
|
48
|
+
* Full builder API for complex configurations.
|
|
49
|
+
*/
|
|
50
|
+
static createTestingModule(metadata: Partial<HyperAppMetadata>): TestingModuleBuilder;
|
|
51
|
+
/**
|
|
52
|
+
* Resets the global container instances (but keeps registrations).
|
|
53
|
+
* Useful between tests when isolation is not possible.
|
|
54
|
+
*/
|
|
55
|
+
static reset(): void;
|
|
56
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.HyperTest = exports.TestingModuleBuilder = exports.TestingModule = void 0;
|
|
19
|
+
require("reflect-metadata");
|
|
20
|
+
const tsyringe_1 = require("tsyringe");
|
|
21
|
+
const stores_1 = require("../__internals/stores");
|
|
22
|
+
const lifecycle_helper_1 = require("../__internals/helpers/lifecycle.helper");
|
|
23
|
+
const bootstrap_1 = require("./bootstrap");
|
|
24
|
+
const HyperApp_1 = require("../lib/server/decorators/HyperApp");
|
|
25
|
+
/**
|
|
26
|
+
* 🧪 TestingModule
|
|
27
|
+
* Holds the context of a compiled test environment.
|
|
28
|
+
*/
|
|
29
|
+
class TestingModule {
|
|
30
|
+
constructor(target) {
|
|
31
|
+
this.target = target;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolves a dependency from the container and ensures it's initialized.
|
|
35
|
+
*/
|
|
36
|
+
resolve(token) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
return yield deepResolve(token);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Shortcut for resolve (consistent with NestJS)
|
|
43
|
+
*/
|
|
44
|
+
get(token) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
return yield this.resolve(token);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates the full HyperExpress application proxy.
|
|
51
|
+
*/
|
|
52
|
+
createHyperApplication() {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
if (!this.target) {
|
|
55
|
+
throw new Error("Cannot create application without a target module/app.");
|
|
56
|
+
}
|
|
57
|
+
return yield (0, bootstrap_1.createApplication)(this.target);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.TestingModule = TestingModule;
|
|
62
|
+
/**
|
|
63
|
+
* 🛠️ TestingModuleBuilder
|
|
64
|
+
* Fluent API for configuring the testing module.
|
|
65
|
+
*/
|
|
66
|
+
class TestingModuleBuilder {
|
|
67
|
+
constructor(metadata) {
|
|
68
|
+
this.metadata = metadata;
|
|
69
|
+
}
|
|
70
|
+
overrideProvider(token) {
|
|
71
|
+
return {
|
|
72
|
+
useValue: (value) => {
|
|
73
|
+
tsyringe_1.container.register(token, { useValue: value });
|
|
74
|
+
return this;
|
|
75
|
+
},
|
|
76
|
+
useClass: (target) => {
|
|
77
|
+
tsyringe_1.container.register(token, { useClass: target });
|
|
78
|
+
return this;
|
|
79
|
+
},
|
|
80
|
+
useFactory: (factory) => {
|
|
81
|
+
tsyringe_1.container.register(token, { useFactory: factory });
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
compile() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
// 1. Create a synthetic app if needed
|
|
89
|
+
let SyntheticApp = class SyntheticApp {
|
|
90
|
+
};
|
|
91
|
+
SyntheticApp = __decorate([
|
|
92
|
+
(0, HyperApp_1.HyperApp)(this.metadata)
|
|
93
|
+
], SyntheticApp);
|
|
94
|
+
// 2. Deep initialize all defined imports/providers
|
|
95
|
+
if (this.metadata.imports) {
|
|
96
|
+
for (const item of this.metadata.imports) {
|
|
97
|
+
const token = typeof item === "object" && "token" in item ? item.token : item;
|
|
98
|
+
yield deepResolve(token);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return new TestingModule(SyntheticApp);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.TestingModuleBuilder = TestingModuleBuilder;
|
|
106
|
+
/**
|
|
107
|
+
* 🚀 HyperTest
|
|
108
|
+
* Entry point for creating testing environments.
|
|
109
|
+
*/
|
|
110
|
+
class HyperTest {
|
|
111
|
+
/**
|
|
112
|
+
* Ultra-simple one-liner to boot a module or app.
|
|
113
|
+
* const module = await HyperTest.create(AppModule);
|
|
114
|
+
*/
|
|
115
|
+
static create(Target, options) {
|
|
116
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
+
const builder = this.createTestingModule({
|
|
118
|
+
imports: [Target, ...((options === null || options === void 0 ? void 0 : options.providers) || [])]
|
|
119
|
+
});
|
|
120
|
+
const module = yield builder.compile();
|
|
121
|
+
// Ensure the target itself is deep-resolved
|
|
122
|
+
yield deepResolve(Target);
|
|
123
|
+
return module;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Full builder API for complex configurations.
|
|
128
|
+
*/
|
|
129
|
+
static createTestingModule(metadata) {
|
|
130
|
+
return new TestingModuleBuilder(metadata);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Resets the global container instances (but keeps registrations).
|
|
134
|
+
* Useful between tests when isolation is not possible.
|
|
135
|
+
*/
|
|
136
|
+
static reset() {
|
|
137
|
+
tsyringe_1.container.clearInstances();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.HyperTest = HyperTest;
|
|
141
|
+
/**
|
|
142
|
+
* 🔄 deepResolve
|
|
143
|
+
* Recursively resolves a token and ensures its onInit chain is executed.
|
|
144
|
+
*/
|
|
145
|
+
function deepResolve(token) {
|
|
146
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
const instance = tsyringe_1.container.resolve(token);
|
|
148
|
+
// 1. Get the actual implementation constructor to inspect dependencies.
|
|
149
|
+
// We prefer instance.constructor because if token is an abstract class,
|
|
150
|
+
// dependencies are defined on the implementation.
|
|
151
|
+
const target = (instance === null || instance === void 0 ? void 0 : instance.constructor) || (typeof token === "function" ? token : null);
|
|
152
|
+
// 2. Recursive resolution of dependencies (Bottom-up initialization)
|
|
153
|
+
if (target && typeof target === "function") {
|
|
154
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
155
|
+
const injectionTokens = Reflect.getOwnMetadata("injectionTokens", target) || {};
|
|
156
|
+
for (let i = 0; i < paramTypes.length; i++) {
|
|
157
|
+
// Use @inject token if present, otherwise use design:paramtype
|
|
158
|
+
const dep = injectionTokens[i] || paramTypes[i];
|
|
159
|
+
// Avoid cycles or primitives
|
|
160
|
+
if (dep && typeof dep === "function" && dep !== Object && dep !== Array && dep !== String && dep !== Number && dep !== Boolean) {
|
|
161
|
+
yield deepResolve(dep);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// 3. Metadata Discovery (traversing @HyperApp, @HyperModule, etc.)
|
|
166
|
+
const metadata = stores_1.HyperMeta.get(target);
|
|
167
|
+
if (metadata) {
|
|
168
|
+
// Resolve imports
|
|
169
|
+
if (metadata.imports && Array.isArray(metadata.imports)) {
|
|
170
|
+
for (const item of metadata.imports) {
|
|
171
|
+
const depToken = typeof item === "object" && item !== null && "token" in item ? item.token : item;
|
|
172
|
+
if (depToken)
|
|
173
|
+
yield deepResolve(depToken);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Resolve modules recursively
|
|
177
|
+
if (metadata.modules && Array.isArray(metadata.modules)) {
|
|
178
|
+
for (const m of metadata.modules) {
|
|
179
|
+
yield deepResolve(m);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Resolve controllers
|
|
183
|
+
if (metadata.controllers && Array.isArray(metadata.controllers)) {
|
|
184
|
+
for (const c of metadata.controllers) {
|
|
185
|
+
yield deepResolve(c);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// 4. Initialize the instance itself
|
|
190
|
+
yield (0, lifecycle_helper_1.initializeInstance)(instance);
|
|
191
|
+
return instance;
|
|
192
|
+
});
|
|
193
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -30,3 +30,4 @@ __exportStar(require("./common/transport"), exports);
|
|
|
30
30
|
__exportStar(require("./common/message-bus"), exports);
|
|
31
31
|
__exportStar(require("./__internals/transform/transform.registry"), exports);
|
|
32
32
|
__exportStar(require("./lib/openapi"), exports);
|
|
33
|
+
__exportStar(require("./common/testing"), exports);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
|
+
import { Constructor } from "./types";
|
|
2
3
|
interface ServiceDecoratorOptions {
|
|
3
4
|
singleton?: boolean;
|
|
4
|
-
token?: string | symbol;
|
|
5
|
+
token?: string | symbol | Constructor | (abstract new (...args: any[]) => any);
|
|
5
6
|
}
|
|
6
7
|
/**
|
|
7
8
|
* 🚀 HyperService Decorator
|
|
@@ -9,7 +9,7 @@ export interface IsSingleton {
|
|
|
9
9
|
}
|
|
10
10
|
export type Constructor<R = object> = new (...args: any[]) => R;
|
|
11
11
|
export type ImportObject = {
|
|
12
|
-
token: InjectionToken;
|
|
12
|
+
token: (abstract new (...args: any[]) => any) | InjectionToken;
|
|
13
13
|
useClass?: Constructor;
|
|
14
14
|
useValue?: any;
|
|
15
15
|
useFactory?: (...args: any[]) => any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenofolio/hyper-decor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.81",
|
|
4
4
|
"description": "Project core with utilities and features",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "zenozaga",
|
|
@@ -67,6 +67,10 @@
|
|
|
67
67
|
"node": "./dist/extension.js",
|
|
68
68
|
"default": "./src/extension.ts"
|
|
69
69
|
},
|
|
70
|
+
"./testing": {
|
|
71
|
+
"node": "./dist/common/testing.js",
|
|
72
|
+
"default": "./src/common/testing.ts"
|
|
73
|
+
},
|
|
70
74
|
"./openapi": {
|
|
71
75
|
"node": "./dist/lib/openapi/index.js",
|
|
72
76
|
"default": "./src/lib/openapi/index.ts"
|
|
@@ -1,173 +0,0 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.default = createParamDecorator;
|
|
16
|
-
require("reflect-metadata");
|
|
17
|
-
const constants_1 = require("../constants");
|
|
18
|
-
const decorator_base_1 = require("../decorator-base");
|
|
19
|
-
const WrongPlaceException_1 = __importDefault(require("../../exeptions/WrongPlaceException"));
|
|
20
|
-
const function_util_1 = require("../utils/function.util");
|
|
21
|
-
const object_util_1 = require("../utils/object.util");
|
|
22
|
-
const transform_registry_1 = require("../transform/transform.registry");
|
|
23
|
-
const identitySelector = (value) => value;
|
|
24
|
-
const identityTransformer = (value) => value;
|
|
25
|
-
function createParamDecorator(sourceKey, decoratorName, keyOrSchema, schemaOrTransform, isWholeSource = false) {
|
|
26
|
-
const _sourceKey = sourceKey;
|
|
27
|
-
return (0, decorator_base_1.DecoratorHelper)({
|
|
28
|
-
type: constants_1.KEY_TYPE_CONTROLLER,
|
|
29
|
-
key: constants_1.KEY_PARAMS_PARAM,
|
|
30
|
-
options: (options, Target, propertyKey, parameterIndex) => {
|
|
31
|
-
const isProperty = typeof parameterIndex === "number";
|
|
32
|
-
if (!isProperty) {
|
|
33
|
-
throw new WrongPlaceException_1.default(decoratorName, "parameter", `${Target.constructor.name}.${String(propertyKey)}`, Target);
|
|
34
|
-
}
|
|
35
|
-
const saved = options !== null && options !== void 0 ? options : { params: {} };
|
|
36
|
-
const method = Target[propertyKey];
|
|
37
|
-
const names = (0, function_util_1.extractArgsNames)(method);
|
|
38
|
-
const types = Reflect.getMetadata(constants_1.DESIGN_PARAMTYPES, Target, propertyKey);
|
|
39
|
-
const name = names === null || names === void 0 ? void 0 : names[parameterIndex];
|
|
40
|
-
const type = types === null || types === void 0 ? void 0 : types[parameterIndex];
|
|
41
|
-
let key = undefined;
|
|
42
|
-
let inputSchemaOrFn = undefined;
|
|
43
|
-
let wholeSource = isWholeSource;
|
|
44
|
-
if (typeof keyOrSchema === "string") {
|
|
45
|
-
key = keyOrSchema;
|
|
46
|
-
inputSchemaOrFn = schemaOrTransform;
|
|
47
|
-
}
|
|
48
|
-
else if (keyOrSchema !== undefined) {
|
|
49
|
-
inputSchemaOrFn = keyOrSchema;
|
|
50
|
-
wholeSource = true;
|
|
51
|
-
}
|
|
52
|
-
const hasKey = key !== undefined && key !== "";
|
|
53
|
-
const hasTransform = inputSchemaOrFn !== undefined;
|
|
54
|
-
const extractor = createExtractor(_sourceKey);
|
|
55
|
-
const selector = createSelector(key);
|
|
56
|
-
const transformer = createTransformer(inputSchemaOrFn, _sourceKey, wholeSource);
|
|
57
|
-
const resolver = composeResolver(extractor, selector, transformer, hasKey, hasTransform);
|
|
58
|
-
if (name && saved) {
|
|
59
|
-
let methodParams = saved.params[propertyKey];
|
|
60
|
-
if (!methodParams) {
|
|
61
|
-
methodParams = saved.params[propertyKey] = [];
|
|
62
|
-
}
|
|
63
|
-
methodParams.push({
|
|
64
|
-
name,
|
|
65
|
-
type,
|
|
66
|
-
index: parameterIndex,
|
|
67
|
-
key: _sourceKey,
|
|
68
|
-
method: propertyKey.toString(),
|
|
69
|
-
resolver,
|
|
70
|
-
schema: inputSchemaOrFn,
|
|
71
|
-
isWholeSource: wholeSource,
|
|
72
|
-
});
|
|
73
|
-
if (methodParams.length > 1) {
|
|
74
|
-
methodParams.sort((a, b) => a.index - b.index);
|
|
75
|
-
}
|
|
76
|
-
Reflect.defineMetadata(constants_1.KEY_PARAMS_PARAM, saved, method);
|
|
77
|
-
}
|
|
78
|
-
return saved;
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
//////////////////////////
|
|
83
|
-
/// Functions
|
|
84
|
-
/////////////////////////
|
|
85
|
-
function createBodyExtractor() {
|
|
86
|
-
return (req) => __awaiter(this, void 0, void 0, function* () {
|
|
87
|
-
const request = req;
|
|
88
|
-
const cachedBody = request.body;
|
|
89
|
-
if (cachedBody !== undefined) {
|
|
90
|
-
return cachedBody;
|
|
91
|
-
}
|
|
92
|
-
const body = yield req.json();
|
|
93
|
-
request.body = body;
|
|
94
|
-
return body;
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
function createReqExtractor() {
|
|
98
|
-
return (req) => __awaiter(this, void 0, void 0, function* () { return req; });
|
|
99
|
-
}
|
|
100
|
-
function createResExtractor() {
|
|
101
|
-
return (_req, res) => __awaiter(this, void 0, void 0, function* () { return res; });
|
|
102
|
-
}
|
|
103
|
-
function createGenericExtractor(sourceKey) {
|
|
104
|
-
return (req) => __awaiter(this, void 0, void 0, function* () { return req[sourceKey]; });
|
|
105
|
-
}
|
|
106
|
-
function createExtractor(sourceKey) {
|
|
107
|
-
switch (sourceKey) {
|
|
108
|
-
case "body":
|
|
109
|
-
return createBodyExtractor();
|
|
110
|
-
case "req":
|
|
111
|
-
return createReqExtractor();
|
|
112
|
-
case "res":
|
|
113
|
-
return createResExtractor();
|
|
114
|
-
default:
|
|
115
|
-
return createGenericExtractor(sourceKey);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
function createSelector(key) {
|
|
119
|
-
if (key === undefined || key === "") {
|
|
120
|
-
return identitySelector;
|
|
121
|
-
}
|
|
122
|
-
return (value) => (0, object_util_1.$get)(value, key, value);
|
|
123
|
-
}
|
|
124
|
-
function createDirectTransformer(fn) {
|
|
125
|
-
return (value) => fn(value);
|
|
126
|
-
}
|
|
127
|
-
function createRegistryTransformer(schema, sourceKey, isWholeSource) {
|
|
128
|
-
const options = { isWholeSource };
|
|
129
|
-
const from = sourceKey;
|
|
130
|
-
return (value, req, res) => transform_registry_1.transformRegistry.resolve({
|
|
131
|
-
data: value,
|
|
132
|
-
schema,
|
|
133
|
-
options,
|
|
134
|
-
req,
|
|
135
|
-
res,
|
|
136
|
-
from,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
function createTransformer(inputSchemaOrFn, sourceKey, isWholeSource) {
|
|
140
|
-
if (inputSchemaOrFn === undefined) {
|
|
141
|
-
return identityTransformer;
|
|
142
|
-
}
|
|
143
|
-
if (typeof inputSchemaOrFn === "function" &&
|
|
144
|
-
inputSchemaOrFn.prototype === undefined) {
|
|
145
|
-
return createDirectTransformer(inputSchemaOrFn);
|
|
146
|
-
}
|
|
147
|
-
if (typeof inputSchemaOrFn === "function" ||
|
|
148
|
-
typeof inputSchemaOrFn === "string") {
|
|
149
|
-
return createRegistryTransformer(inputSchemaOrFn, sourceKey, isWholeSource);
|
|
150
|
-
}
|
|
151
|
-
return identityTransformer;
|
|
152
|
-
}
|
|
153
|
-
function composeResolver(extractor, selector, transformer, hasKey, hasTransform) {
|
|
154
|
-
if (!hasKey && !hasTransform) {
|
|
155
|
-
return extractor;
|
|
156
|
-
}
|
|
157
|
-
if (hasKey && !hasTransform) {
|
|
158
|
-
return (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
159
|
-
const value = yield extractor(req, res);
|
|
160
|
-
return selector(value);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
if (!hasKey && hasTransform) {
|
|
164
|
-
return (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
165
|
-
const value = yield extractor(req, res);
|
|
166
|
-
return transformer(value, req, res);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
return (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
170
|
-
const value = yield extractor(req, res);
|
|
171
|
-
return transformer(selector(value), req, res);
|
|
172
|
-
});
|
|
173
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
/**
|
|
3
|
-
* Helper function to create route decorators for HTTP methods.
|
|
4
|
-
*
|
|
5
|
-
* @param {string} method - The HTTP method (e.g., GET, POST).
|
|
6
|
-
* @returns {(path?: string) => MethodDecorator} - A method decorator for defining routes.
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
|
-
export default function createRouteDecorator<T extends any = undefined>(method: string): (path?: string, options?: T) => MethodDecorator & ClassDecorator;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = createRouteDecorator;
|
|
4
|
-
require("reflect-metadata");
|
|
5
|
-
const constants_1 = require("../constants");
|
|
6
|
-
const decorator_base_1 = require("../decorator-base");
|
|
7
|
-
/**
|
|
8
|
-
* Helper function to create route decorators for HTTP methods.
|
|
9
|
-
*
|
|
10
|
-
* @param {string} method - The HTTP method (e.g., GET, POST).
|
|
11
|
-
* @returns {(path?: string) => MethodDecorator} - A method decorator for defining routes.
|
|
12
|
-
*
|
|
13
|
-
*/
|
|
14
|
-
function createRouteDecorator(method) {
|
|
15
|
-
return (path = "/", options) => (0, decorator_base_1.DecoratorHelper)({
|
|
16
|
-
type: constants_1.KEY_TYPE_CONTROLLER,
|
|
17
|
-
key: constants_1.KEY_PARAMS_ROUTE,
|
|
18
|
-
targetResolver: (target) => { var _a; return (_a = target.constructor) !== null && _a !== void 0 ? _a : target; },
|
|
19
|
-
options: (data, Target, propertyKey, descriptor) => {
|
|
20
|
-
// add openAPI data here
|
|
21
|
-
var _a;
|
|
22
|
-
const handler = descriptor.value;
|
|
23
|
-
if (typeof handler !== "function")
|
|
24
|
-
return data;
|
|
25
|
-
const saved = (_a = Reflect.getMetadata(constants_1.KEY_PARAMS_ROUTE, Target)) !== null && _a !== void 0 ? _a : {
|
|
26
|
-
routes: new Set(),
|
|
27
|
-
};
|
|
28
|
-
saved.routes.add({
|
|
29
|
-
className: Target.name,
|
|
30
|
-
method,
|
|
31
|
-
path,
|
|
32
|
-
propertyKey,
|
|
33
|
-
handler: handler,
|
|
34
|
-
options,
|
|
35
|
-
});
|
|
36
|
-
return saved;
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
export type DecoratorBaseTypes = "APP" | "MODULE" | "CONTROLLER" | "ROUTE" | "MIDDLEWARE";
|
|
3
|
-
type DefineResolve<T> = (old: T, target?: any, property?: any, descriptor?: any) => T;
|
|
4
|
-
interface onDefineResolve<T> {
|
|
5
|
-
(data: {
|
|
6
|
-
key: string;
|
|
7
|
-
options: T;
|
|
8
|
-
target: any;
|
|
9
|
-
property?: any;
|
|
10
|
-
descriptor?: any;
|
|
11
|
-
}, defineData: (options: T) => void): void;
|
|
12
|
-
}
|
|
13
|
-
interface BeseDecoratorOptions<T extends any = any> {
|
|
14
|
-
type?: DecoratorBaseTypes | string;
|
|
15
|
-
key: string;
|
|
16
|
-
options: T | DefineResolve<T>;
|
|
17
|
-
targetResolver?: (target: any, propertyKey?: any, descriptorOrIndex?: any) => any;
|
|
18
|
-
onDefineData?: onDefineResolve<T>;
|
|
19
|
-
}
|
|
20
|
-
interface BeseDecorator<T> {
|
|
21
|
-
(target: T): any;
|
|
22
|
-
(target: T, propertyKey?: any, descriptor?: any): any;
|
|
23
|
-
}
|
|
24
|
-
type TransformFunction<TOptions, T> = (options: TOptions, target: T, propertyKey?: any, descriptor?: any) => any;
|
|
25
|
-
export declare function DecoratorHelper<T, Target extends any = any>({ key, type, options, targetResolver, onDefineData }: BeseDecoratorOptions<T>, ...transformers: TransformFunction<T, Target>[]): BeseDecorator<Target>;
|
|
26
|
-
export declare const defineDecorData: <T>(key: string, options: T | DefineResolve<T>, target: any, property?: any, descriptor?: any) => void;
|
|
27
|
-
export declare const getDecorData: <T>(key: string, target: any, property?: any) => T;
|
|
28
|
-
export declare const hasDecorData: (key: string, target: any, property?: any) => boolean;
|
|
29
|
-
export declare const extractDecorData: <T>(target: any) => T | undefined;
|
|
30
|
-
export {};
|