@zenofolio/hyper-decor 1.0.60 → 1.0.62
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/debug.txt +1 -0
- 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 +79 -52
- package/dist/__internals/helpers/tree.helper.d.ts +32 -0
- package/dist/__internals/helpers/tree.helper.js +48 -0
- 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/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 +2 -0
- 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/index.d.ts +1 -0
- package/dist/decorators/index.js +1 -0
- package/dist/decorators/types.d.ts +19 -3
- package/dist/index.d.ts +7 -0
- package/dist/index.js +9 -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
package/debug.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
State: class-before-dep-ok
|
|
@@ -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,37 @@ 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);
|
|
127
145
|
const modules = (_c = (_b = data.module) === null || _b === void 0 ? void 0 : _b.modules) !== null && _c !== void 0 ? _c : [];
|
|
128
146
|
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 : [];
|
|
147
|
+
const routes = (_f = data.routes) !== null && _f !== void 0 ? _f : { routes: [] };
|
|
130
148
|
const middlewares = (_g = data.middlewares) !== null && _g !== void 0 ? _g : [];
|
|
131
149
|
const scopes = (_h = data.scopes) !== null && _h !== void 0 ? _h : [];
|
|
132
150
|
const roles = (_j = data.roles) !== null && _j !== void 0 ? _j : [];
|
|
151
|
+
const needsRouter = controllers.length > 0 ||
|
|
152
|
+
routes.routes.size > 0 ||
|
|
153
|
+
middlewares.length > 0 ||
|
|
154
|
+
scopes.length > 0 ||
|
|
155
|
+
roles.length > 0;
|
|
156
|
+
const _router = router !== null && router !== void 0 ? router : (needsRouter ? if_router(target) : undefined);
|
|
133
157
|
////////////////////////////////
|
|
134
158
|
/// Prepare Imports
|
|
135
159
|
////////////////////////////////
|
|
136
|
-
|
|
160
|
+
const context = { target: target, metadata: data, type: "target" };
|
|
161
|
+
yield (0, imports_helper_1.prepareImports)(target, imports, hooks, context);
|
|
137
162
|
////////////////////////////////
|
|
138
|
-
/// Attach Middlewares
|
|
163
|
+
/// Attach Middlewares & Security
|
|
139
164
|
////////////////////////////////
|
|
140
|
-
_router
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
if (_router) {
|
|
166
|
+
_router.use(...middlewares);
|
|
167
|
+
(0, scope_transfrom_1.default)(scopes, (middleware, scopes) => {
|
|
168
|
+
stores_1.ScopeStore.addAll(scopes);
|
|
169
|
+
_router.use(middleware);
|
|
170
|
+
});
|
|
171
|
+
(0, role_transform_1.default)(roles, (middleware) => _router.use(middleware));
|
|
172
|
+
}
|
|
146
173
|
////////////////////////////////
|
|
147
174
|
/// Prepare Modules
|
|
148
175
|
////////////////////////////////
|
|
@@ -150,15 +177,18 @@ function prepareTarget(_a) {
|
|
|
150
177
|
const moduleData = getData(module);
|
|
151
178
|
if (!moduleData.module)
|
|
152
179
|
return;
|
|
153
|
-
const
|
|
180
|
+
const res = yield prepareTarget({
|
|
154
181
|
target: module,
|
|
155
182
|
imports: moduleData.module.imports,
|
|
156
183
|
namespace: `${namespace}/${module.name}`,
|
|
157
184
|
prefix: moduleData.module.path,
|
|
158
185
|
instance: tsyringe_1.container.resolve(module),
|
|
159
186
|
log,
|
|
187
|
+
hooks,
|
|
160
188
|
});
|
|
161
|
-
|
|
189
|
+
if (res.router && _router) {
|
|
190
|
+
_router.use(res.path || "/", res.router);
|
|
191
|
+
}
|
|
162
192
|
}));
|
|
163
193
|
// ////////////////////////////////
|
|
164
194
|
// /// Prepare Controllers
|
|
@@ -168,32 +198,37 @@ function prepareTarget(_a) {
|
|
|
168
198
|
const controllerData = data.controller;
|
|
169
199
|
if (!controllerData)
|
|
170
200
|
return;
|
|
171
|
-
const
|
|
201
|
+
const res = yield prepareTarget({
|
|
172
202
|
target: controller,
|
|
173
203
|
namespace: `${namespace}/${controller.name}`,
|
|
174
204
|
prefix: controllerData.path,
|
|
175
205
|
imports: controllerData.imports,
|
|
176
206
|
instance: tsyringe_1.container.resolve(controller),
|
|
177
207
|
log,
|
|
208
|
+
hooks,
|
|
178
209
|
});
|
|
179
|
-
|
|
210
|
+
if (res.router && _router) {
|
|
211
|
+
_router.use(res.path || "/", res.router);
|
|
212
|
+
}
|
|
180
213
|
}));
|
|
181
214
|
////////////////////////////////
|
|
182
215
|
/// Prepare Routes
|
|
183
216
|
////////////////////////////////
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
217
|
+
if (_router) {
|
|
218
|
+
yield (0, object_util_1.$each)(Array.from(routes.routes), (route) => __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
if (typeof route !== "object")
|
|
220
|
+
return;
|
|
221
|
+
yield prepareRoutes({
|
|
222
|
+
target: target,
|
|
223
|
+
router: _router,
|
|
224
|
+
route,
|
|
225
|
+
namespace,
|
|
226
|
+
instance,
|
|
227
|
+
prefix: prefix || "/",
|
|
228
|
+
log,
|
|
229
|
+
});
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
197
232
|
return {
|
|
198
233
|
router: _router,
|
|
199
234
|
path: prefix,
|
|
@@ -232,21 +267,13 @@ function prepareRoutes(_a) {
|
|
|
232
267
|
}
|
|
233
268
|
else {
|
|
234
269
|
$fn.call(router, path, ...middlewares, (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
270
|
+
const len = params.length;
|
|
271
|
+
const args = new Array(len);
|
|
272
|
+
for (let i = 0; i < len; i++) {
|
|
273
|
+
args[i] = yield params[i].resolver(req, res);
|
|
274
|
+
}
|
|
275
|
+
return handler.apply(instance, args);
|
|
240
276
|
}));
|
|
241
277
|
}
|
|
242
278
|
});
|
|
243
279
|
}
|
|
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
|
+
}
|
|
@@ -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);
|
|
@@ -14,11 +14,10 @@ function scopeTransfrom(listScopes, ...callback) {
|
|
|
14
14
|
if (!userScopesRaw || userScopesRaw.length === 0) {
|
|
15
15
|
return next(new exeptions_1.NotScopeException(`FORBIDDEN`, [], Array.from(scopeNames)));
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
if (userScopes.has(constants_1.FULL_ACCESS))
|
|
17
|
+
if (userScopesRaw.includes(constants_1.FULL_ACCESS))
|
|
19
18
|
return next();
|
|
20
19
|
for (const scope of scopes) {
|
|
21
|
-
if (!
|
|
20
|
+
if (!userScopesRaw.includes(scope.scope)) {
|
|
22
21
|
return next(new exeptions_1.NotScopeException((_a = scope.message) !== null && _a !== void 0 ? _a : `FORBIDDEN`, userScopesRaw, Array.from(scopeNames)));
|
|
23
22
|
}
|
|
24
23
|
}
|