@zenofolio/hyper-decor 1.0.4 → 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.
Files changed (154) hide show
  1. package/README.md +64 -1
  2. package/debug.txt +1 -0
  3. package/dist/__internals/constants.d.ts +5 -1
  4. package/dist/__internals/constants.js +5 -1
  5. package/dist/__internals/creators/request.creator.d.ts +2 -3
  6. package/dist/__internals/creators/request.creator.js +5 -3
  7. package/dist/__internals/creators/routes.creator.d.ts +2 -3
  8. package/dist/__internals/creators/routes.creator.js +5 -3
  9. package/dist/__internals/decorator-base.js +47 -11
  10. package/dist/__internals/helpers/imports.helper.d.ts +8 -0
  11. package/dist/__internals/helpers/imports.helper.js +92 -0
  12. package/dist/__internals/helpers/lifecycle.helper.d.ts +3 -0
  13. package/dist/__internals/helpers/lifecycle.helper.js +25 -0
  14. package/dist/__internals/helpers/merge-metadata.js +16 -20
  15. package/dist/__internals/helpers/prepare.helper.d.ts +11 -0
  16. package/dist/__internals/helpers/prepare.helper.js +348 -0
  17. package/dist/__internals/helpers/tree.helper.d.ts +36 -0
  18. package/dist/__internals/helpers/tree.helper.js +81 -0
  19. package/dist/__internals/stores/service.store.d.ts +1 -0
  20. package/dist/__internals/{transform/pass.transfrom.js → stores/service.store.js} +2 -0
  21. package/dist/__internals/transform/middleware.transform.d.ts +3 -0
  22. package/dist/__internals/transform/middleware.transform.js +19 -0
  23. package/dist/__internals/transform/role.transform.js +8 -5
  24. package/dist/__internals/transform/scope.transfrom.d.ts +5 -7
  25. package/dist/__internals/transform/scope.transfrom.js +52 -38
  26. package/dist/__internals/transform/transform.registry.d.ts +33 -0
  27. package/dist/__internals/transform/transform.registry.js +59 -0
  28. package/dist/__internals/utils/function.util.d.ts +1 -4
  29. package/dist/__internals/utils/function.util.js +22 -10
  30. package/dist/common/bootstrap.js +4 -0
  31. package/dist/common/helpers/index.d.ts +1 -0
  32. package/dist/common/helpers/index.js +1 -0
  33. package/dist/common/helpers/scopes.d.ts +3 -3
  34. package/dist/common/helpers/scopes.js +7 -8
  35. package/dist/common/helpers/state.d.ts +17 -0
  36. package/dist/common/helpers/state.js +44 -0
  37. package/dist/common/message-bus.d.ts +11 -0
  38. package/dist/common/message-bus.js +51 -0
  39. package/dist/common/transport.d.ts +9 -0
  40. package/dist/common/transport.js +46 -0
  41. package/dist/decorators/File.d.ts +1 -1
  42. package/dist/decorators/Http.d.ts +20 -13
  43. package/dist/decorators/Http.js +77 -31
  44. package/dist/decorators/HyperApp.d.ts +0 -4
  45. package/dist/decorators/HyperApp.js +16 -182
  46. package/dist/decorators/HyperController.js +2 -1
  47. package/dist/decorators/HyperService.d.ts +15 -0
  48. package/dist/decorators/HyperService.js +29 -0
  49. package/dist/decorators/Messaging.d.ts +10 -0
  50. package/dist/decorators/Messaging.js +22 -0
  51. package/dist/decorators/Middleware.d.ts +5 -4
  52. package/dist/decorators/Middleware.js +33 -19
  53. package/dist/decorators/Output.d.ts +9 -0
  54. package/dist/decorators/Output.js +18 -0
  55. package/dist/decorators/Pass.d.ts +6 -3
  56. package/dist/decorators/Pass.js +6 -3
  57. package/dist/decorators/Role.js +5 -5
  58. package/dist/decorators/Routes.d.ts +14 -13
  59. package/dist/decorators/Scope.js +3 -3
  60. package/dist/decorators/Transform.d.ts +14 -0
  61. package/dist/decorators/Transform.js +18 -0
  62. package/dist/decorators/index.d.ts +3 -0
  63. package/dist/decorators/index.js +3 -0
  64. package/dist/decorators/types.d.ts +45 -10
  65. package/dist/decorators/types.js +4 -0
  66. package/dist/extension.js +11 -2
  67. package/dist/index.d.ts +6 -0
  68. package/dist/index.js +6 -0
  69. package/dist/lib/openapi/collectors/class.collector.d.ts +9 -0
  70. package/dist/lib/openapi/collectors/class.collector.js +67 -0
  71. package/dist/lib/openapi/collectors/index.d.ts +4 -0
  72. package/dist/lib/openapi/collectors/index.js +20 -0
  73. package/dist/lib/openapi/collectors/method.collector.d.ts +2 -0
  74. package/dist/lib/openapi/collectors/method.collector.js +68 -0
  75. package/dist/lib/openapi/collectors/param.collector.d.ts +2 -0
  76. package/dist/lib/openapi/collectors/param.collector.js +64 -0
  77. package/dist/lib/openapi/collectors/schema.collector.d.ts +11 -0
  78. package/dist/lib/openapi/collectors/schema.collector.js +37 -0
  79. package/dist/lib/openapi/constants.d.ts +46 -0
  80. package/dist/lib/openapi/constants.js +61 -0
  81. package/dist/lib/openapi/decorators/api-bearer-auth.decorator.d.ts +2 -0
  82. package/dist/lib/openapi/decorators/api-bearer-auth.decorator.js +10 -0
  83. package/dist/lib/openapi/decorators/api-method.decorator.d.ts +3 -0
  84. package/dist/lib/openapi/decorators/api-method.decorator.js +11 -0
  85. package/dist/lib/openapi/decorators/api-parameter.decorator.d.ts +3 -0
  86. package/dist/lib/openapi/decorators/api-parameter.decorator.js +10 -0
  87. package/dist/lib/openapi/decorators/api-request-body.decorator.d.ts +3 -0
  88. package/dist/lib/openapi/decorators/api-request-body.decorator.js +10 -0
  89. package/dist/lib/openapi/decorators/api-response.decorator.d.ts +3 -0
  90. package/dist/lib/openapi/decorators/api-response.decorator.js +10 -0
  91. package/dist/lib/openapi/decorators/api-security.decorator.d.ts +3 -0
  92. package/dist/lib/openapi/decorators/api-security.decorator.js +10 -0
  93. package/dist/lib/openapi/decorators/api-tag.decorator.d.ts +3 -0
  94. package/dist/lib/openapi/decorators/api-tag.decorator.js +13 -0
  95. package/dist/lib/openapi/decorators/index.d.ts +7 -0
  96. package/dist/lib/openapi/decorators/index.js +23 -0
  97. package/dist/lib/openapi/helpers/index.d.ts +7 -0
  98. package/dist/lib/openapi/helpers/index.js +23 -0
  99. package/dist/lib/openapi/helpers/method.helper.d.ts +3 -0
  100. package/dist/lib/openapi/helpers/method.helper.js +20 -0
  101. package/dist/lib/openapi/helpers/openapi.helper.d.ts +7 -0
  102. package/dist/lib/openapi/helpers/openapi.helper.js +51 -0
  103. package/dist/lib/openapi/helpers/parameter.helper.d.ts +3 -0
  104. package/dist/lib/openapi/helpers/parameter.helper.js +16 -0
  105. package/dist/lib/openapi/helpers/request-body.helper.d.ts +3 -0
  106. package/dist/lib/openapi/helpers/request-body.helper.js +9 -0
  107. package/dist/lib/openapi/helpers/response.helper.d.ts +3 -0
  108. package/dist/lib/openapi/helpers/response.helper.js +18 -0
  109. package/dist/lib/openapi/helpers/security.helper.d.ts +3 -0
  110. package/dist/lib/openapi/helpers/security.helper.js +17 -0
  111. package/dist/lib/openapi/helpers/tag.helper.d.ts +3 -0
  112. package/dist/lib/openapi/helpers/tag.helper.js +10 -0
  113. package/dist/lib/openapi/index.d.ts +6 -0
  114. package/dist/lib/openapi/index.js +22 -0
  115. package/dist/lib/openapi/metadata.registry.d.ts +29 -0
  116. package/dist/lib/openapi/metadata.registry.js +41 -0
  117. package/dist/lib/openapi/types.d.ts +131 -0
  118. package/dist/stores/index.d.ts +1 -0
  119. package/dist/{common/openapi → stores}/index.js +1 -2
  120. package/dist/stores/scope.store.d.ts +14 -0
  121. package/dist/stores/scope.store.js +29 -0
  122. package/dist/type.d.ts +13 -2
  123. package/hyper-express-decorators.d.ts +1 -0
  124. package/package.json +73 -60
  125. package/scripts/clean.js +56 -0
  126. package/scripts/test-server.ts +85 -0
  127. package/tsconfig.json +18 -13
  128. package/vitest.config.mjs +30 -0
  129. package/vitest.json +0 -0
  130. package/.mocharc.js +0 -5
  131. package/dist/__internals/store.d.ts +0 -10
  132. package/dist/__internals/store.js +0 -17
  133. package/dist/__internals/stores/middleware.store.d.ts +0 -7
  134. package/dist/__internals/stores/middleware.store.js +0 -19
  135. package/dist/__internals/stores/params.store.d.ts +0 -21
  136. package/dist/__internals/stores/params.store.js +0 -65
  137. package/dist/__internals/stores/routes.store.d.ts +0 -17
  138. package/dist/__internals/stores/routes.store.js +0 -43
  139. package/dist/__internals/stores/store.interface.d.ts +0 -8
  140. package/dist/__internals/transform/method.transform.d.ts +0 -2
  141. package/dist/__internals/transform/method.transform.js +0 -20
  142. package/dist/__internals/transform/pass.transfrom.d.ts +0 -1
  143. package/dist/__internals/utils/mixin.utils.d.ts +0 -11
  144. package/dist/__internals/utils/mixin.utils.js +0 -34
  145. package/dist/__internals/utils/router.d.ts +0 -1
  146. package/dist/__internals/utils/router.js +0 -2
  147. package/dist/common/openapi/collect-class-data.d.ts +0 -21
  148. package/dist/common/openapi/collect-class-data.js +0 -45
  149. package/dist/common/openapi/collect-function-data.d.ts +0 -32
  150. package/dist/common/openapi/collect-function-data.js +0 -70
  151. package/dist/common/openapi/index.d.ts +0 -2
  152. /package/dist/__internals/stores/{index.d.ts → metadata.store.d.ts} +0 -0
  153. /package/dist/__internals/stores/{index.js → metadata.store.js} +0 -0
  154. /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>;
@@ -1,2 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serviceStore = void 0;
4
+ exports.serviceStore = new Set();
@@ -0,0 +1,3 @@
1
+ import { MiddlewareHandler } from "hyper-express";
2
+ import { MiddlewareType } from "../../decorators";
3
+ export default function middlewareTransformer(list: MiddlewareType[]): MiddlewareHandler[];
@@ -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
- // if scopes is empty, then we don't need to check for scopes
10
+ var _a;
10
11
  if (isEmtpy)
11
12
  return next();
12
- // get the user scopes
13
- const requestRoles = (0, helpers_1.getRoles)(req);
14
- // find the first scope that is not in the userScopes
15
- const role = roles.find((scope) => requestRoles === null || requestRoles === void 0 ? void 0 : requestRoles.includes(scope.role));
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
- export default function scopeTransfrom(listScopes: ScopeType[], callback?: (middleware: MiddlewareHandler, scopes: {
4
- scope: string;
5
- description: string;
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
- function scopeTransfrom(listScopes, callback) {
7
- const { scopes, scopeNames, isEmtpy } = resolveScopes(listScopes);
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
- // if scopes is empty, then we don't need to check for scopes
11
- if (isEmtpy)
11
+ if (isEmpty)
12
12
  return next();
13
- // get the user scopes
14
- const userScopes = (0, helpers_1.getScopes)(req);
15
- // find the first scope that is not in the userScopes
16
- const error = scopes.find((scope) => !(userScopes === null || userScopes === void 0 ? void 0 : userScopes.includes(scope.scope)));
17
- if (error) {
18
- return next(new exeptions_1.NotScopeException((_a = error.message) !== null && _a !== void 0 ? _a : `You don't have the required scopes to access this resource`, userScopes, Array.from(scopeNames)));
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 (scopeNames.size > 0 && callback) {
23
- callback(middleware, scopes, scopeNames);
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
- if (typeof scope === "string") {
39
- $scopes[scope] = {
40
- scope,
41
- description: "",
42
- message: null,
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
- isEmtpy: values.length === 0,
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
+ };