@zenofolio/hyper-decor 1.0.61 → 1.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__internals/constants.d.ts +1 -0
- package/dist/__internals/constants.js +1 -0
- package/dist/__internals/decorator-base.js +46 -10
- package/dist/__internals/helpers/imports.helper.d.ts +2 -2
- package/dist/__internals/helpers/imports.helper.js +68 -21
- package/dist/__internals/helpers/lifecycle.helper.d.ts +3 -0
- package/dist/__internals/helpers/lifecycle.helper.js +25 -0
- package/dist/__internals/helpers/merge-metadata.js +16 -20
- package/dist/__internals/helpers/prepare.helper.js +85 -52
- package/dist/__internals/helpers/tree.helper.d.ts +32 -0
- package/dist/__internals/helpers/tree.helper.js +48 -0
- package/dist/__internals/transform/middleware.transform.js +0 -2
- package/dist/__internals/transform/role.transform.js +5 -5
- package/dist/__internals/transform/scope.transfrom.js +2 -3
- package/dist/common/bootstrap.js +4 -0
- package/dist/common/helpers/role.js +1 -4
- package/dist/common/message-bus.d.ts +11 -0
- package/dist/common/message-bus.js +51 -0
- package/dist/common/transport.d.ts +9 -0
- package/dist/common/transport.js +46 -0
- package/dist/decorators/HyperApp.js +3 -1
- package/dist/decorators/HyperService.d.ts +2 -1
- package/dist/decorators/HyperService.js +6 -4
- package/dist/decorators/Messaging.d.ts +10 -0
- package/dist/decorators/Messaging.js +22 -0
- package/dist/decorators/Middleware.d.ts +1 -1
- package/dist/decorators/Middleware.js +14 -2
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +1 -0
- package/dist/decorators/types.d.ts +21 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/type.d.ts +5 -2
- package/dist/vitest.config.d.ts +2 -0
- package/dist/vitest.config.js +34 -0
- package/package.json +66 -59
- package/scripts/clean.js +56 -0
- package/vitest.config.mjs +30 -0
- package/vitest.json +0 -0
- package/.mocharc.js +0 -5
- package/dist/__internals/store.d.ts +0 -29
- package/dist/__internals/store.js +0 -17
- package/dist/__internals/stores/index.d.ts +0 -15
- package/dist/__internals/stores/index.js +0 -37
- package/dist/__internals/stores/middleware.store.d.ts +0 -7
- package/dist/__internals/stores/middleware.store.js +0 -19
- package/dist/__internals/stores/params.store.d.ts +0 -21
- package/dist/__internals/stores/params.store.js +0 -65
- package/dist/__internals/stores/routes.store.d.ts +0 -17
- package/dist/__internals/stores/routes.store.js +0 -43
- package/dist/__internals/stores/store.interface.d.ts +0 -8
- package/dist/__internals/stores/store.interface.js +0 -2
- package/dist/__internals/transform/method.transform.d.ts +0 -2
- package/dist/__internals/transform/method.transform.js +0 -20
- package/dist/__internals/transform/pass.transfrom.d.ts +0 -1
- package/dist/__internals/transform/pass.transfrom.js +0 -2
- package/dist/__internals/utils/mixin.utils.d.ts +0 -11
- package/dist/__internals/utils/mixin.utils.js +0 -34
- package/dist/__internals/utils/router.d.ts +0 -1
- package/dist/__internals/utils/router.js +0 -2
- package/dist/collectors/index.d.ts +0 -1
- package/dist/collectors/index.js +0 -17
- package/dist/collectors/scope.collector.d.ts +0 -14
- package/dist/collectors/scope.collector.js +0 -29
- package/dist/common/openapi/collect-class-data.d.ts +0 -21
- package/dist/common/openapi/collect-class-data.js +0 -45
- package/dist/common/openapi/collect-function-data.d.ts +0 -32
- package/dist/common/openapi/collect-function-data.js +0 -70
- package/dist/common/openapi/index.d.ts +0 -2
- package/dist/common/openapi/index.js +0 -18
- package/dist/decorators/Service.d.ts +0 -5
- package/dist/decorators/Service.js +0 -16
|
@@ -48,12 +48,17 @@ function DecoratorHelper({ key, type, options, targetResolver, onDefineData }, .
|
|
|
48
48
|
else {
|
|
49
49
|
(0, exports.defineDecorData)(key, Object.assign({ type }, options), Target);
|
|
50
50
|
value = Reflect.decorate(transforms, Target);
|
|
51
|
+
// If the class was wrapped/replaced, apply metadata to the new class too
|
|
52
|
+
if (value && value !== Target) {
|
|
53
|
+
(0, exports.defineDecorData)(key, Object.assign({ type }, options), value);
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
(0, tsyringe_1.injectable)()((0, object_util_1.$constructor)(target));
|
|
54
58
|
return value;
|
|
55
59
|
};
|
|
56
60
|
}
|
|
61
|
+
const METADATA_CACHE = new WeakMap();
|
|
57
62
|
const defineDecorData = (key, options, target, property, descriptor) => {
|
|
58
63
|
let value = options;
|
|
59
64
|
if (typeof options === "function") {
|
|
@@ -66,21 +71,52 @@ const defineDecorData = (key, options, target, property, descriptor) => {
|
|
|
66
71
|
else {
|
|
67
72
|
Reflect.defineMetadata(key, value, target);
|
|
68
73
|
}
|
|
74
|
+
// Update Cache
|
|
75
|
+
let targetCache = METADATA_CACHE.get(target);
|
|
76
|
+
if (!targetCache) {
|
|
77
|
+
targetCache = new Map();
|
|
78
|
+
METADATA_CACHE.set(target, targetCache);
|
|
79
|
+
}
|
|
80
|
+
targetCache.set(property ? `${key}:${property}` : key, value);
|
|
69
81
|
};
|
|
70
82
|
exports.defineDecorData = defineDecorData;
|
|
71
|
-
const getDecorData = (key, target, property) =>
|
|
72
|
-
?
|
|
73
|
-
|
|
83
|
+
const getDecorData = (key, target, property) => {
|
|
84
|
+
const cacheKey = property ? `${key}:${property}` : key;
|
|
85
|
+
const targetCache = METADATA_CACHE.get(target);
|
|
86
|
+
if (targetCache && targetCache.has(cacheKey)) {
|
|
87
|
+
return targetCache.get(cacheKey);
|
|
88
|
+
}
|
|
89
|
+
const value = property
|
|
90
|
+
? Reflect.getMetadata(key, target, property)
|
|
91
|
+
: Reflect.getMetadata(key, target);
|
|
92
|
+
if (value !== undefined) {
|
|
93
|
+
let tc = METADATA_CACHE.get(target);
|
|
94
|
+
if (!tc) {
|
|
95
|
+
tc = new Map();
|
|
96
|
+
METADATA_CACHE.set(target, tc);
|
|
97
|
+
}
|
|
98
|
+
tc.set(cacheKey, value);
|
|
99
|
+
}
|
|
100
|
+
return value;
|
|
101
|
+
};
|
|
74
102
|
exports.getDecorData = getDecorData;
|
|
75
|
-
const hasDecorData = (key, target, property) =>
|
|
76
|
-
?
|
|
77
|
-
|
|
103
|
+
const hasDecorData = (key, target, property) => {
|
|
104
|
+
const cacheKey = property ? `${key}:${property}` : key;
|
|
105
|
+
const targetCache = METADATA_CACHE.get(target);
|
|
106
|
+
if (targetCache && targetCache.has(cacheKey))
|
|
107
|
+
return true;
|
|
108
|
+
return property
|
|
109
|
+
? Reflect.hasMetadata(key, target, property)
|
|
110
|
+
: Reflect.hasMetadata(key, target);
|
|
111
|
+
};
|
|
78
112
|
exports.hasDecorData = hasDecorData;
|
|
79
113
|
const extractDecorData = (target) => {
|
|
80
114
|
const keys = Reflect.getMetadataKeys(target);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
115
|
+
const result = {};
|
|
116
|
+
for (let i = 0; i < keys.length; i++) {
|
|
117
|
+
const key = keys[i];
|
|
118
|
+
result[key] = (0, exports.getDecorData)(key, target);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
85
121
|
};
|
|
86
122
|
exports.extractDecorData = extractDecorData;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ImportType } from "../../decorators/types";
|
|
1
|
+
import { IHyperHooks, ImportType } from "../../decorators/types";
|
|
2
2
|
/**
|
|
3
3
|
* Prepare imports for the target class.
|
|
4
4
|
*
|
|
5
5
|
* @param target
|
|
6
6
|
* @param imports
|
|
7
7
|
*/
|
|
8
|
-
export declare function prepareImports(
|
|
8
|
+
export declare function prepareImports(_target: any, imports: ImportType[], hooks?: IHyperHooks, context?: any): Promise<void>;
|
|
@@ -11,35 +11,82 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.prepareImports = prepareImports;
|
|
13
13
|
const tsyringe_1 = require("tsyringe");
|
|
14
|
+
const lifecycle_helper_1 = require("./lifecycle.helper");
|
|
15
|
+
const decorator_base_1 = require("../decorator-base");
|
|
16
|
+
const constants_1 = require("../constants");
|
|
17
|
+
const message_bus_1 = require("../../common/message-bus");
|
|
14
18
|
/**
|
|
15
19
|
* Prepare imports for the target class.
|
|
16
20
|
*
|
|
17
21
|
* @param target
|
|
18
22
|
* @param imports
|
|
19
23
|
*/
|
|
20
|
-
function prepareImports(
|
|
24
|
+
function prepareImports(_target, imports, hooks, context) {
|
|
21
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
const isSingleton = ((_a = _class.isSingleton) === null || _a === void 0 ? void 0 : _a.call(_class)) === true;
|
|
28
|
-
if (isSingleton) {
|
|
29
|
-
if (isInitialized(_class))
|
|
30
|
-
continue;
|
|
31
|
-
tsyringe_1.container.registerInstance(service, _class);
|
|
26
|
+
const bus = tsyringe_1.container.resolve(message_bus_1.MessageBus);
|
|
27
|
+
yield Promise.all(imports.map((item) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
let token;
|
|
29
|
+
if (typeof item === "function" || typeof item === "string" || typeof item === "symbol") {
|
|
30
|
+
token = item;
|
|
32
31
|
}
|
|
33
|
-
if (typeof
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
32
|
+
else if (item && typeof item === "object" && "token" in item) {
|
|
33
|
+
token = item.token;
|
|
34
|
+
if (item.useClass) {
|
|
35
|
+
tsyringe_1.container.register(token, { useClass: item.useClass }, item.options);
|
|
36
|
+
}
|
|
37
|
+
else if ("useValue" in item) {
|
|
38
|
+
tsyringe_1.container.registerInstance(token, item.useValue);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
else if (item.useFactory) {
|
|
42
|
+
tsyringe_1.container.register(token, { useFactory: item.useFactory }, item.options);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
else if (item.useToken) {
|
|
46
|
+
tsyringe_1.container.register(token, { useToken: item.useToken }, item.options);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
37
49
|
}
|
|
38
|
-
|
|
50
|
+
if (!token)
|
|
51
|
+
return;
|
|
52
|
+
try {
|
|
53
|
+
const instance = tsyringe_1.container.resolve(token);
|
|
54
|
+
if (!instance)
|
|
55
|
+
return;
|
|
56
|
+
// Skip if already initialized to avoid double work/double subscription
|
|
57
|
+
const alreadyDone = (0, lifecycle_helper_1.isInitialized)(instance);
|
|
58
|
+
if (!alreadyDone) {
|
|
59
|
+
if (hooks === null || hooks === void 0 ? void 0 : hooks.onBeforeInit) {
|
|
60
|
+
yield hooks.onBeforeInit(instance, token, context);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
yield (0, lifecycle_helper_1.initializeInstance)(instance);
|
|
64
|
+
if (!alreadyDone) {
|
|
65
|
+
if (hooks === null || hooks === void 0 ? void 0 : hooks.onAfterInit) {
|
|
66
|
+
yield hooks.onAfterInit(instance, token, context);
|
|
67
|
+
}
|
|
68
|
+
// Handle singleton registration if it's a constructor and not registered
|
|
69
|
+
if (typeof token === "function" && !tsyringe_1.container.isRegistered(token)) {
|
|
70
|
+
const isSingleton = typeof instance.isSingleton === "function" ? instance.isSingleton() : true;
|
|
71
|
+
if (isSingleton) {
|
|
72
|
+
tsyringe_1.container.registerInstance(token, instance);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Discovery: Messaging (only on first init)
|
|
76
|
+
const messaging = (0, decorator_base_1.getDecorData)(constants_1.METADATA_KEYS.ON_MESSAGE, typeof token === "function" ? token : instance.constructor);
|
|
77
|
+
if (messaging === null || messaging === void 0 ? void 0 : messaging.length) {
|
|
78
|
+
messaging.forEach((msg) => {
|
|
79
|
+
bus.listen(msg.topic, instance[msg.propertyKey].bind(instance));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
// Skip dependencies that cannot be resolved automatically
|
|
86
|
+
// Log a warning to prevent silent failures in production
|
|
87
|
+
const name = typeof token === "function" ? token.name : String(token);
|
|
88
|
+
console.warn(`[HyperDecor] Warn: Could not resolve dependency for token "${name}". It might be missing injectable() or not exported correctly.`);
|
|
89
|
+
}
|
|
90
|
+
})));
|
|
39
91
|
});
|
|
40
92
|
}
|
|
41
|
-
////////////////////////
|
|
42
|
-
/// Utils
|
|
43
|
-
////////////////////////
|
|
44
|
-
const isInitialized = (target) => Reflect.get(target, "____initialized") === true;
|
|
45
|
-
const setInitialized = (target) => Reflect.set(target, "____initialized", true);
|
|
@@ -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
|
+
}
|
|
@@ -10,35 +10,31 @@ require("reflect-metadata");
|
|
|
10
10
|
* @param options Merge options (e.g., array handling).
|
|
11
11
|
*/
|
|
12
12
|
function mergeMetadata(target, source, keys, options = {}) {
|
|
13
|
-
for (
|
|
13
|
+
for (let i = 0; i < keys.length; i++) {
|
|
14
|
+
const key = keys[i];
|
|
14
15
|
const sourceMeta = Reflect.getMetadata(key, source);
|
|
15
|
-
const targetMeta = Reflect.getMetadata(key, target);
|
|
16
16
|
if (sourceMeta === undefined)
|
|
17
17
|
continue;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
mergedMeta = deepMerge(targetMeta, sourceMeta, options);
|
|
21
|
-
}
|
|
22
|
-
Reflect.defineMetadata(key, mergedMeta, target);
|
|
18
|
+
const targetMeta = Reflect.getMetadata(key, target);
|
|
19
|
+
Reflect.defineMetadata(key, targetMeta === undefined ? sourceMeta : deepMerge(targetMeta, sourceMeta, options), target);
|
|
23
20
|
}
|
|
24
21
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Performs a deep merge of two objects.
|
|
27
|
-
* @param target Target object.
|
|
28
|
-
* @param source Source object.
|
|
29
|
-
* @param options Merge options.
|
|
30
|
-
* @returns Merged object.
|
|
31
|
-
*/
|
|
32
22
|
function deepMerge(target, source, options) {
|
|
33
23
|
if (Array.isArray(target) && Array.isArray(source)) {
|
|
34
|
-
|
|
24
|
+
if (options.overwriteArrays)
|
|
25
|
+
return source;
|
|
26
|
+
// Faster deduplication for primitive arrays
|
|
27
|
+
const combined = target.concat(source);
|
|
28
|
+
return Array.from(new Set(combined));
|
|
35
29
|
}
|
|
36
|
-
if (typeof
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
if (source && typeof source === "object" && target && typeof target === "object") {
|
|
31
|
+
const result = Object.assign({}, target);
|
|
32
|
+
const sourceKeys = Object.keys(source);
|
|
33
|
+
for (let i = 0; i < sourceKeys.length; i++) {
|
|
34
|
+
const k = sourceKeys[i];
|
|
35
|
+
result[k] = deepMerge(result[k], source[k], options);
|
|
40
36
|
}
|
|
41
|
-
return
|
|
37
|
+
return result;
|
|
42
38
|
}
|
|
43
39
|
return source;
|
|
44
40
|
}
|
|
@@ -24,7 +24,8 @@ const middleware_transform_1 = __importDefault(require("../transform/middleware.
|
|
|
24
24
|
const tsyringe_1 = require("tsyringe");
|
|
25
25
|
const path_util_1 = require("../utils/path.util");
|
|
26
26
|
const imports_helper_1 = require("./imports.helper");
|
|
27
|
-
const
|
|
27
|
+
const message_bus_1 = require("../../common/message-bus");
|
|
28
|
+
const transport_1 = require("../../common/transport");
|
|
28
29
|
const if_router = (current) => {
|
|
29
30
|
if (!current || !((current === null || current === void 0 ? void 0 : current.prototype) instanceof hyper_express_1.Router))
|
|
30
31
|
return new hyper_express_1.Router();
|
|
@@ -71,12 +72,29 @@ function getData(target) {
|
|
|
71
72
|
*/
|
|
72
73
|
function prepareApplication(options, Target, app, log) {
|
|
73
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
-
var _a, _b;
|
|
75
|
+
var _a, _b, _c;
|
|
75
76
|
const data = getData(Target);
|
|
76
77
|
const prefix = (_a = options.prefix) !== null && _a !== void 0 ? _a : "/";
|
|
77
78
|
const imports = (_b = options.imports) !== null && _b !== void 0 ? _b : [];
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
// Register transports if provided, otherwise fallback to internal
|
|
80
|
+
const bus = tsyringe_1.container.resolve(message_bus_1.MessageBus);
|
|
81
|
+
if ((_c = options === null || options === void 0 ? void 0 : options.transports) === null || _c === void 0 ? void 0 : _c.length) {
|
|
82
|
+
options.transports.forEach((t) => bus.registerTransport(t));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
bus.registerTransport(new transport_1.InternalTransport());
|
|
86
|
+
}
|
|
87
|
+
let hooks = options.hooks;
|
|
88
|
+
if (typeof hooks === "function" && !(hooks instanceof hyper_express_1.Router)) {
|
|
89
|
+
if (hooks && "constructor" in hooks) {
|
|
90
|
+
if (tsyringe_1.container.isRegistered(hooks)) {
|
|
91
|
+
tsyringe_1.container.register(hooks, hooks);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
hooks = tsyringe_1.container.resolve(hooks);
|
|
95
|
+
}
|
|
96
|
+
const context = { target: Target, metadata: options, type: "app" };
|
|
97
|
+
yield (0, imports_helper_1.prepareImports)(Target, imports, hooks, context);
|
|
80
98
|
if (data.middlewares.length) {
|
|
81
99
|
app.use(...data.middlewares);
|
|
82
100
|
log("middleware", `${Target.name} with middlewares: ${data.middlewares
|
|
@@ -92,11 +110,11 @@ function prepareApplication(options, Target, app, log) {
|
|
|
92
110
|
app.use(middleware);
|
|
93
111
|
log("middleware", `${Target.name} with roles: ${data.roles.join(", ")}`);
|
|
94
112
|
});
|
|
95
|
-
const routers = yield Promise.all(options.modules.map((module) => __awaiter(this, void 0, void 0, function* () {
|
|
96
|
-
var _a, _b, _c
|
|
113
|
+
const routers = (yield Promise.all(options.modules.map((module) => __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
var _a, _b, _c;
|
|
97
115
|
const data = getData(module);
|
|
98
|
-
const path = (
|
|
99
|
-
const imports = (
|
|
116
|
+
const path = (_a = data.module) === null || _a === void 0 ? void 0 : _a.path;
|
|
117
|
+
const imports = (_c = (_b = data.module) === null || _b === void 0 ? void 0 : _b.imports) !== null && _c !== void 0 ? _c : [];
|
|
100
118
|
return prepareTarget({
|
|
101
119
|
target: module,
|
|
102
120
|
router: if_router(module),
|
|
@@ -105,10 +123,11 @@ function prepareApplication(options, Target, app, log) {
|
|
|
105
123
|
prefix: path,
|
|
106
124
|
imports: imports,
|
|
107
125
|
log,
|
|
126
|
+
hooks: hooks,
|
|
108
127
|
});
|
|
109
|
-
})));
|
|
128
|
+
})))).filter((r) => r.router);
|
|
110
129
|
routers.forEach(({ router, path }) => {
|
|
111
|
-
app.use((0, path_util_1.join)(prefix, path), router);
|
|
130
|
+
app.use((0, path_util_1.join)(prefix, path || "/"), router);
|
|
112
131
|
});
|
|
113
132
|
});
|
|
114
133
|
}
|
|
@@ -120,29 +139,43 @@ function prepareApplication(options, Target, app, log) {
|
|
|
120
139
|
* @returns
|
|
121
140
|
*/
|
|
122
141
|
function prepareTarget(_a) {
|
|
123
|
-
return __awaiter(this, arguments, void 0, function* ({ target, router, prefix
|
|
142
|
+
return __awaiter(this, arguments, void 0, function* ({ target, router, prefix, namespace = "", instance, imports = [], log, hooks, }) {
|
|
124
143
|
var _b, _c, _d, _e, _f, _g, _h, _j;
|
|
125
|
-
const _router = router !== null && router !== void 0 ? router : if_router(target);
|
|
126
144
|
const data = getData(target);
|
|
145
|
+
if (data.module) {
|
|
146
|
+
log("modules", `${namespace} { ${prefix || "/"} }`);
|
|
147
|
+
}
|
|
148
|
+
else if (data.controller) {
|
|
149
|
+
log("controllers", `${namespace} { ${prefix || "/"} }`);
|
|
150
|
+
}
|
|
127
151
|
const modules = (_c = (_b = data.module) === null || _b === void 0 ? void 0 : _b.modules) !== null && _c !== void 0 ? _c : [];
|
|
128
152
|
const controllers = (_e = (_d = data.module) === null || _d === void 0 ? void 0 : _d.controllers) !== null && _e !== void 0 ? _e : [];
|
|
129
|
-
const routes = (_f = data.routes) !== null && _f !== void 0 ? _f : [];
|
|
153
|
+
const routes = (_f = data.routes) !== null && _f !== void 0 ? _f : { routes: [] };
|
|
130
154
|
const middlewares = (_g = data.middlewares) !== null && _g !== void 0 ? _g : [];
|
|
131
155
|
const scopes = (_h = data.scopes) !== null && _h !== void 0 ? _h : [];
|
|
132
156
|
const roles = (_j = data.roles) !== null && _j !== void 0 ? _j : [];
|
|
157
|
+
const needsRouter = controllers.length > 0 ||
|
|
158
|
+
routes.routes.size > 0 ||
|
|
159
|
+
middlewares.length > 0 ||
|
|
160
|
+
scopes.length > 0 ||
|
|
161
|
+
roles.length > 0;
|
|
162
|
+
const _router = router !== null && router !== void 0 ? router : (needsRouter ? if_router(target) : undefined);
|
|
133
163
|
////////////////////////////////
|
|
134
164
|
/// Prepare Imports
|
|
135
165
|
////////////////////////////////
|
|
136
|
-
|
|
166
|
+
const context = { target: target, metadata: data, type: "target" };
|
|
167
|
+
yield (0, imports_helper_1.prepareImports)(target, imports, hooks, context);
|
|
137
168
|
////////////////////////////////
|
|
138
|
-
/// Attach Middlewares
|
|
169
|
+
/// Attach Middlewares & Security
|
|
139
170
|
////////////////////////////////
|
|
140
|
-
_router
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
171
|
+
if (_router) {
|
|
172
|
+
_router.use(...middlewares);
|
|
173
|
+
(0, scope_transfrom_1.default)(scopes, (middleware, scopes) => {
|
|
174
|
+
stores_1.ScopeStore.addAll(scopes);
|
|
175
|
+
_router.use(middleware);
|
|
176
|
+
});
|
|
177
|
+
(0, role_transform_1.default)(roles, (middleware) => _router.use(middleware));
|
|
178
|
+
}
|
|
146
179
|
////////////////////////////////
|
|
147
180
|
/// Prepare Modules
|
|
148
181
|
////////////////////////////////
|
|
@@ -150,15 +183,18 @@ function prepareTarget(_a) {
|
|
|
150
183
|
const moduleData = getData(module);
|
|
151
184
|
if (!moduleData.module)
|
|
152
185
|
return;
|
|
153
|
-
const
|
|
186
|
+
const res = yield prepareTarget({
|
|
154
187
|
target: module,
|
|
155
188
|
imports: moduleData.module.imports,
|
|
156
189
|
namespace: `${namespace}/${module.name}`,
|
|
157
190
|
prefix: moduleData.module.path,
|
|
158
191
|
instance: tsyringe_1.container.resolve(module),
|
|
159
192
|
log,
|
|
193
|
+
hooks,
|
|
160
194
|
});
|
|
161
|
-
|
|
195
|
+
if (res.router && _router) {
|
|
196
|
+
_router.use(res.path || "/", res.router);
|
|
197
|
+
}
|
|
162
198
|
}));
|
|
163
199
|
// ////////////////////////////////
|
|
164
200
|
// /// Prepare Controllers
|
|
@@ -168,32 +204,37 @@ function prepareTarget(_a) {
|
|
|
168
204
|
const controllerData = data.controller;
|
|
169
205
|
if (!controllerData)
|
|
170
206
|
return;
|
|
171
|
-
const
|
|
207
|
+
const res = yield prepareTarget({
|
|
172
208
|
target: controller,
|
|
173
209
|
namespace: `${namespace}/${controller.name}`,
|
|
174
210
|
prefix: controllerData.path,
|
|
175
211
|
imports: controllerData.imports,
|
|
176
212
|
instance: tsyringe_1.container.resolve(controller),
|
|
177
213
|
log,
|
|
214
|
+
hooks,
|
|
178
215
|
});
|
|
179
|
-
|
|
216
|
+
if (res.router && _router) {
|
|
217
|
+
_router.use(res.path || "/", res.router);
|
|
218
|
+
}
|
|
180
219
|
}));
|
|
181
220
|
////////////////////////////////
|
|
182
221
|
/// Prepare Routes
|
|
183
222
|
////////////////////////////////
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
223
|
+
if (_router) {
|
|
224
|
+
yield (0, object_util_1.$each)(Array.from(routes.routes), (route) => __awaiter(this, void 0, void 0, function* () {
|
|
225
|
+
if (typeof route !== "object")
|
|
226
|
+
return;
|
|
227
|
+
yield prepareRoutes({
|
|
228
|
+
target: target,
|
|
229
|
+
router: _router,
|
|
230
|
+
route,
|
|
231
|
+
namespace,
|
|
232
|
+
instance,
|
|
233
|
+
prefix: prefix || "/",
|
|
234
|
+
log,
|
|
235
|
+
});
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
197
238
|
return {
|
|
198
239
|
router: _router,
|
|
199
240
|
path: prefix,
|
|
@@ -232,21 +273,13 @@ function prepareRoutes(_a) {
|
|
|
232
273
|
}
|
|
233
274
|
else {
|
|
234
275
|
$fn.call(router, path, ...middlewares, (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
276
|
+
const len = params.length;
|
|
277
|
+
const args = new Array(len);
|
|
278
|
+
for (let i = 0; i < len; i++) {
|
|
279
|
+
args[i] = yield params[i].resolver(req, res);
|
|
280
|
+
}
|
|
281
|
+
return handler.apply(instance, args);
|
|
240
282
|
}));
|
|
241
283
|
}
|
|
242
284
|
});
|
|
243
285
|
}
|
|
244
|
-
function prepareServices(list) {
|
|
245
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
246
|
-
yield Promise.all(Array.from(list).map((service) => __awaiter(this, void 0, void 0, function* () {
|
|
247
|
-
const instance = tsyringe_1.container.resolve(service);
|
|
248
|
-
if (instance.onInit)
|
|
249
|
-
yield instance.onInit();
|
|
250
|
-
})));
|
|
251
|
-
});
|
|
252
|
-
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HyperAppMetadata, HyperModuleMetadata, HyperControllerMetadata, RouteMetadata } from "../../decorators/types";
|
|
2
|
+
export interface AppTree {
|
|
3
|
+
app: HyperAppMetadata & {
|
|
4
|
+
target: any;
|
|
5
|
+
fullPath: string;
|
|
6
|
+
};
|
|
7
|
+
modules: ModuleNode[];
|
|
8
|
+
}
|
|
9
|
+
export interface ModuleNode {
|
|
10
|
+
metadata: HyperModuleMetadata;
|
|
11
|
+
target: any;
|
|
12
|
+
fullPath: string;
|
|
13
|
+
modules: ModuleNode[];
|
|
14
|
+
controllers: ControllerNode[];
|
|
15
|
+
services: any[];
|
|
16
|
+
}
|
|
17
|
+
export interface ControllerNode {
|
|
18
|
+
metadata: HyperControllerMetadata;
|
|
19
|
+
target: any;
|
|
20
|
+
fullPath: string;
|
|
21
|
+
routes: RouteNode[];
|
|
22
|
+
services: any[];
|
|
23
|
+
}
|
|
24
|
+
export interface RouteNode extends RouteMetadata {
|
|
25
|
+
fullPath: string;
|
|
26
|
+
params: any[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the complete application metadata tree.
|
|
30
|
+
* This is useful for generating Swagger/OpenAPI documentation or graphing the app structure.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAppTree(Target: any): AppTree;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAppTree = getAppTree;
|
|
4
|
+
const decorator_base_1 = require("../decorator-base");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
const path_util_1 = require("../utils/path.util");
|
|
7
|
+
/**
|
|
8
|
+
* Extracts the complete application metadata tree.
|
|
9
|
+
* This is useful for generating Swagger/OpenAPI documentation or graphing the app structure.
|
|
10
|
+
*/
|
|
11
|
+
function getAppTree(Target) {
|
|
12
|
+
const appMetadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_APP, Target);
|
|
13
|
+
const prefix = (appMetadata === null || appMetadata === void 0 ? void 0 : appMetadata.prefix) || "/";
|
|
14
|
+
return {
|
|
15
|
+
app: Object.assign(Object.assign({}, appMetadata), { target: Target, fullPath: prefix }),
|
|
16
|
+
modules: ((appMetadata === null || appMetadata === void 0 ? void 0 : appMetadata.modules) || []).map(m => getModuleNode(m, prefix))
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function getModuleNode(Target, parentPath = "") {
|
|
20
|
+
const metadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_MODULE, Target);
|
|
21
|
+
const currentPath = (0, path_util_1.join)(parentPath, (metadata === null || metadata === void 0 ? void 0 : metadata.path) || "");
|
|
22
|
+
return {
|
|
23
|
+
metadata,
|
|
24
|
+
target: Target,
|
|
25
|
+
fullPath: currentPath,
|
|
26
|
+
modules: ((metadata === null || metadata === void 0 ? void 0 : metadata.modules) || []).map(m => getModuleNode(m, currentPath)),
|
|
27
|
+
controllers: ((metadata === null || metadata === void 0 ? void 0 : metadata.controllers) || []).map(c => getControllerNode(c, currentPath)),
|
|
28
|
+
services: ((metadata === null || metadata === void 0 ? void 0 : metadata.imports) || [])
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function getControllerNode(Target, parentPath = "") {
|
|
32
|
+
const metadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_TYPE_CONTROLLER, Target);
|
|
33
|
+
const routeList = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_ROUTE, Target);
|
|
34
|
+
const paramMetadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_PARAM, Target);
|
|
35
|
+
const currentPath = (0, path_util_1.join)(parentPath, (metadata === null || metadata === void 0 ? void 0 : metadata.path) || "");
|
|
36
|
+
const routes = Array.from((routeList === null || routeList === void 0 ? void 0 : routeList.routes) || []).map((route) => {
|
|
37
|
+
var _a;
|
|
38
|
+
const params = ((_a = paramMetadata === null || paramMetadata === void 0 ? void 0 : paramMetadata.params) === null || _a === void 0 ? void 0 : _a[route.propertyKey]) || [];
|
|
39
|
+
return Object.assign(Object.assign({}, route), { fullPath: (0, path_util_1.join)(currentPath, route.path), params });
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
metadata,
|
|
43
|
+
target: Target,
|
|
44
|
+
fullPath: currentPath,
|
|
45
|
+
routes,
|
|
46
|
+
services: (metadata === null || metadata === void 0 ? void 0 : metadata.imports) || []
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.default = middlewareTransformer;
|
|
4
4
|
const tsyringe_1 = require("tsyringe");
|
|
5
5
|
function middlewareTransformer(list) {
|
|
6
|
-
if (!(list === null || list === void 0 ? void 0 : list.length))
|
|
7
|
-
return [];
|
|
8
6
|
return list
|
|
9
7
|
.map((middleware) => {
|
|
10
8
|
if (isClass(middleware)) {
|
|
@@ -10,16 +10,16 @@ function roleTransform(list, callback) {
|
|
|
10
10
|
var _a;
|
|
11
11
|
if (isEmtpy)
|
|
12
12
|
return next();
|
|
13
|
-
const requestRoles =
|
|
14
|
-
if (requestRoles.
|
|
13
|
+
const requestRoles = (_a = (0, helpers_1.getRoles)(req)) !== null && _a !== void 0 ? _a : [];
|
|
14
|
+
if (requestRoles.length === 0 && isEmtpy)
|
|
15
15
|
return next();
|
|
16
|
-
if (requestRoles.
|
|
16
|
+
if (requestRoles.includes(constants_1.FULL_ACCESS))
|
|
17
17
|
return next();
|
|
18
|
-
const role = roles.some((scope) => requestRoles.
|
|
18
|
+
const role = roles.some((scope) => requestRoles.includes(scope.role));
|
|
19
19
|
if (role) {
|
|
20
20
|
return next();
|
|
21
21
|
}
|
|
22
|
-
return next(new exeptions_1.NotRoleException(`Only ${Array.from(names).join(", ")} can access this resource`,
|
|
22
|
+
return next(new exeptions_1.NotRoleException(`Only ${Array.from(names).join(", ")} can access this resource`, requestRoles, Array.from(names)));
|
|
23
23
|
};
|
|
24
24
|
if (names.size > 0 && callback) {
|
|
25
25
|
callback(middleware, roles, names);
|