@zenofolio/hyper-decor 0.0.3 → 1.0.7
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 +64 -1
- package/debug.txt +1 -0
- package/dist/__internals/constants.d.ts +5 -1
- package/dist/__internals/constants.js +5 -1
- package/dist/__internals/creators/request.creator.d.ts +2 -3
- package/dist/__internals/creators/request.creator.js +5 -3
- package/dist/__internals/creators/routes.creator.d.ts +2 -3
- package/dist/__internals/creators/routes.creator.js +5 -3
- package/dist/__internals/decorator-base.js +47 -11
- package/dist/__internals/helpers/imports.helper.d.ts +8 -0
- package/dist/__internals/helpers/imports.helper.js +92 -0
- 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.d.ts +11 -0
- package/dist/__internals/helpers/prepare.helper.js +348 -0
- package/dist/__internals/helpers/tree.helper.d.ts +36 -0
- package/dist/__internals/helpers/tree.helper.js +81 -0
- package/dist/__internals/stores/service.store.d.ts +1 -0
- package/dist/__internals/{transform/pass.transfrom.js → stores/service.store.js} +2 -0
- package/dist/__internals/transform/middleware.transform.d.ts +3 -0
- package/dist/__internals/transform/middleware.transform.js +19 -0
- package/dist/__internals/transform/role.transform.js +8 -5
- package/dist/__internals/transform/scope.transfrom.d.ts +5 -7
- package/dist/__internals/transform/scope.transfrom.js +52 -38
- package/dist/__internals/transform/transform.registry.d.ts +33 -0
- package/dist/__internals/transform/transform.registry.js +59 -0
- package/dist/__internals/utils/function.util.d.ts +1 -4
- package/dist/__internals/utils/function.util.js +22 -10
- package/dist/common/bootstrap.js +4 -0
- package/dist/common/helpers/index.d.ts +1 -0
- package/dist/common/helpers/index.js +1 -0
- package/dist/common/helpers/scopes.d.ts +3 -3
- package/dist/common/helpers/scopes.js +7 -8
- package/dist/common/helpers/state.d.ts +17 -0
- package/dist/common/helpers/state.js +44 -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/File.d.ts +1 -1
- package/dist/decorators/Http.d.ts +20 -13
- package/dist/decorators/Http.js +77 -31
- package/dist/decorators/HyperApp.d.ts +0 -4
- package/dist/decorators/HyperApp.js +16 -182
- package/dist/decorators/HyperController.js +2 -1
- package/dist/decorators/HyperService.d.ts +15 -0
- package/dist/decorators/HyperService.js +29 -0
- package/dist/decorators/Messaging.d.ts +10 -0
- package/dist/decorators/Messaging.js +22 -0
- package/dist/decorators/Middleware.d.ts +5 -4
- package/dist/decorators/Middleware.js +33 -19
- package/dist/decorators/Output.d.ts +9 -0
- package/dist/decorators/Output.js +18 -0
- package/dist/decorators/Pass.d.ts +6 -3
- package/dist/decorators/Pass.js +6 -3
- package/dist/decorators/Role.js +5 -5
- package/dist/decorators/Routes.d.ts +14 -13
- package/dist/decorators/Scope.js +3 -3
- package/dist/decorators/Transform.d.ts +14 -0
- package/dist/decorators/Transform.js +18 -0
- package/dist/decorators/index.d.ts +3 -0
- package/dist/decorators/index.js +3 -0
- package/dist/decorators/types.d.ts +45 -10
- package/dist/decorators/types.js +4 -0
- package/dist/extension.js +11 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/lib/openapi/collectors/class.collector.d.ts +9 -0
- package/dist/lib/openapi/collectors/class.collector.js +67 -0
- package/dist/lib/openapi/collectors/index.d.ts +4 -0
- package/dist/lib/openapi/collectors/index.js +20 -0
- package/dist/lib/openapi/collectors/method.collector.d.ts +2 -0
- package/dist/lib/openapi/collectors/method.collector.js +68 -0
- package/dist/lib/openapi/collectors/param.collector.d.ts +2 -0
- package/dist/lib/openapi/collectors/param.collector.js +64 -0
- package/dist/lib/openapi/collectors/schema.collector.d.ts +11 -0
- package/dist/lib/openapi/collectors/schema.collector.js +37 -0
- package/dist/lib/openapi/constants.d.ts +46 -0
- package/dist/lib/openapi/constants.js +61 -0
- package/dist/lib/openapi/decorators/api-bearer-auth.decorator.d.ts +2 -0
- package/dist/lib/openapi/decorators/api-bearer-auth.decorator.js +10 -0
- package/dist/lib/openapi/decorators/api-method.decorator.d.ts +3 -0
- package/dist/lib/openapi/decorators/api-method.decorator.js +11 -0
- package/dist/lib/openapi/decorators/api-parameter.decorator.d.ts +3 -0
- package/dist/lib/openapi/decorators/api-parameter.decorator.js +10 -0
- package/dist/lib/openapi/decorators/api-request-body.decorator.d.ts +3 -0
- package/dist/lib/openapi/decorators/api-request-body.decorator.js +10 -0
- package/dist/lib/openapi/decorators/api-response.decorator.d.ts +3 -0
- package/dist/lib/openapi/decorators/api-response.decorator.js +10 -0
- package/dist/lib/openapi/decorators/api-security.decorator.d.ts +3 -0
- package/dist/lib/openapi/decorators/api-security.decorator.js +10 -0
- package/dist/lib/openapi/decorators/api-tag.decorator.d.ts +3 -0
- package/dist/lib/openapi/decorators/api-tag.decorator.js +13 -0
- package/dist/lib/openapi/decorators/index.d.ts +7 -0
- package/dist/lib/openapi/decorators/index.js +23 -0
- package/dist/lib/openapi/helpers/index.d.ts +7 -0
- package/dist/lib/openapi/helpers/index.js +23 -0
- package/dist/lib/openapi/helpers/method.helper.d.ts +3 -0
- package/dist/lib/openapi/helpers/method.helper.js +20 -0
- package/dist/lib/openapi/helpers/openapi.helper.d.ts +7 -0
- package/dist/lib/openapi/helpers/openapi.helper.js +51 -0
- package/dist/lib/openapi/helpers/parameter.helper.d.ts +3 -0
- package/dist/lib/openapi/helpers/parameter.helper.js +16 -0
- package/dist/lib/openapi/helpers/request-body.helper.d.ts +3 -0
- package/dist/lib/openapi/helpers/request-body.helper.js +9 -0
- package/dist/lib/openapi/helpers/response.helper.d.ts +3 -0
- package/dist/lib/openapi/helpers/response.helper.js +18 -0
- package/dist/lib/openapi/helpers/security.helper.d.ts +3 -0
- package/dist/lib/openapi/helpers/security.helper.js +17 -0
- package/dist/lib/openapi/helpers/tag.helper.d.ts +3 -0
- package/dist/lib/openapi/helpers/tag.helper.js +10 -0
- package/dist/lib/openapi/index.d.ts +6 -0
- package/dist/lib/openapi/index.js +22 -0
- package/dist/lib/openapi/metadata.registry.d.ts +29 -0
- package/dist/lib/openapi/metadata.registry.js +41 -0
- package/dist/lib/openapi/types.d.ts +131 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/{common/openapi → stores}/index.js +1 -2
- package/dist/stores/scope.store.d.ts +14 -0
- package/dist/stores/scope.store.js +29 -0
- package/dist/type.d.ts +13 -2
- package/hyper-express-decorators.d.ts +1 -0
- package/package.json +73 -60
- package/scripts/clean.js +56 -0
- package/scripts/test-server.ts +85 -0
- package/tsconfig.json +18 -13
- package/vitest.config.mjs +30 -0
- package/vitest.json +0 -0
- package/.mocharc.js +0 -5
- package/dist/__internals/store.d.ts +0 -10
- package/dist/__internals/store.js +0 -17
- 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/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/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/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/__internals/stores/{index.d.ts → metadata.store.d.ts} +0 -0
- /package/dist/__internals/stores/{index.js → metadata.store.js} +0 -0
- /package/dist/{__internals/stores/store.interface.js → lib/openapi/types.js} +0 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.prepareApplication = prepareApplication;
|
|
16
|
+
const hyper_express_1 = require("hyper-express");
|
|
17
|
+
const stores_1 = require("../../stores");
|
|
18
|
+
const role_transform_1 = __importDefault(require("../transform/role.transform"));
|
|
19
|
+
const scope_transfrom_1 = __importDefault(require("../transform/scope.transfrom"));
|
|
20
|
+
const object_util_1 = require("../utils/object.util");
|
|
21
|
+
const decorator_base_1 = require("../decorator-base");
|
|
22
|
+
const constants_1 = require("../constants");
|
|
23
|
+
const middleware_transform_1 = __importDefault(require("../transform/middleware.transform"));
|
|
24
|
+
const tsyringe_1 = require("tsyringe");
|
|
25
|
+
const path_util_1 = require("../utils/path.util");
|
|
26
|
+
const imports_helper_1 = require("./imports.helper");
|
|
27
|
+
const message_bus_1 = require("../../common/message-bus");
|
|
28
|
+
const transport_1 = require("../../common/transport");
|
|
29
|
+
const transform_registry_1 = require("../transform/transform.registry");
|
|
30
|
+
const if_router = (current) => {
|
|
31
|
+
if (!current || !((current === null || current === void 0 ? void 0 : current.prototype) instanceof hyper_express_1.Router))
|
|
32
|
+
return new hyper_express_1.Router();
|
|
33
|
+
return new current();
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Extract the data from the target class.
|
|
37
|
+
*
|
|
38
|
+
* @param target
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
41
|
+
function getData(target) {
|
|
42
|
+
var _a, _b, _c, _d, _e;
|
|
43
|
+
const app = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_APP, target);
|
|
44
|
+
const module = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_MODULE, target);
|
|
45
|
+
const controller = (0, decorator_base_1.getDecorData)(constants_1.KEY_TYPE_CONTROLLER, target);
|
|
46
|
+
const middlewares = (0, middleware_transform_1.default)((_a = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_MIDDLEWARES, target)) !== null && _a !== void 0 ? _a : []);
|
|
47
|
+
const scopes = (_b = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_SCOPE, target)) !== null && _b !== void 0 ? _b : [];
|
|
48
|
+
const roles = (_c = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_ROLE, target)) !== null && _c !== void 0 ? _c : [];
|
|
49
|
+
const routes = (_d = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_ROUTE, target)) !== null && _d !== void 0 ? _d : {
|
|
50
|
+
routes: [],
|
|
51
|
+
};
|
|
52
|
+
const params = (_e = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_PARAM, target)) !== null && _e !== void 0 ? _e : {};
|
|
53
|
+
const pass = (0, decorator_base_1.getDecorData)(constants_1.KEY_PARAMS_PASS, target);
|
|
54
|
+
return {
|
|
55
|
+
app,
|
|
56
|
+
module,
|
|
57
|
+
controller,
|
|
58
|
+
middlewares,
|
|
59
|
+
scopes,
|
|
60
|
+
roles,
|
|
61
|
+
routes,
|
|
62
|
+
params,
|
|
63
|
+
pass,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Prepare the application with the given options.
|
|
68
|
+
*
|
|
69
|
+
* @param options
|
|
70
|
+
* @param Target
|
|
71
|
+
* @param app
|
|
72
|
+
* @param log
|
|
73
|
+
*/
|
|
74
|
+
function prepareApplication(options, Target, app, log) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
var _a, _b, _c;
|
|
77
|
+
const data = getData(Target);
|
|
78
|
+
const prefix = (_a = options.prefix) !== null && _a !== void 0 ? _a : "/";
|
|
79
|
+
const imports = (_b = options.imports) !== null && _b !== void 0 ? _b : [];
|
|
80
|
+
// Register transports if provided, otherwise fallback to internal
|
|
81
|
+
const bus = tsyringe_1.container.resolve(message_bus_1.MessageBus);
|
|
82
|
+
if ((_c = options === null || options === void 0 ? void 0 : options.transports) === null || _c === void 0 ? void 0 : _c.length) {
|
|
83
|
+
options.transports.forEach((t) => bus.registerTransport(t));
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
bus.registerTransport(new transport_1.InternalTransport());
|
|
87
|
+
}
|
|
88
|
+
let hooks = options.hooks;
|
|
89
|
+
if (typeof hooks === "function" && !(hooks instanceof hyper_express_1.Router)) {
|
|
90
|
+
if (hooks && "constructor" in hooks) {
|
|
91
|
+
if (tsyringe_1.container.isRegistered(hooks)) {
|
|
92
|
+
tsyringe_1.container.register(hooks, hooks);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
hooks = tsyringe_1.container.resolve(hooks);
|
|
96
|
+
}
|
|
97
|
+
const context = { target: Target, metadata: options, type: "app" };
|
|
98
|
+
yield (0, imports_helper_1.prepareImports)(Target, imports, hooks, context);
|
|
99
|
+
if (data.middlewares.length) {
|
|
100
|
+
app.use(...data.middlewares);
|
|
101
|
+
log("middleware", `${Target.name} with middlewares: ${data.middlewares
|
|
102
|
+
.map((e) => e.name)
|
|
103
|
+
.join(", ")}`);
|
|
104
|
+
}
|
|
105
|
+
(0, scope_transfrom_1.default)(data.scopes, (middleware, scopes) => {
|
|
106
|
+
stores_1.ScopeStore.addAll(scopes);
|
|
107
|
+
app.use(middleware);
|
|
108
|
+
log("middleware", `${Target.name} with scopes: ${data.scopes.join(", ")}`);
|
|
109
|
+
});
|
|
110
|
+
(0, role_transform_1.default)(data.roles, (middleware) => {
|
|
111
|
+
app.use(middleware);
|
|
112
|
+
log("middleware", `${Target.name} with roles: ${data.roles.join(", ")}`);
|
|
113
|
+
});
|
|
114
|
+
const routers = (yield Promise.all(options.modules.map((module) => __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
var _a, _b, _c;
|
|
116
|
+
const data = getData(module);
|
|
117
|
+
const path = (_a = data.module) === null || _a === void 0 ? void 0 : _a.path;
|
|
118
|
+
const imports = (_c = (_b = data.module) === null || _b === void 0 ? void 0 : _b.imports) !== null && _c !== void 0 ? _c : [];
|
|
119
|
+
return prepareTarget({
|
|
120
|
+
target: module,
|
|
121
|
+
router: if_router(module),
|
|
122
|
+
namespace: `${Target.name}/${module.name}`,
|
|
123
|
+
instance: app,
|
|
124
|
+
prefix: path,
|
|
125
|
+
imports: imports,
|
|
126
|
+
log,
|
|
127
|
+
hooks: hooks,
|
|
128
|
+
});
|
|
129
|
+
})))).filter((r) => r.router);
|
|
130
|
+
routers.forEach(({ router, path }) => {
|
|
131
|
+
app.use((0, path_util_1.join)(prefix, path || "/"), router);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Prepare the target class
|
|
137
|
+
* HyperModule or HyperController can be used as target.
|
|
138
|
+
*
|
|
139
|
+
* @param param0
|
|
140
|
+
* @returns
|
|
141
|
+
*/
|
|
142
|
+
function prepareTarget(_a) {
|
|
143
|
+
return __awaiter(this, arguments, void 0, function* ({ target, router, prefix, namespace = "", instance, imports = [], log, hooks, }) {
|
|
144
|
+
var _b, _c, _d, _e, _f, _g, _h, _j;
|
|
145
|
+
const data = getData(target);
|
|
146
|
+
if (data.module) {
|
|
147
|
+
log("modules", `${namespace} { ${prefix || "/"} }`);
|
|
148
|
+
}
|
|
149
|
+
else if (data.controller) {
|
|
150
|
+
log("controllers", `${namespace} { ${prefix || "/"} }`);
|
|
151
|
+
}
|
|
152
|
+
const modules = (_c = (_b = data.module) === null || _b === void 0 ? void 0 : _b.modules) !== null && _c !== void 0 ? _c : [];
|
|
153
|
+
const controllers = (_e = (_d = data.module) === null || _d === void 0 ? void 0 : _d.controllers) !== null && _e !== void 0 ? _e : [];
|
|
154
|
+
const routes = (_f = data.routes) !== null && _f !== void 0 ? _f : { routes: [] };
|
|
155
|
+
const middlewares = (_g = data.middlewares) !== null && _g !== void 0 ? _g : [];
|
|
156
|
+
const scopes = (_h = data.scopes) !== null && _h !== void 0 ? _h : [];
|
|
157
|
+
const roles = (_j = data.roles) !== null && _j !== void 0 ? _j : [];
|
|
158
|
+
const needsRouter = controllers.length > 0 ||
|
|
159
|
+
routes.routes.size > 0 ||
|
|
160
|
+
middlewares.length > 0 ||
|
|
161
|
+
scopes.length > 0 ||
|
|
162
|
+
roles.length > 0;
|
|
163
|
+
const _router = router !== null && router !== void 0 ? router : (needsRouter ? if_router(target) : undefined);
|
|
164
|
+
////////////////////////////////
|
|
165
|
+
/// Prepare Imports
|
|
166
|
+
////////////////////////////////
|
|
167
|
+
const context = { target: target, metadata: data, type: "target" };
|
|
168
|
+
yield (0, imports_helper_1.prepareImports)(target, imports, hooks, context);
|
|
169
|
+
////////////////////////////////
|
|
170
|
+
/// Attach Middlewares & Security
|
|
171
|
+
////////////////////////////////
|
|
172
|
+
if (_router) {
|
|
173
|
+
_router.use(...middlewares);
|
|
174
|
+
(0, scope_transfrom_1.default)(scopes, (middleware, scopes) => {
|
|
175
|
+
stores_1.ScopeStore.addAll(scopes);
|
|
176
|
+
_router.use(middleware);
|
|
177
|
+
});
|
|
178
|
+
(0, role_transform_1.default)(roles, (middleware) => _router.use(middleware));
|
|
179
|
+
}
|
|
180
|
+
////////////////////////////////
|
|
181
|
+
/// Prepare Modules
|
|
182
|
+
////////////////////////////////
|
|
183
|
+
yield (0, object_util_1.$each)(modules, (module) => __awaiter(this, void 0, void 0, function* () {
|
|
184
|
+
const moduleData = getData(module);
|
|
185
|
+
if (!moduleData.module)
|
|
186
|
+
return;
|
|
187
|
+
const res = yield prepareTarget({
|
|
188
|
+
target: module,
|
|
189
|
+
imports: moduleData.module.imports,
|
|
190
|
+
namespace: `${namespace}/${module.name}`,
|
|
191
|
+
prefix: moduleData.module.path,
|
|
192
|
+
instance: tsyringe_1.container.resolve(module),
|
|
193
|
+
log,
|
|
194
|
+
hooks,
|
|
195
|
+
});
|
|
196
|
+
if (res.router && _router) {
|
|
197
|
+
_router.use(res.path || "/", res.router);
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
// ////////////////////////////////
|
|
201
|
+
// /// Prepare Controllers
|
|
202
|
+
// ////////////////////////////////
|
|
203
|
+
yield (0, object_util_1.$each)(controllers, (controller) => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
const data = getData(controller);
|
|
205
|
+
const controllerData = data.controller;
|
|
206
|
+
if (!controllerData)
|
|
207
|
+
return;
|
|
208
|
+
const res = yield prepareTarget({
|
|
209
|
+
target: controller,
|
|
210
|
+
namespace: `${namespace}/${controller.name}`,
|
|
211
|
+
prefix: controllerData.path,
|
|
212
|
+
imports: controllerData.imports,
|
|
213
|
+
instance: tsyringe_1.container.resolve(controller),
|
|
214
|
+
log,
|
|
215
|
+
hooks,
|
|
216
|
+
});
|
|
217
|
+
if (res.router && _router) {
|
|
218
|
+
_router.use(res.path || "/", res.router);
|
|
219
|
+
}
|
|
220
|
+
}));
|
|
221
|
+
////////////////////////////////
|
|
222
|
+
/// Prepare Routes
|
|
223
|
+
////////////////////////////////
|
|
224
|
+
if (_router) {
|
|
225
|
+
yield (0, object_util_1.$each)(Array.from(routes.routes), (route) => __awaiter(this, void 0, void 0, function* () {
|
|
226
|
+
if (typeof route !== "object")
|
|
227
|
+
return;
|
|
228
|
+
yield prepareRoutes({
|
|
229
|
+
target: target,
|
|
230
|
+
router: _router,
|
|
231
|
+
route,
|
|
232
|
+
namespace,
|
|
233
|
+
instance,
|
|
234
|
+
prefix: prefix || "/",
|
|
235
|
+
log,
|
|
236
|
+
});
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
router: _router,
|
|
241
|
+
path: prefix,
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Resolves method parameters and applies adaptive transformations.
|
|
247
|
+
* Optimized: Metadata is resolved once and passed here.
|
|
248
|
+
*/
|
|
249
|
+
function resolveMethodParams(req, res, params) {
|
|
250
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
251
|
+
const len = params.length;
|
|
252
|
+
const args = new Array(len);
|
|
253
|
+
for (let i = 0; i < len; i++) {
|
|
254
|
+
const param = params[i];
|
|
255
|
+
let val = yield param.resolver(req, res);
|
|
256
|
+
if (param.schema) {
|
|
257
|
+
val = yield transform_registry_1.transformRegistry.resolve({
|
|
258
|
+
data: val,
|
|
259
|
+
schema: param.schema,
|
|
260
|
+
options: { isWholeSource: param.isWholeSource },
|
|
261
|
+
req,
|
|
262
|
+
res,
|
|
263
|
+
from: param.key,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
args[i] = val;
|
|
267
|
+
}
|
|
268
|
+
return args;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Handles output transformation and sends the response.
|
|
273
|
+
* Optimized: outputSchema is pre-resolved outside the request hotpath.
|
|
274
|
+
*/
|
|
275
|
+
function handleResponse(req, res, result, outputSchema) {
|
|
276
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
+
if (result === undefined || res.completed)
|
|
278
|
+
return;
|
|
279
|
+
if (outputSchema && outputSchema !== Object && outputSchema !== Promise) {
|
|
280
|
+
const transformed = yield transform_registry_1.transformRegistry.resolve({
|
|
281
|
+
data: result,
|
|
282
|
+
schema: outputSchema,
|
|
283
|
+
options: {},
|
|
284
|
+
req,
|
|
285
|
+
res,
|
|
286
|
+
from: "response",
|
|
287
|
+
});
|
|
288
|
+
if (transformed !== undefined && !res.completed) {
|
|
289
|
+
res.json(transformed);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (!res.completed) {
|
|
294
|
+
if (typeof result === "object" && result !== null) {
|
|
295
|
+
res.json(result);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
res.send(result);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Prepare the routes for the target class.
|
|
305
|
+
*/
|
|
306
|
+
function prepareRoutes(_a) {
|
|
307
|
+
return __awaiter(this, arguments, void 0, function* ({ target, router, route, instance, namespace, log, }) {
|
|
308
|
+
var _b, _c, _d;
|
|
309
|
+
const { method, path, handler, propertyKey, options } = route;
|
|
310
|
+
const metadata = getData(handler);
|
|
311
|
+
const params = (_d = (_c = (_b = metadata.params) === null || _b === void 0 ? void 0 : _b.params) === null || _c === void 0 ? void 0 : _c[propertyKey]) !== null && _d !== void 0 ? _d : [];
|
|
312
|
+
const $fn = Reflect.get(router, method);
|
|
313
|
+
if (!$fn)
|
|
314
|
+
return;
|
|
315
|
+
const middlewares = [...metadata.middlewares];
|
|
316
|
+
const proto = target.prototype || target;
|
|
317
|
+
// Pre-resolve Output-Metadata
|
|
318
|
+
const outputSchema = Reflect.getMetadata(constants_1.KEY_OUTPUT_SCHEMA, proto, propertyKey) ||
|
|
319
|
+
Reflect.getMetadata(constants_1.DESIGN_RETURNTYPE, proto, propertyKey);
|
|
320
|
+
(0, role_transform_1.default)(metadata.roles, (middleware) => middlewares.push(middleware));
|
|
321
|
+
(0, scope_transfrom_1.default)(metadata.scopes, (middleware, scopes) => {
|
|
322
|
+
middlewares.push(middleware);
|
|
323
|
+
stores_1.ScopeStore.addAll(scopes);
|
|
324
|
+
});
|
|
325
|
+
log("routes", `${namespace}/${propertyKey.toString()} ${method.toUpperCase()} { ${path} }`);
|
|
326
|
+
const routeHandler = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
327
|
+
try {
|
|
328
|
+
const args = params.length > 0
|
|
329
|
+
? yield resolveMethodParams(req, res, params)
|
|
330
|
+
: [req, res];
|
|
331
|
+
const result = yield handler.apply(instance, args);
|
|
332
|
+
yield handleResponse(req, res, result, outputSchema);
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
if (!res.completed) {
|
|
336
|
+
res.status(500).json({
|
|
337
|
+
error: err.message || "Internal Server Error",
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
if (method === "ws" && options) {
|
|
343
|
+
router.ws(path, options, handler.bind(instance));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
$fn.call(router, path, ...middlewares, routeHandler);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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;
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const serviceStore: Set<any>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = middlewareTransformer;
|
|
4
|
+
const tsyringe_1 = require("tsyringe");
|
|
5
|
+
function middlewareTransformer(list) {
|
|
6
|
+
return list
|
|
7
|
+
.map((middleware) => {
|
|
8
|
+
if (isClass(middleware)) {
|
|
9
|
+
const instance = tsyringe_1.container.resolve(middleware);
|
|
10
|
+
return instance.handle.bind(instance);
|
|
11
|
+
}
|
|
12
|
+
if (typeof middleware === "function") {
|
|
13
|
+
return middleware;
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
})
|
|
17
|
+
.filter((middleware) => !!middleware);
|
|
18
|
+
}
|
|
19
|
+
const isClass = (fn) => typeof fn === "function" && `${fn}`.indexOf("class") === 0;
|
|
@@ -3,16 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.default = roleTransform;
|
|
4
4
|
const exeptions_1 = require("../../exeptions");
|
|
5
5
|
const helpers_1 = require("../../common/helpers");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
6
7
|
function roleTransform(list, callback) {
|
|
7
8
|
const { roles, names, isEmtpy } = resolveRoles(list);
|
|
8
9
|
const middleware = (req, res, next) => {
|
|
9
|
-
|
|
10
|
+
var _a;
|
|
10
11
|
if (isEmtpy)
|
|
11
12
|
return next();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const requestRoles = (_a = (0, helpers_1.getRoles)(req)) !== null && _a !== void 0 ? _a : [];
|
|
14
|
+
if (requestRoles.length === 0 && isEmtpy)
|
|
15
|
+
return next();
|
|
16
|
+
if (requestRoles.includes(constants_1.FULL_ACCESS))
|
|
17
|
+
return next();
|
|
18
|
+
const role = roles.some((scope) => requestRoles.includes(scope.role));
|
|
16
19
|
if (role) {
|
|
17
20
|
return next();
|
|
18
21
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { MiddlewareHandler } from "hyper-express";
|
|
2
|
-
import { ScopeType } from "../../decorators";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
message: string | null;
|
|
7
|
-
}[], names: Set<string>) => void): MiddlewareHandler;
|
|
1
|
+
import { MiddlewareHandler } from "hyper-express/types";
|
|
2
|
+
import { ScopeMap, ScopeType } from "../../decorators";
|
|
3
|
+
type Callback = (middleware: MiddlewareHandler, scopes: ScopeMap[], names: Set<string>) => void;
|
|
4
|
+
export default function scopeTransfrom(listScopes: ScopeType[], ...callback: Callback[]): MiddlewareHandler;
|
|
5
|
+
export {};
|
|
@@ -3,24 +3,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.default = scopeTransfrom;
|
|
4
4
|
const exeptions_1 = require("../../exeptions");
|
|
5
5
|
const helpers_1 = require("../../common/helpers");
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
function scopeTransfrom(listScopes, ...callback) {
|
|
8
|
+
const { scopes, scopeNames, isEmpty } = resolveScopes(listScopes);
|
|
8
9
|
const middleware = (req, res, next) => {
|
|
9
10
|
var _a;
|
|
10
|
-
|
|
11
|
-
if (isEmtpy)
|
|
11
|
+
if (isEmpty)
|
|
12
12
|
return next();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
return next(
|
|
13
|
+
const userScopesRaw = (0, helpers_1.getScopes)(req);
|
|
14
|
+
if (!userScopesRaw || userScopesRaw.length === 0) {
|
|
15
|
+
return next(new exeptions_1.NotScopeException(`FORBIDDEN`, [], Array.from(scopeNames)));
|
|
16
|
+
}
|
|
17
|
+
if (userScopesRaw.includes(constants_1.FULL_ACCESS))
|
|
18
|
+
return next();
|
|
19
|
+
for (const scope of scopes) {
|
|
20
|
+
if (!userScopesRaw.includes(scope.scope)) {
|
|
21
|
+
return next(new exeptions_1.NotScopeException((_a = scope.message) !== null && _a !== void 0 ? _a : `FORBIDDEN`, userScopesRaw, Array.from(scopeNames)));
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
return next();
|
|
21
25
|
};
|
|
22
|
-
if (
|
|
23
|
-
|
|
26
|
+
if (!isEmpty && callback.length > 0) {
|
|
27
|
+
for (const cb of callback)
|
|
28
|
+
cb(middleware, scopes, scopeNames);
|
|
24
29
|
}
|
|
25
30
|
return middleware;
|
|
26
31
|
}
|
|
@@ -35,38 +40,47 @@ const resolveScopes = (scopes) => {
|
|
|
35
40
|
var _a, _b;
|
|
36
41
|
const $scopes = {};
|
|
37
42
|
for (const scope of scopes) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
const list = parseScope(scope);
|
|
44
|
+
if (list.length === 0)
|
|
45
|
+
continue;
|
|
46
|
+
for (const s of list) {
|
|
47
|
+
$scopes[s.scope] = {
|
|
48
|
+
scope: s.scope,
|
|
49
|
+
description: (_a = s.description) !== null && _a !== void 0 ? _a : "",
|
|
50
|
+
message: (_b = s.message) !== null && _b !== void 0 ? _b : `You don't have the required scopes to access this resource`,
|
|
43
51
|
};
|
|
44
52
|
}
|
|
45
|
-
else if (Array.isArray(scope)) {
|
|
46
|
-
for (const s of scope) {
|
|
47
|
-
switch (typeof s) {
|
|
48
|
-
case "string":
|
|
49
|
-
$scopes[s] = {
|
|
50
|
-
scope: s,
|
|
51
|
-
description: "",
|
|
52
|
-
message: null,
|
|
53
|
-
};
|
|
54
|
-
break;
|
|
55
|
-
case "object":
|
|
56
|
-
$scopes[s.scope] = {
|
|
57
|
-
scope: s.scope,
|
|
58
|
-
description: (_a = s.description) !== null && _a !== void 0 ? _a : "",
|
|
59
|
-
message: (_b = s.message) !== null && _b !== void 0 ? _b : null,
|
|
60
|
-
};
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
53
|
}
|
|
66
54
|
const values = Object.values($scopes);
|
|
67
55
|
return {
|
|
68
56
|
scopes: values,
|
|
69
57
|
scopeNames: new Set(Object.keys($scopes)),
|
|
70
|
-
|
|
58
|
+
isEmpty: values.length === 0,
|
|
71
59
|
};
|
|
72
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Parse the scope to a standard format
|
|
63
|
+
*
|
|
64
|
+
* @param scope
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
67
|
+
const parseScope = (scope) => {
|
|
68
|
+
switch (typeof scope) {
|
|
69
|
+
case "string":
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
scope,
|
|
73
|
+
description: "",
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
case "object":
|
|
77
|
+
if (Array.isArray(scope)) {
|
|
78
|
+
if (scope.length === 0)
|
|
79
|
+
return [];
|
|
80
|
+
return scope.map((s) => parseScope(s)).flat();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return [scope];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|