@zenofolio/hyper-decor 1.0.76 → 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/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
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractDecorData = exports.hasDecorData = exports.getDecorData = exports.defineDecorData = void 0;
|
|
4
|
-
exports.DecoratorHelper = DecoratorHelper;
|
|
5
|
-
require("reflect-metadata");
|
|
6
|
-
const tsyringe_1 = require("tsyringe");
|
|
7
|
-
const object_util_1 = require("./utils/object.util");
|
|
8
|
-
function DecoratorHelper({ key, type, options, targetResolver, onDefineData }, ...transformers) {
|
|
9
|
-
return (target, propertyKey, descriptor) => {
|
|
10
|
-
const isProperty = !!propertyKey;
|
|
11
|
-
const isMethod = !!descriptor;
|
|
12
|
-
let _options = options;
|
|
13
|
-
const Target = targetResolver
|
|
14
|
-
? targetResolver(target, propertyKey, descriptor)
|
|
15
|
-
: target;
|
|
16
|
-
if (options instanceof Function) {
|
|
17
|
-
const data = (0, exports.getDecorData)(key, Target);
|
|
18
|
-
const optionsResolver = options;
|
|
19
|
-
const value = optionsResolver(data, Target, propertyKey, descriptor);
|
|
20
|
-
if (value)
|
|
21
|
-
_options = Object.assign(Object.assign({}, _options), value);
|
|
22
|
-
}
|
|
23
|
-
if (onDefineData) {
|
|
24
|
-
onDefineData({
|
|
25
|
-
key,
|
|
26
|
-
options: Object.assign({ type }, _options),
|
|
27
|
-
target: Target,
|
|
28
|
-
property: propertyKey,
|
|
29
|
-
descriptor,
|
|
30
|
-
}, (data) => {
|
|
31
|
-
(0, exports.defineDecorData)(key, Object.assign({ type }, data), Target);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
(0, exports.defineDecorData)(key, Object.assign({ type }, _options), Target);
|
|
36
|
-
}
|
|
37
|
-
let value = Target;
|
|
38
|
-
if (transformers.length) {
|
|
39
|
-
const transforms = transformers.map((fn) => fn.bind(Target, _options));
|
|
40
|
-
if (isProperty) {
|
|
41
|
-
(0, exports.defineDecorData)(key, Object.assign({ type }, options), Target, propertyKey);
|
|
42
|
-
value = Reflect.decorate(transforms, Target, propertyKey);
|
|
43
|
-
}
|
|
44
|
-
else if (isMethod) {
|
|
45
|
-
(0, exports.defineDecorData)(key, Object.assign({ type }, options), Target);
|
|
46
|
-
value = Reflect.decorate(transforms, Target, propertyKey, descriptor);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
(0, exports.defineDecorData)(key, Object.assign({ type }, options), Target);
|
|
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
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
(0, tsyringe_1.injectable)()((0, object_util_1.$constructor)(target));
|
|
58
|
-
return value;
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const METADATA_CACHE = new WeakMap();
|
|
62
|
-
const defineDecorData = (key, options, target, property, descriptor) => {
|
|
63
|
-
let value = options;
|
|
64
|
-
if (typeof options === "function" && !(options.prototype && options.prototype.constructor === options)) {
|
|
65
|
-
const old = (0, exports.getDecorData)(key, target, property);
|
|
66
|
-
value = Object.assign(Object.assign({}, old), options(old, target, property, descriptor));
|
|
67
|
-
}
|
|
68
|
-
if (property) {
|
|
69
|
-
Reflect.defineMetadata(key, value, target, property);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
Reflect.defineMetadata(key, value, target);
|
|
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);
|
|
81
|
-
};
|
|
82
|
-
exports.defineDecorData = defineDecorData;
|
|
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
|
-
};
|
|
102
|
-
exports.getDecorData = getDecorData;
|
|
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
|
-
};
|
|
112
|
-
exports.hasDecorData = hasDecorData;
|
|
113
|
-
const extractDecorData = (target) => {
|
|
114
|
-
const keys = Reflect.getMetadataKeys(target);
|
|
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;
|
|
121
|
-
};
|
|
122
|
-
exports.extractDecorData = extractDecorData;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { IHyperHooks, ImportType } from "../../decorators/types";
|
|
2
|
-
/**
|
|
3
|
-
* Prepare imports for the target class.
|
|
4
|
-
*
|
|
5
|
-
* @param target
|
|
6
|
-
* @param imports
|
|
7
|
-
*/
|
|
8
|
-
export declare function prepareImports(_target: any, imports: ImportType[], hooks?: IHyperHooks, context?: any): Promise<void>;
|
|
@@ -1,92 +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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.prepareImports = prepareImports;
|
|
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");
|
|
18
|
-
/**
|
|
19
|
-
* Prepare imports for the target class.
|
|
20
|
-
*
|
|
21
|
-
* @param target
|
|
22
|
-
* @param imports
|
|
23
|
-
*/
|
|
24
|
-
function prepareImports(_target, imports, hooks, context) {
|
|
25
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
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;
|
|
31
|
-
}
|
|
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
|
-
}
|
|
49
|
-
}
|
|
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
|
-
})));
|
|
91
|
-
});
|
|
92
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
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: Record<string, ModuleNode>;
|
|
8
|
-
paths: Record<string, RouteNode[]>;
|
|
9
|
-
openapi?: any;
|
|
10
|
-
}
|
|
11
|
-
export interface ModuleNode {
|
|
12
|
-
metadata: HyperModuleMetadata;
|
|
13
|
-
target: any;
|
|
14
|
-
fullPath: string;
|
|
15
|
-
modules: Record<string, ModuleNode>;
|
|
16
|
-
controllers: Record<string, ControllerNode>;
|
|
17
|
-
services: any[];
|
|
18
|
-
openapi?: any;
|
|
19
|
-
}
|
|
20
|
-
export interface ControllerNode {
|
|
21
|
-
metadata: HyperControllerMetadata;
|
|
22
|
-
target: any;
|
|
23
|
-
fullPath: string;
|
|
24
|
-
routes: RouteNode[];
|
|
25
|
-
services: any[];
|
|
26
|
-
openapi?: any;
|
|
27
|
-
}
|
|
28
|
-
export interface RouteNode extends RouteMetadata {
|
|
29
|
-
fullPath: string;
|
|
30
|
-
params: any[];
|
|
31
|
-
openapi?: any;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Extracts the complete application metadata tree.
|
|
35
|
-
*/
|
|
36
|
-
export declare function getAppTree(Target: any): AppTree;
|
|
@@ -1,81 +0,0 @@
|
|
|
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
|
-
const class_collector_1 = require("../../lib/openapi/collectors/class.collector");
|
|
8
|
-
const metadata_registry_1 = require("../../lib/openapi/metadata.registry");
|
|
9
|
-
/**
|
|
10
|
-
* Extracts the complete application metadata tree.
|
|
11
|
-
*/
|
|
12
|
-
function getAppTree(Target) {
|
|
13
|
-
const appMetadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_APP, Target);
|
|
14
|
-
const prefix = (appMetadata === null || appMetadata === void 0 ? void 0 : appMetadata.prefix) || "/";
|
|
15
|
-
const tree = {
|
|
16
|
-
app: Object.assign(Object.assign({}, appMetadata), { target: Target, fullPath: prefix }),
|
|
17
|
-
modules: {},
|
|
18
|
-
paths: {}
|
|
19
|
-
};
|
|
20
|
-
((appMetadata === null || appMetadata === void 0 ? void 0 : appMetadata.modules) || []).forEach(m => {
|
|
21
|
-
const node = getModuleNode(m, prefix, tree.paths);
|
|
22
|
-
tree.modules[m.name] = node;
|
|
23
|
-
});
|
|
24
|
-
// Apply tree processors
|
|
25
|
-
metadata_registry_1.openApiRegistry.getProcessors().forEach(processor => processor(tree));
|
|
26
|
-
return tree;
|
|
27
|
-
}
|
|
28
|
-
function getModuleNode(Target, parentPath = "", globalPaths = {}) {
|
|
29
|
-
const metadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_MODULE, Target);
|
|
30
|
-
const currentPath = (0, path_util_1.join)(parentPath, (metadata === null || metadata === void 0 ? void 0 : metadata.path) || "");
|
|
31
|
-
const openapi = (0, class_collector_1.collectClassMetadata)(Target);
|
|
32
|
-
const node = {
|
|
33
|
-
metadata,
|
|
34
|
-
target: Target,
|
|
35
|
-
fullPath: currentPath,
|
|
36
|
-
modules: {},
|
|
37
|
-
controllers: {},
|
|
38
|
-
services: ((metadata === null || metadata === void 0 ? void 0 : metadata.imports) || []),
|
|
39
|
-
openapi
|
|
40
|
-
};
|
|
41
|
-
((metadata === null || metadata === void 0 ? void 0 : metadata.modules) || []).forEach(m => {
|
|
42
|
-
node.modules[m.name] = getModuleNode(m, currentPath, globalPaths);
|
|
43
|
-
});
|
|
44
|
-
((metadata === null || metadata === void 0 ? void 0 : metadata.controllers) || []).forEach(c => {
|
|
45
|
-
node.controllers[c.name] = getControllerNode(c, currentPath, globalPaths);
|
|
46
|
-
});
|
|
47
|
-
return node;
|
|
48
|
-
}
|
|
49
|
-
function getControllerNode(Target, parentPath = "", globalPaths = {}) {
|
|
50
|
-
var _a;
|
|
51
|
-
const metadata = (0, decorator_base_1.getDecorData)(constants_1.KEY_TYPE_CONTROLLER, Target);
|
|
52
|
-
const routeList = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_ROUTE, Target);
|
|
53
|
-
// Param metadata can be on the constructor or the prototype
|
|
54
|
-
const paramMetadata = (_a = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_PARAM, Target)) !== null && _a !== void 0 ? _a : (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_PARAM, Target.prototype);
|
|
55
|
-
const currentPath = (0, path_util_1.join)(parentPath, (metadata === null || metadata === void 0 ? void 0 : metadata.path) || "");
|
|
56
|
-
const openapi = (0, class_collector_1.collectClassMetadata)(Target);
|
|
57
|
-
const routes = Array.from((routeList === null || routeList === void 0 ? void 0 : routeList.routes) || []).map((route) => {
|
|
58
|
-
var _a, _b, _c, _d, _e, _f;
|
|
59
|
-
// Also try to get params from the handler itself if not in aggregated metadata
|
|
60
|
-
const params = (_e = (_b = (_a = paramMetadata === null || paramMetadata === void 0 ? void 0 : paramMetadata.params) === null || _a === void 0 ? void 0 : _a[route.propertyKey]) !== null && _b !== void 0 ? _b : (_d = (_c = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_PARAM, route.handler)) === null || _c === void 0 ? void 0 : _c.params) === null || _d === void 0 ? void 0 : _d[route.propertyKey]) !== null && _e !== void 0 ? _e : [];
|
|
61
|
-
const fullPath = (0, path_util_1.join)(currentPath, route.path);
|
|
62
|
-
// Get OpenAPI metadata for the method
|
|
63
|
-
const methodOpenApi = ((_f = openapi.methods) === null || _f === void 0 ? void 0 : _f[route.propertyKey]) || {};
|
|
64
|
-
const routeNode = Object.assign(Object.assign({}, route), { fullPath,
|
|
65
|
-
params, openapi: methodOpenApi });
|
|
66
|
-
// Add to global paths map
|
|
67
|
-
if (!globalPaths[fullPath]) {
|
|
68
|
-
globalPaths[fullPath] = [];
|
|
69
|
-
}
|
|
70
|
-
globalPaths[fullPath].push(routeNode);
|
|
71
|
-
return routeNode;
|
|
72
|
-
});
|
|
73
|
-
return {
|
|
74
|
-
metadata,
|
|
75
|
-
target: Target,
|
|
76
|
-
fullPath: currentPath,
|
|
77
|
-
routes,
|
|
78
|
-
services: (metadata === null || metadata === void 0 ? void 0 : metadata.imports) || [],
|
|
79
|
-
openapi
|
|
80
|
-
};
|
|
81
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
interface MetadataStoreOptions {
|
|
2
|
-
target: any;
|
|
3
|
-
propertyKey?: string | symbol;
|
|
4
|
-
descriptorOrIndex?: any;
|
|
5
|
-
}
|
|
6
|
-
declare class MetadatStore {
|
|
7
|
-
static define(key: string | symbol, value: any, { target, propertyKey }: MetadataStoreOptions): void;
|
|
8
|
-
static get<T>(key: string | symbol, { target, propertyKey }: MetadataStoreOptions, def: T): T;
|
|
9
|
-
static list<T extends any = any>(key: string | symbol, { target, propertyKey }: MetadataStoreOptions): {
|
|
10
|
-
has: () => boolean;
|
|
11
|
-
get: () => never[];
|
|
12
|
-
set: (...value: T[]) => void;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export default MetadatStore;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const object_util_1 = require("../utils/object.util");
|
|
4
|
-
class MetadatStore {
|
|
5
|
-
static define(key, value, { target, propertyKey }) {
|
|
6
|
-
if (target && typeof propertyKey === "string") {
|
|
7
|
-
Reflect.defineMetadata(key, value, Reflect.get(target, propertyKey));
|
|
8
|
-
}
|
|
9
|
-
else {
|
|
10
|
-
Reflect.defineMetadata(key, value, (0, object_util_1.$constructor)(target));
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
static get(key, { target, propertyKey }, def) {
|
|
14
|
-
if (target && typeof propertyKey === "string") {
|
|
15
|
-
return Reflect.getMetadata(key, Reflect.get(target, propertyKey)) || def;
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
return Reflect.getMetadata(key, (0, object_util_1.$constructor)(target)) || def;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
static list(key, { target, propertyKey }) {
|
|
22
|
-
return {
|
|
23
|
-
has: () => {
|
|
24
|
-
return this.get(key, { target, propertyKey }, []).length > 0;
|
|
25
|
-
},
|
|
26
|
-
get: () => {
|
|
27
|
-
return this.get(key, { target, propertyKey }, []);
|
|
28
|
-
},
|
|
29
|
-
set: (...value) => {
|
|
30
|
-
const list = this.get(key, { target, propertyKey }, []);
|
|
31
|
-
list.push(...value);
|
|
32
|
-
this.define(key, list, { target, propertyKey });
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
exports.default = MetadatStore;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const serviceStore: Set<any>;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Request } from "hyper-express/types";
|
|
2
|
-
/**
|
|
3
|
-
* File upload restrictions
|
|
4
|
-
*/
|
|
5
|
-
export interface FileUploadRestrictions {
|
|
6
|
-
allowedMimeTypes: string[];
|
|
7
|
-
maxFileSize: number;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* File restrictions resolver
|
|
11
|
-
*/
|
|
12
|
-
export type FileRestrictions = FileUploadRestrictions | ((request: Request) => FileUploadRestrictions | Promise<FileUploadRestrictions>);
|
|
13
|
-
/**
|
|
14
|
-
* File decorator options
|
|
15
|
-
*/
|
|
16
|
-
export interface FileOptions {
|
|
17
|
-
fieldName: string | string[];
|
|
18
|
-
restrictions?: FileRestrictions;
|
|
19
|
-
required?: boolean;
|
|
20
|
-
}
|
|
21
|
-
export interface UploadedFile {
|
|
22
|
-
field: string;
|
|
23
|
-
name: string;
|
|
24
|
-
filename: string;
|
|
25
|
-
mimeType: string;
|
|
26
|
-
size: number;
|
|
27
|
-
extension: string;
|
|
28
|
-
buffer: Buffer;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Decorator to extract file from the request
|
|
32
|
-
*/
|
|
33
|
-
export declare const File: {
|
|
34
|
-
(options: FileOptions | string): ParameterDecorator;
|
|
35
|
-
options(options: FileOptions, required?: boolean): (fieldName: string | string[]) => ParameterDecorator;
|
|
36
|
-
restrictions(restrictions: FileRestrictions): (fieldName: string | string[], required?: boolean) => ParameterDecorator;
|
|
37
|
-
};
|
package/dist/decorators/File.js
DELETED
|
@@ -1,167 +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 __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
-
var m = o[Symbol.asyncIterator], i;
|
|
14
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
-
};
|
|
18
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.File = void 0;
|
|
23
|
-
const Http_1 = require("./Http");
|
|
24
|
-
const HyperFileException_1 = __importDefault(require("../exeptions/HyperFileException"));
|
|
25
|
-
/**
|
|
26
|
-
* Decorator to extract file from the request
|
|
27
|
-
*/
|
|
28
|
-
const File = (options) => {
|
|
29
|
-
const _options = typeof options === "string" ? { fieldName: options } : options;
|
|
30
|
-
return (0, Http_1.createCustomRequestDecorator)("File", (request) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
-
var _a;
|
|
32
|
-
const { allowedMimeTypes, maxFileSize } = yield resolveRestrictions(request, _options.restrictions);
|
|
33
|
-
const passTypes = allowedMimeTypes.includes("*") || allowedMimeTypes.length === 0;
|
|
34
|
-
const passSize = maxFileSize === Infinity;
|
|
35
|
-
const contentType = (_a = request.headers) === null || _a === void 0 ? void 0 : _a["content-type"];
|
|
36
|
-
const isMultipart = contentType === null || contentType === void 0 ? void 0 : contentType.includes("multipart/form-data");
|
|
37
|
-
if (!isMultipart) {
|
|
38
|
-
throw new HyperFileException_1.default("Invalid request, expected multipart form data", {
|
|
39
|
-
fieldName: _options.fieldName,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
const files = yield extractFiles(request, {
|
|
43
|
-
maxSize: passSize ? undefined : maxFileSize,
|
|
44
|
-
mimeTypes: passTypes ? undefined : allowedMimeTypes,
|
|
45
|
-
requires: _options.required
|
|
46
|
-
? Array.isArray(_options.fieldName)
|
|
47
|
-
? _options.fieldName
|
|
48
|
-
: [_options.fieldName]
|
|
49
|
-
: undefined,
|
|
50
|
-
requireName: true,
|
|
51
|
-
});
|
|
52
|
-
return Array.isArray(_options.fieldName)
|
|
53
|
-
? files
|
|
54
|
-
: files[_options.fieldName];
|
|
55
|
-
}));
|
|
56
|
-
};
|
|
57
|
-
exports.File = File;
|
|
58
|
-
exports.File.options = (options, required = false) => {
|
|
59
|
-
return (fieldName) => {
|
|
60
|
-
return (0, exports.File)(Object.assign(Object.assign({}, options), { required, fieldName }));
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
exports.File.restrictions = (restrictions) => {
|
|
64
|
-
return (fieldName, required = false) => {
|
|
65
|
-
return (0, exports.File)({ fieldName, restrictions, required });
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
const resolveRestrictions = (request, restrictions) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
-
if (typeof restrictions === "function") {
|
|
70
|
-
return yield restrictions(request);
|
|
71
|
-
}
|
|
72
|
-
return (restrictions !== null && restrictions !== void 0 ? restrictions : {
|
|
73
|
-
allowedMimeTypes: ["*"],
|
|
74
|
-
maxFileSize: Infinity,
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
/**
|
|
78
|
-
* Extract files from a request with validation and secure streaming.
|
|
79
|
-
*/
|
|
80
|
-
const extractFiles = (request, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
|
-
var _a;
|
|
82
|
-
const filesMap = {};
|
|
83
|
-
// Track if we are already over total limit (Content-Length check as first line of defense)
|
|
84
|
-
const totalLength = Number((_a = request.headers) === null || _a === void 0 ? void 0 : _a["content-length"]);
|
|
85
|
-
if ((options === null || options === void 0 ? void 0 : options.maxSize) && !isNaN(totalLength) && totalLength > options.maxSize + 1024 * 10) { // Buffer for boundaries
|
|
86
|
-
// Content-Length is significantly larger than allowed file size
|
|
87
|
-
// We don't throw yet because multipart might have multiple files or large fields
|
|
88
|
-
}
|
|
89
|
-
yield request.multipart((field) => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
-
var _a, e_1, _b, _c;
|
|
91
|
-
var _d, _e;
|
|
92
|
-
if (field.file && field.file.stream) {
|
|
93
|
-
const chunks = [];
|
|
94
|
-
let totalRead = 0;
|
|
95
|
-
try {
|
|
96
|
-
// Safe stream reading with early exit
|
|
97
|
-
for (var _f = true, _g = __asyncValues(field.file.stream), _h; _h = yield _g.next(), _a = _h.done, !_a; _f = true) {
|
|
98
|
-
_c = _h.value;
|
|
99
|
-
_f = false;
|
|
100
|
-
const chunk = _c;
|
|
101
|
-
totalRead += chunk.length;
|
|
102
|
-
if ((options === null || options === void 0 ? void 0 : options.maxSize) && totalRead > options.maxSize) {
|
|
103
|
-
throw new HyperFileException_1.default(`File '${field.name}' exceeds the maximum limit of ${options.maxSize} bytes`, { field: field.name, maxSize: options.maxSize });
|
|
104
|
-
}
|
|
105
|
-
chunks.push(chunk);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
109
|
-
finally {
|
|
110
|
-
try {
|
|
111
|
-
if (!_f && !_a && (_b = _g.return)) yield _b.call(_g);
|
|
112
|
-
}
|
|
113
|
-
finally { if (e_1) throw e_1.error; }
|
|
114
|
-
}
|
|
115
|
-
const bufferFile = Buffer.concat(chunks);
|
|
116
|
-
const { fileTypeFromBuffer } = yield import("file-type");
|
|
117
|
-
const type = yield fileTypeFromBuffer(bufferFile);
|
|
118
|
-
const mimeType = (type === null || type === void 0 ? void 0 : type.mime) || "unknown/unrecognized";
|
|
119
|
-
const extension = (type === null || type === void 0 ? void 0 : type.ext) || "bin";
|
|
120
|
-
// Validate MIME type early if unrecognized
|
|
121
|
-
if (!type && (options === null || options === void 0 ? void 0 : options.mimeTypes) && options.mimeTypes.length > 0) {
|
|
122
|
-
throw new HyperFileException_1.default(`Invalid file type for field '${field.name}'. Could not recognize file signature. Expected one of: ${options.mimeTypes.join(", ")}`, { field: field.name, allowedMimeTypes: options.mimeTypes });
|
|
123
|
-
}
|
|
124
|
-
// Validate MIME type if recognized
|
|
125
|
-
if ((options === null || options === void 0 ? void 0 : options.mimeTypes) && !options.mimeTypes.includes(mimeType)) {
|
|
126
|
-
throw new HyperFileException_1.default(`Invalid file type for field '${field.name}'. Expected: ${options.mimeTypes.join(", ")}, Received: ${mimeType}`, {
|
|
127
|
-
field: field.name,
|
|
128
|
-
allowedMimeTypes: options.mimeTypes,
|
|
129
|
-
receivedMimeType: mimeType,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
if ((options === null || options === void 0 ? void 0 : options.requireName) && !((_d = field.file) === null || _d === void 0 ? void 0 : _d.name)) {
|
|
133
|
-
throw new HyperFileException_1.default(`File name is required for field '${field.name}'`, {
|
|
134
|
-
field: field.name,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
// Secure filename resolution
|
|
138
|
-
const rawName = ((_e = field.file) === null || _e === void 0 ? void 0 : _e.name) || field.name;
|
|
139
|
-
// Sanitize: remove null bytes, path traversal sequences, and extract base name
|
|
140
|
-
const sanitizedBase = rawName.replace(/\0/g, "").split(/[\\/]/).pop() || "file";
|
|
141
|
-
const nameOnly = sanitizedBase.includes(".")
|
|
142
|
-
? sanitizedBase.substring(0, sanitizedBase.lastIndexOf("."))
|
|
143
|
-
: sanitizedBase;
|
|
144
|
-
const filename = `${nameOnly}.${extension}`;
|
|
145
|
-
filesMap[field.name] = {
|
|
146
|
-
field: field.name,
|
|
147
|
-
name: nameOnly,
|
|
148
|
-
filename: filename,
|
|
149
|
-
extension: extension,
|
|
150
|
-
size: bufferFile.byteLength,
|
|
151
|
-
mimeType: mimeType,
|
|
152
|
-
buffer: bufferFile,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
}));
|
|
156
|
-
// Check for required files
|
|
157
|
-
if (options === null || options === void 0 ? void 0 : options.requires) {
|
|
158
|
-
for (const required of options.requires) {
|
|
159
|
-
if (!filesMap[required]) {
|
|
160
|
-
throw new HyperFileException_1.default(`File "${required}" is required`, {
|
|
161
|
-
required,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return filesMap;
|
|
167
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ParameterResolver } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Get the value of a key from the request object
|
|
4
|
-
*
|
|
5
|
-
* @param key
|
|
6
|
-
* @returns
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Get the value of a key from the request object or transform the entire query.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* \@Query('id')
|
|
13
|
-
* \@Query('id', IntSchema)
|
|
14
|
-
* \@Query(UserQueryDto)
|
|
15
|
-
*/
|
|
16
|
-
export declare function Query(keyOrSchema?: string | any, schemaOrTransform?: any): any;
|
|
17
|
-
export declare function Body(keyOrSchema?: string | any, schemaOrTransform?: any): any;
|
|
18
|
-
export declare function Param(keyOrSchema: string | any, schemaOrTransform?: any): any;
|
|
19
|
-
export declare function Headers(keyOrSchema?: string | any, schemaOrTransform?: any): any;
|
|
20
|
-
export declare const Req: () => ParameterDecorator;
|
|
21
|
-
export declare const Res: () => ParameterDecorator;
|
|
22
|
-
export declare const createCustomRequestDecorator: (decoratorName: string, resolver: ParameterResolver) => ParameterDecorator;
|