@expressots/adapter-express 3.0.0 → 4.0.0-preview.1
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 +39 -96
- package/lib/CHANGELOG.md +31 -5
- package/lib/README.md +39 -96
- package/lib/cjs/adapter-express/application-express.base.js +3 -1
- package/lib/cjs/adapter-express/application-express.js +1049 -85
- package/lib/cjs/adapter-express/express-utils/conditional-middleware.js +102 -0
- package/lib/cjs/adapter-express/express-utils/constants.js +17 -0
- package/lib/cjs/adapter-express/express-utils/content-negotiation-decorators.js +129 -0
- package/lib/cjs/adapter-express/express-utils/decorators.js +186 -49
- package/lib/cjs/adapter-express/express-utils/exception-filter-decorators.js +11 -0
- package/lib/cjs/adapter-express/express-utils/guard-context-factory.js +84 -0
- package/lib/cjs/adapter-express/express-utils/guard-middleware.js +115 -0
- package/lib/cjs/adapter-express/express-utils/guard-utils.js +18 -0
- package/lib/cjs/adapter-express/express-utils/http-context-store.js +15 -0
- package/lib/cjs/adapter-express/express-utils/http-status-middleware.js +37 -2
- package/lib/cjs/adapter-express/express-utils/index.js +67 -1
- package/lib/cjs/adapter-express/express-utils/interceptor-middleware.js +132 -0
- package/lib/cjs/adapter-express/express-utils/inversify-express-server.js +810 -63
- package/lib/cjs/adapter-express/express-utils/lazy-module-middleware.js +241 -0
- package/lib/cjs/adapter-express/express-utils/middleware-composition.js +95 -0
- package/lib/cjs/adapter-express/express-utils/permission-preloader.middleware.js +48 -0
- package/lib/cjs/adapter-express/express-utils/route-constraints.js +95 -0
- package/lib/cjs/adapter-express/express-utils/scope-extractor.interface.js +2 -0
- package/lib/cjs/adapter-express/express-utils/scope-extractor.js +66 -0
- package/lib/cjs/adapter-express/express-utils/setup-authorization.js +71 -0
- package/lib/cjs/adapter-express/express-utils/setup-event-system.js +113 -0
- package/lib/cjs/adapter-express/express-utils/setup-interceptors.js +103 -0
- package/lib/cjs/adapter-express/express-utils/setup-lazy-loading.js +228 -0
- package/lib/cjs/adapter-express/express-utils/utils.js +30 -12
- package/lib/cjs/adapter-express/express-utils/validation-decorators.js +205 -0
- package/lib/cjs/adapter-express/express-utils/validation-service.js +252 -0
- package/lib/cjs/adapter-express/index.js +7 -5
- package/lib/cjs/adapter-express/micro-api/application-express-micro-route.js +31 -1
- package/lib/cjs/adapter-express/micro-api/application-express-micro.js +11 -37
- package/lib/cjs/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
- package/lib/cjs/adapter-express/micro-api/gateway/index.js +11 -0
- package/lib/cjs/adapter-express/micro-api/gateway/service-proxy.js +214 -0
- package/lib/cjs/adapter-express/micro-api/index.js +27 -3
- package/lib/cjs/adapter-express/micro-api/micro.js +217 -0
- package/lib/cjs/adapter-express/micro-api/queue/index.js +8 -0
- package/lib/cjs/adapter-express/micro-api/queue/queue.interface.js +2 -0
- package/lib/cjs/adapter-express/micro-api/queue/rabbitmq-consumer.js +255 -0
- package/lib/cjs/adapter-express/micro-api/serverless/aws-lambda.adapter.js +183 -0
- package/lib/cjs/adapter-express/micro-api/serverless/cloudflare.adapter.js +158 -0
- package/lib/cjs/adapter-express/micro-api/serverless/index.js +12 -0
- package/lib/cjs/adapter-express/micro-api/serverless/vercel.adapter.js +102 -0
- package/lib/cjs/adapter-express/micro-api/service-mesh/index.js +10 -0
- package/lib/cjs/adapter-express/micro-api/service-mesh/service-client.js +194 -0
- package/lib/cjs/adapter-express/micro-api/service-mesh/service-discovery.js +261 -0
- package/lib/cjs/adapter-express/middleware/index.js +21 -0
- package/lib/cjs/adapter-express/middleware/request-logging.middleware.js +244 -0
- package/lib/cjs/adapter-express/render/engine.js +15 -15
- package/lib/cjs/adapter-express/render/index.js +5 -0
- package/lib/cjs/adapter-express/studio/index.js +9 -0
- package/lib/cjs/adapter-express/studio/studio-integration.js +214 -0
- package/lib/cjs/index.js +1 -1
- package/lib/cjs/types/adapter-express/application-express.base.d.ts +20 -7
- package/lib/cjs/types/adapter-express/application-express.d.ts +273 -32
- package/lib/cjs/types/adapter-express/express-utils/base-middleware.d.ts +2 -2
- package/lib/cjs/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
- package/lib/cjs/types/adapter-express/express-utils/constants.d.ts +13 -0
- package/lib/cjs/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
- package/lib/cjs/types/adapter-express/express-utils/decorators.d.ts +54 -6
- package/lib/cjs/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
- package/lib/cjs/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
- package/lib/cjs/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
- package/lib/cjs/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
- package/lib/cjs/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
- package/lib/cjs/types/adapter-express/express-utils/httpResponseMessage.d.ts +1 -1
- package/lib/cjs/types/adapter-express/express-utils/index.d.ts +30 -2
- package/lib/cjs/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
- package/lib/cjs/types/adapter-express/express-utils/interfaces.d.ts +42 -5
- package/lib/cjs/types/adapter-express/express-utils/inversify-express-server.d.ts +114 -2
- package/lib/cjs/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
- package/lib/cjs/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
- package/lib/cjs/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
- package/lib/cjs/types/adapter-express/express-utils/route-constraints.d.ts +89 -0
- package/lib/cjs/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
- package/lib/cjs/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
- package/lib/cjs/types/adapter-express/express-utils/utils.d.ts +17 -2
- package/lib/cjs/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
- package/lib/cjs/types/adapter-express/express-utils/validation-service.d.ts +88 -0
- package/lib/cjs/types/adapter-express/index.d.ts +6 -4
- package/lib/cjs/types/adapter-express/micro-api/application-express-micro-route.d.ts +25 -14
- package/lib/cjs/types/adapter-express/micro-api/application-express-micro.d.ts +3 -10
- package/lib/cjs/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
- package/lib/cjs/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
- package/lib/cjs/types/adapter-express/micro-api/index.d.ts +7 -1
- package/lib/cjs/types/adapter-express/micro-api/micro.d.ts +66 -0
- package/lib/cjs/types/adapter-express/micro-api/queue/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
- package/lib/cjs/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
- package/lib/cjs/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
- package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
- package/lib/cjs/types/adapter-express/middleware/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
- package/lib/cjs/types/adapter-express/render/index.d.ts +1 -0
- package/lib/cjs/types/adapter-express/studio/index.d.ts +1 -0
- package/lib/cjs/types/adapter-express/studio/studio-integration.d.ts +92 -0
- package/lib/cjs/types/index.d.ts +1 -1
- package/lib/esm/adapter-express/application-express.base.js +24 -0
- package/lib/esm/adapter-express/application-express.js +1300 -0
- package/lib/esm/adapter-express/application-express.types.js +1 -0
- package/lib/esm/adapter-express/express-utils/base-middleware.js +19 -0
- package/lib/esm/adapter-express/express-utils/conditional-middleware.js +96 -0
- package/lib/esm/adapter-express/express-utils/constants.js +63 -0
- package/lib/esm/adapter-express/express-utils/content/httpContent.js +6 -0
- package/lib/esm/adapter-express/express-utils/content-negotiation-decorators.js +120 -0
- package/lib/esm/adapter-express/express-utils/decorators.js +575 -0
- package/lib/esm/adapter-express/express-utils/exception-filter-decorators.js +6 -0
- package/lib/esm/adapter-express/express-utils/guard-context-factory.js +83 -0
- package/lib/esm/adapter-express/express-utils/guard-middleware.js +115 -0
- package/lib/esm/adapter-express/express-utils/guard-utils.js +14 -0
- package/lib/esm/adapter-express/express-utils/http-context-store.js +10 -0
- package/lib/esm/adapter-express/express-utils/http-status-middleware.js +116 -0
- package/lib/esm/adapter-express/express-utils/httpResponseMessage.js +29 -0
- package/lib/esm/adapter-express/express-utils/index.js +24 -0
- package/lib/esm/adapter-express/express-utils/interceptor-middleware.js +130 -0
- package/lib/esm/adapter-express/express-utils/interfaces.js +1 -0
- package/lib/esm/adapter-express/express-utils/inversify-express-server.js +1031 -0
- package/lib/esm/adapter-express/express-utils/lazy-module-middleware.js +236 -0
- package/lib/esm/adapter-express/express-utils/middleware-composition.js +89 -0
- package/lib/esm/adapter-express/express-utils/permission-preloader.middleware.js +45 -0
- package/lib/esm/adapter-express/express-utils/resolver-multer.js +30 -0
- package/lib/esm/adapter-express/express-utils/route-constraints.js +91 -0
- package/lib/esm/adapter-express/express-utils/scope-extractor.interface.js +1 -0
- package/lib/esm/adapter-express/express-utils/scope-extractor.js +63 -0
- package/lib/esm/adapter-express/express-utils/setup-authorization.js +68 -0
- package/lib/esm/adapter-express/express-utils/setup-event-system.js +110 -0
- package/lib/esm/adapter-express/express-utils/setup-interceptors.js +100 -0
- package/lib/esm/adapter-express/express-utils/setup-lazy-loading.js +225 -0
- package/lib/esm/adapter-express/express-utils/utils.js +68 -0
- package/lib/esm/adapter-express/express-utils/validation-decorators.js +199 -0
- package/lib/esm/adapter-express/express-utils/validation-service.js +251 -0
- package/lib/esm/adapter-express/index.js +7 -0
- package/lib/esm/adapter-express/micro-api/application-express-micro-container.js +48 -0
- package/lib/esm/adapter-express/micro-api/application-express-micro-route.js +128 -0
- package/lib/esm/adapter-express/micro-api/application-express-micro.js +161 -0
- package/lib/esm/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
- package/lib/esm/adapter-express/micro-api/gateway/index.js +5 -0
- package/lib/esm/adapter-express/micro-api/gateway/service-proxy.js +210 -0
- package/lib/esm/adapter-express/micro-api/index.js +10 -0
- package/lib/esm/adapter-express/micro-api/micro.js +211 -0
- package/lib/esm/adapter-express/micro-api/queue/index.js +4 -0
- package/lib/esm/adapter-express/micro-api/queue/queue.interface.js +1 -0
- package/lib/esm/adapter-express/micro-api/queue/rabbitmq-consumer.js +229 -0
- package/lib/esm/adapter-express/micro-api/serverless/aws-lambda.adapter.js +180 -0
- package/lib/esm/adapter-express/micro-api/serverless/cloudflare.adapter.js +155 -0
- package/lib/esm/adapter-express/micro-api/serverless/index.js +6 -0
- package/lib/esm/adapter-express/micro-api/serverless/vercel.adapter.js +99 -0
- package/lib/esm/adapter-express/micro-api/service-mesh/index.js +5 -0
- package/lib/esm/adapter-express/micro-api/service-mesh/service-client.js +191 -0
- package/lib/esm/adapter-express/micro-api/service-mesh/service-discovery.js +259 -0
- package/lib/esm/adapter-express/middleware/index.js +5 -0
- package/lib/esm/adapter-express/middleware/request-logging.middleware.js +239 -0
- package/lib/esm/adapter-express/render/constants.js +37 -0
- package/lib/esm/adapter-express/render/engine.js +51 -0
- package/lib/esm/adapter-express/render/index.js +1 -0
- package/lib/esm/adapter-express/render/resolve-render.js +30 -0
- package/lib/esm/adapter-express/studio/index.js +1 -0
- package/lib/esm/adapter-express/studio/studio-integration.js +184 -0
- package/lib/esm/index.mjs +1 -0
- package/lib/esm/package.json +3 -0
- package/lib/esm/types/adapter-express/application-express.base.d.ts +77 -0
- package/lib/esm/types/adapter-express/application-express.d.ts +411 -0
- package/lib/esm/types/adapter-express/application-express.types.d.ts +23 -0
- package/lib/esm/types/adapter-express/express-utils/base-middleware.d.ts +8 -0
- package/lib/esm/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
- package/lib/esm/types/adapter-express/express-utils/constants.d.ts +57 -0
- package/lib/esm/types/adapter-express/express-utils/content/httpContent.d.ts +6 -0
- package/lib/esm/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
- package/lib/esm/types/adapter-express/express-utils/decorators.d.ts +257 -0
- package/lib/esm/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
- package/lib/esm/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
- package/lib/esm/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
- package/lib/esm/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
- package/lib/esm/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
- package/lib/esm/types/adapter-express/express-utils/http-status-middleware.d.ts +26 -0
- package/lib/esm/types/adapter-express/express-utils/httpResponseMessage.d.ts +14 -0
- package/lib/esm/types/adapter-express/express-utils/index.d.ts +30 -0
- package/lib/esm/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
- package/lib/esm/types/adapter-express/express-utils/interfaces.d.ts +115 -0
- package/lib/esm/types/adapter-express/express-utils/inversify-express-server.d.ts +172 -0
- package/lib/esm/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
- package/lib/esm/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
- package/lib/esm/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
- package/lib/esm/types/adapter-express/express-utils/resolver-multer.d.ts +7 -0
- package/lib/esm/types/adapter-express/express-utils/route-constraints.d.ts +89 -0
- package/lib/esm/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
- package/lib/esm/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
- package/lib/esm/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
- package/lib/esm/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
- package/lib/esm/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
- package/lib/esm/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
- package/lib/esm/types/adapter-express/express-utils/utils.d.ts +24 -0
- package/lib/esm/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
- package/lib/esm/types/adapter-express/express-utils/validation-service.d.ts +88 -0
- package/lib/esm/types/adapter-express/index.d.ts +7 -0
- package/lib/esm/types/adapter-express/micro-api/application-express-micro-container.d.ts +47 -0
- package/lib/esm/types/adapter-express/micro-api/application-express-micro-route.d.ts +104 -0
- package/lib/esm/types/adapter-express/micro-api/application-express-micro.d.ts +72 -0
- package/lib/esm/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
- package/lib/esm/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
- package/lib/esm/types/adapter-express/micro-api/index.d.ts +7 -0
- package/lib/esm/types/adapter-express/micro-api/micro.d.ts +66 -0
- package/lib/esm/types/adapter-express/micro-api/queue/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
- package/lib/esm/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
- package/lib/esm/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
- package/lib/esm/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
- package/lib/esm/types/adapter-express/middleware/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
- package/lib/esm/types/adapter-express/render/constants.d.ts +26 -0
- package/lib/esm/types/adapter-express/render/engine.d.ts +20 -0
- package/lib/esm/types/adapter-express/render/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/render/resolve-render.d.ts +7 -0
- package/lib/esm/types/adapter-express/studio/index.d.ts +1 -0
- package/lib/esm/types/adapter-express/studio/studio-integration.d.ts +92 -0
- package/lib/esm/types/index.d.ts +1 -0
- package/lib/package.json +156 -146
- package/package.json +156 -146
- package/lib/cjs/di/di.interfaces.js +0 -10
- package/lib/cjs/types/di/di.interfaces.d.ts +0 -289
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { inject, injectable, decorate, getGlobalUploadConfig } from "@expressots/core";
|
|
3
|
+
import { TYPE, METADATA_KEY, PARAMETER_TYPE, HTTP_CODE_METADATA, RENDER_METADATA_KEY, } from "./constants.js";
|
|
4
|
+
import { packageResolver } from "./resolver-multer.js";
|
|
5
|
+
import { Report, StatusCode } from "@expressots/core";
|
|
6
|
+
// Explicit type annotation: without this, the inferred type pulls a
|
|
7
|
+
// non-portable path from @expressots/core's internal decorator_utils,
|
|
8
|
+
// which TS2742 rejects under NodeNext when emitting .d.ts files.
|
|
9
|
+
export const injectHttpContext = inject(TYPE.HttpContext);
|
|
10
|
+
/**
|
|
11
|
+
* Controller decorator to define a new controller
|
|
12
|
+
* @param path route path
|
|
13
|
+
* @param middleware array of middleware to be applied to all routes in the controller
|
|
14
|
+
* @public API
|
|
15
|
+
*/
|
|
16
|
+
export function controller(path, ...middleware) {
|
|
17
|
+
return (target) => {
|
|
18
|
+
// Check for version metadata on the controller class
|
|
19
|
+
const controllerVersion = Reflect.getOwnMetadata(METADATA_KEY.version, target);
|
|
20
|
+
const currentMetadata = {
|
|
21
|
+
middleware,
|
|
22
|
+
path,
|
|
23
|
+
target: target,
|
|
24
|
+
version: controllerVersion,
|
|
25
|
+
};
|
|
26
|
+
const pathMetadata = Reflect.getOwnMetadata(HTTP_CODE_METADATA.path, Reflect) || {};
|
|
27
|
+
const statusCodeMetadata = Reflect.getOwnMetadata(HTTP_CODE_METADATA.statusCode, Reflect) || {};
|
|
28
|
+
const statusCodePathMapping = Reflect.getOwnMetadata(HTTP_CODE_METADATA.httpCode, Reflect) || {};
|
|
29
|
+
for (const key in pathMetadata) {
|
|
30
|
+
if (statusCodeMetadata && statusCodeMetadata[key]) {
|
|
31
|
+
const methodPath = pathMetadata[key]["path"];
|
|
32
|
+
// Properly join controller and method paths
|
|
33
|
+
let realPath;
|
|
34
|
+
if (methodPath === "/" || methodPath === "") {
|
|
35
|
+
realPath = path;
|
|
36
|
+
}
|
|
37
|
+
else if (path === "/" || path === "") {
|
|
38
|
+
realPath = methodPath.startsWith("/") ? methodPath : `/${methodPath}`;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// Normalize: remove trailing slash from controller, ensure method has leading slash
|
|
42
|
+
const basePath = path.endsWith("/") ? path.slice(0, -1) : path;
|
|
43
|
+
const subPath = methodPath.startsWith("/") ? methodPath : `/${methodPath}`;
|
|
44
|
+
realPath = `${basePath}${subPath}`;
|
|
45
|
+
}
|
|
46
|
+
statusCodePathMapping[`${realPath}/-${pathMetadata[key]["method"].toLowerCase()}`] =
|
|
47
|
+
statusCodeMetadata[key];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
Reflect.defineMetadata(HTTP_CODE_METADATA.httpCode, statusCodePathMapping, Reflect);
|
|
51
|
+
Reflect.deleteMetadata(HTTP_CODE_METADATA.statusCode, Reflect);
|
|
52
|
+
Reflect.deleteMetadata(HTTP_CODE_METADATA.path, Reflect);
|
|
53
|
+
decorate(injectable(), target);
|
|
54
|
+
Reflect.defineMetadata(METADATA_KEY.controller, currentMetadata, target);
|
|
55
|
+
const previousMetadata = Reflect.getMetadata(METADATA_KEY.controller, Reflect) || [];
|
|
56
|
+
const newMetadata = [currentMetadata, ...previousMetadata];
|
|
57
|
+
Reflect.defineMetadata(METADATA_KEY.controller, newMetadata, Reflect);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Http decorator to define the status code for a route
|
|
62
|
+
* @param code
|
|
63
|
+
* @returns MethodDecorator
|
|
64
|
+
* @example ```typescript
|
|
65
|
+
* @Http(200)
|
|
66
|
+
* @Get("/")
|
|
67
|
+
* hello() {
|
|
68
|
+
* return "Hello World";
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
* @public API
|
|
72
|
+
*/
|
|
73
|
+
export function Http(code) {
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
75
|
+
return (target, key, descriptor) => {
|
|
76
|
+
let httpCodeMetadata = Reflect.getOwnMetadata(HTTP_CODE_METADATA.statusCode, Reflect);
|
|
77
|
+
if (httpCodeMetadata) {
|
|
78
|
+
httpCodeMetadata[key] = code;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
httpCodeMetadata = {};
|
|
82
|
+
httpCodeMetadata[key] = code;
|
|
83
|
+
}
|
|
84
|
+
Reflect.defineMetadata(HTTP_CODE_METADATA.statusCode, httpCodeMetadata, Reflect);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Version decorator to define the API version for a controller or route method
|
|
89
|
+
* @param version API version (e.g., "1", "1.0", "v1", or 1)
|
|
90
|
+
* @returns ClassDecorator | MethodDecorator
|
|
91
|
+
* @example ```typescript
|
|
92
|
+
* @Version("1")
|
|
93
|
+
* @controller("/users")
|
|
94
|
+
* class UserController {}
|
|
95
|
+
*
|
|
96
|
+
* // Or at method level:
|
|
97
|
+
* @Version("2")
|
|
98
|
+
* @Get("/")
|
|
99
|
+
* getUsers() {
|
|
100
|
+
* return "v2 users";
|
|
101
|
+
* }
|
|
102
|
+
* ```
|
|
103
|
+
* @public API
|
|
104
|
+
*/
|
|
105
|
+
export function Version(version) {
|
|
106
|
+
// Normalize version to string format (e.g., "v1" or "1" -> "v1")
|
|
107
|
+
const normalizedVersion = typeof version === "number" ? `v${version}` : version.startsWith("v") ? version : `v${version}`;
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
+
return (target, key, descriptor) => {
|
|
110
|
+
if (key !== undefined && descriptor !== undefined) {
|
|
111
|
+
// Method decorator - store version metadata for the method
|
|
112
|
+
// This will be read by enhancedHttpMethod/Method when they create metadata
|
|
113
|
+
Reflect.defineMetadata(METADATA_KEY.version, normalizedVersion, target, key);
|
|
114
|
+
// Also update existing metadata if it exists
|
|
115
|
+
const metadataList = Reflect.getOwnMetadata(METADATA_KEY.controllerMethod, target.constructor);
|
|
116
|
+
if (metadataList) {
|
|
117
|
+
const methodMetadata = metadataList.find((m) => m.key === key);
|
|
118
|
+
if (methodMetadata) {
|
|
119
|
+
methodMetadata.version = normalizedVersion;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Class decorator - store version metadata for the controller
|
|
125
|
+
// This will be read by controller decorator when it creates metadata
|
|
126
|
+
Reflect.defineMetadata(METADATA_KEY.version, normalizedVersion, target);
|
|
127
|
+
// Also update existing metadata if it exists
|
|
128
|
+
const controllerMetadata = Reflect.getOwnMetadata(METADATA_KEY.controller, target);
|
|
129
|
+
if (controllerMetadata) {
|
|
130
|
+
controllerMetadata.version = normalizedVersion;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Decorator to allow accept all HTTP methods
|
|
137
|
+
* @param path route path, wildcard
|
|
138
|
+
* @param middleware array of middleware to be applied to all routes defined in path logic
|
|
139
|
+
* @public API
|
|
140
|
+
*/
|
|
141
|
+
export function All(path, ...middleware) {
|
|
142
|
+
return Method("all", path, ...middleware);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Decorator to allow GET HTTP method
|
|
146
|
+
* @param path route path
|
|
147
|
+
* @param middleware array of middleware to be applied to the route
|
|
148
|
+
* @public API
|
|
149
|
+
*/
|
|
150
|
+
export function Get(path, ...middleware) {
|
|
151
|
+
return enhancedHttpMethod("get", path, ...middleware);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Decorator to allow POST HTTP method
|
|
155
|
+
* @param path route path
|
|
156
|
+
* @param middleware array of middleware to be applied to the route
|
|
157
|
+
* @public API
|
|
158
|
+
*/
|
|
159
|
+
export function Post(path, ...middleware) {
|
|
160
|
+
return Method("post", path, ...middleware);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Decorator to allow PUT HTTP method
|
|
164
|
+
* @param path route path
|
|
165
|
+
* @param middleware array of middleware to be applied to the route
|
|
166
|
+
* @public API
|
|
167
|
+
*/
|
|
168
|
+
export function Put(path, ...middleware) {
|
|
169
|
+
return enhancedHttpMethod("put", path, ...middleware);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Decorator to allow PATCH HTTP method
|
|
173
|
+
* @param path route path
|
|
174
|
+
* @param middleware array of middleware to be applied to the route
|
|
175
|
+
* @public API
|
|
176
|
+
*/
|
|
177
|
+
export function Patch(path, ...middleware) {
|
|
178
|
+
return enhancedHttpMethod("patch", path, ...middleware);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Decorator to allow HEAD HTTP method
|
|
182
|
+
* @param path route path
|
|
183
|
+
* @param middleware array of middleware to be applied to the route
|
|
184
|
+
* @public API
|
|
185
|
+
*/
|
|
186
|
+
export function Head(path, ...middleware) {
|
|
187
|
+
return Method("head", path, ...middleware);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Decorator to allow DELETE HTTP method
|
|
191
|
+
* @param path route path
|
|
192
|
+
* @param middleware array of middleware to be applied to the route
|
|
193
|
+
* @public API
|
|
194
|
+
*/
|
|
195
|
+
export function Delete(path, ...middleware) {
|
|
196
|
+
return enhancedHttpMethod("delete", path, ...middleware);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Decorator to allow OPTIONS HTTP method
|
|
200
|
+
* @param path route path
|
|
201
|
+
* @param middleware array of middleware to be applied to the route
|
|
202
|
+
*/
|
|
203
|
+
function enhancedHttpMethod(method, path, ...middleware) {
|
|
204
|
+
return (target, key) => {
|
|
205
|
+
// Check for version metadata on the method
|
|
206
|
+
const methodVersion = Reflect.getOwnMetadata(METADATA_KEY.version, target, key);
|
|
207
|
+
const metadata = {
|
|
208
|
+
key: String(key),
|
|
209
|
+
method,
|
|
210
|
+
middleware,
|
|
211
|
+
path,
|
|
212
|
+
target: target,
|
|
213
|
+
version: methodVersion,
|
|
214
|
+
};
|
|
215
|
+
let metadataList = [];
|
|
216
|
+
let pathMetadata = Reflect.getOwnMetadata(HTTP_CODE_METADATA.path, Reflect);
|
|
217
|
+
if (pathMetadata) {
|
|
218
|
+
pathMetadata[key] = {
|
|
219
|
+
path,
|
|
220
|
+
method,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
pathMetadata = {};
|
|
225
|
+
pathMetadata[key] = {
|
|
226
|
+
path,
|
|
227
|
+
method,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
Reflect.defineMetadata(HTTP_CODE_METADATA.path, pathMetadata, Reflect);
|
|
231
|
+
if (!Reflect.hasOwnMetadata(METADATA_KEY.controllerMethod, target.constructor)) {
|
|
232
|
+
Reflect.defineMetadata(METADATA_KEY.controllerMethod, metadataList, target.constructor);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
metadataList = Reflect.getOwnMetadata(METADATA_KEY.controllerMethod, target.constructor);
|
|
236
|
+
}
|
|
237
|
+
metadataList.push(metadata);
|
|
238
|
+
const paramsInfo = Reflect.getMetadata("design:paramtypes", target, key) || [];
|
|
239
|
+
metadataList.forEach((m) => {
|
|
240
|
+
m.middleware.unshift((req, res, next) => {
|
|
241
|
+
req.params &&
|
|
242
|
+
Object.keys(req.params).forEach((param, idx) => {
|
|
243
|
+
const type = paramsInfo[idx];
|
|
244
|
+
req.params[param] = convertToType(req.params[param], type);
|
|
245
|
+
});
|
|
246
|
+
next();
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Decorator to allow custom HTTP method
|
|
253
|
+
* @param method custom HTTP method
|
|
254
|
+
* @param path route path
|
|
255
|
+
* @param middleware array of middleware to be applied to the route
|
|
256
|
+
* @public API
|
|
257
|
+
*/
|
|
258
|
+
export function Method(method, path, ...middleware) {
|
|
259
|
+
return (target, key) => {
|
|
260
|
+
// Check for version metadata on the method
|
|
261
|
+
const methodVersion = Reflect.getOwnMetadata(METADATA_KEY.version, target, key);
|
|
262
|
+
const metadata = {
|
|
263
|
+
key: String(key),
|
|
264
|
+
method,
|
|
265
|
+
middleware,
|
|
266
|
+
path,
|
|
267
|
+
target: target,
|
|
268
|
+
version: methodVersion,
|
|
269
|
+
};
|
|
270
|
+
let metadataList = [];
|
|
271
|
+
let pathMetadata = Reflect.getOwnMetadata(HTTP_CODE_METADATA.path, Reflect);
|
|
272
|
+
if (pathMetadata) {
|
|
273
|
+
pathMetadata[key] = {
|
|
274
|
+
path,
|
|
275
|
+
method,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
pathMetadata = {};
|
|
280
|
+
pathMetadata[key] = {
|
|
281
|
+
path,
|
|
282
|
+
method,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
Reflect.defineMetadata(HTTP_CODE_METADATA.path, pathMetadata, Reflect);
|
|
286
|
+
if (!Reflect.hasOwnMetadata(METADATA_KEY.controllerMethod, target.constructor)) {
|
|
287
|
+
Reflect.defineMetadata(METADATA_KEY.controllerMethod, metadataList, target.constructor);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
metadataList = Reflect.getOwnMetadata(METADATA_KEY.controllerMethod, target.constructor);
|
|
291
|
+
}
|
|
292
|
+
metadataList.push(metadata);
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Parameter decorator to inject the request object
|
|
297
|
+
* @returns ParameterDecorator
|
|
298
|
+
*/
|
|
299
|
+
export const request = paramDecoratorFactory(PARAMETER_TYPE.REQUEST);
|
|
300
|
+
/**
|
|
301
|
+
* Parameter decorator to inject the response object
|
|
302
|
+
* @returns ParameterDecorator
|
|
303
|
+
*/
|
|
304
|
+
export const response = paramDecoratorFactory(PARAMETER_TYPE.RESPONSE);
|
|
305
|
+
/**
|
|
306
|
+
* Parameter decorator to inject parameters from the route
|
|
307
|
+
* @returns ParameterDecorator
|
|
308
|
+
*/
|
|
309
|
+
export const param = paramDecoratorFactory(PARAMETER_TYPE.PARAMS);
|
|
310
|
+
/**
|
|
311
|
+
* Parameter decorator to inject query parameters
|
|
312
|
+
* @returns ParameterDecorator
|
|
313
|
+
*/
|
|
314
|
+
export const query = paramDecoratorFactory(PARAMETER_TYPE.QUERY);
|
|
315
|
+
/**
|
|
316
|
+
* Parameter decorator to inject the request body
|
|
317
|
+
* @returns ParameterDecorator
|
|
318
|
+
*/
|
|
319
|
+
export const body = paramDecoratorFactory(PARAMETER_TYPE.BODY);
|
|
320
|
+
/**
|
|
321
|
+
* Parameter decorator to inject the request headers
|
|
322
|
+
* @returns ParameterDecorator
|
|
323
|
+
*/
|
|
324
|
+
export const headers = paramDecoratorFactory(PARAMETER_TYPE.HEADERS);
|
|
325
|
+
/**
|
|
326
|
+
* Parameter decorator to inject the request cookies
|
|
327
|
+
* @returns ParameterDecorator
|
|
328
|
+
*/
|
|
329
|
+
export const cookies = paramDecoratorFactory(PARAMETER_TYPE.COOKIES);
|
|
330
|
+
/**
|
|
331
|
+
* Parameter decorator next function
|
|
332
|
+
* @returns ParameterDecorator
|
|
333
|
+
*/
|
|
334
|
+
export const next = paramDecoratorFactory(PARAMETER_TYPE.NEXT);
|
|
335
|
+
/**
|
|
336
|
+
* Parameter decorator to inject the principal object obtained from AuthProvider
|
|
337
|
+
* @returns ParameterDecorator
|
|
338
|
+
*/
|
|
339
|
+
export const principal = paramDecoratorFactory(PARAMETER_TYPE.PRINCIPAL);
|
|
340
|
+
/**
|
|
341
|
+
* Parameter decorator to inject the request user object
|
|
342
|
+
* @returns ParameterDecorator
|
|
343
|
+
*/
|
|
344
|
+
function paramDecoratorFactory(parameterType) {
|
|
345
|
+
return (name) => params(parameterType, name);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Parameter decorator to inject the request object
|
|
349
|
+
* @returns ParameterDecorator
|
|
350
|
+
* @param type - The type of parameter to inject
|
|
351
|
+
* @param parameterName - The name of the parameter to inject
|
|
352
|
+
* @public API
|
|
353
|
+
*/
|
|
354
|
+
export function params(type, parameterName) {
|
|
355
|
+
return (target, methodName, index) => {
|
|
356
|
+
let metadataList = {};
|
|
357
|
+
let parameterMetadataList = [];
|
|
358
|
+
const parameterMetadata = {
|
|
359
|
+
index,
|
|
360
|
+
injectRoot: parameterName === undefined,
|
|
361
|
+
parameterName,
|
|
362
|
+
type,
|
|
363
|
+
};
|
|
364
|
+
if (!Reflect.hasOwnMetadata(METADATA_KEY.controllerParameter, target.constructor)) {
|
|
365
|
+
parameterMetadataList.unshift(parameterMetadata);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
metadataList = Reflect.getOwnMetadata(METADATA_KEY.controllerParameter, target.constructor);
|
|
369
|
+
if (metadataList[methodName]) {
|
|
370
|
+
parameterMetadataList = metadataList[methodName] || [];
|
|
371
|
+
}
|
|
372
|
+
parameterMetadataList.unshift(parameterMetadata);
|
|
373
|
+
}
|
|
374
|
+
metadataList[methodName] = parameterMetadataList;
|
|
375
|
+
Reflect.defineMetadata(METADATA_KEY.controllerParameter, metadataList, target.constructor);
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Render decorator to define the template and default data for a route
|
|
380
|
+
* @param template The template to render
|
|
381
|
+
* @param defaultData The default data to pass to the template
|
|
382
|
+
* @returns MethodDecorator
|
|
383
|
+
* @public API
|
|
384
|
+
*/
|
|
385
|
+
export function Render(template, defaultData) {
|
|
386
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
387
|
+
return (target, propertyKey, descriptor) => {
|
|
388
|
+
Reflect.defineMetadata(RENDER_METADATA_KEY, { template, defaultData }, target, propertyKey);
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
export function getRenderMetadata(target, propertyKey) {
|
|
392
|
+
return Reflect.getMetadata(RENDER_METADATA_KEY, target, propertyKey) || {};
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Converts a string value to the specified type.
|
|
396
|
+
* @param value The value to convert.
|
|
397
|
+
* @param type The type to convert the value to.
|
|
398
|
+
* @returns The converted value.
|
|
399
|
+
*/
|
|
400
|
+
function convertToType(value, type) {
|
|
401
|
+
if (type === Number) {
|
|
402
|
+
return Number(value);
|
|
403
|
+
}
|
|
404
|
+
else if (type === String) {
|
|
405
|
+
return value;
|
|
406
|
+
}
|
|
407
|
+
else if (type === Boolean) {
|
|
408
|
+
return value === "true" || value === "1";
|
|
409
|
+
}
|
|
410
|
+
return value;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Type guard to check if an object is a Request
|
|
414
|
+
*/
|
|
415
|
+
function isRequest(obj) {
|
|
416
|
+
return (typeof obj === "object" && obj !== null && "method" in obj && "headers" in obj && "url" in obj);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Type guard to check if an object is a Response
|
|
420
|
+
*/
|
|
421
|
+
function isResponse(obj) {
|
|
422
|
+
return (typeof obj === "object" && obj !== null && "status" in obj && "json" in obj && "send" in obj);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* File upload decorator to handle file uploads.
|
|
426
|
+
*
|
|
427
|
+
* This decorator integrates with the global upload configuration
|
|
428
|
+
* set via `Middleware.upload()` in app.ts. If global config exists,
|
|
429
|
+
* it will be used as defaults, with local options taking precedence.
|
|
430
|
+
*
|
|
431
|
+
* @param options - Field configuration (fieldName, maxCount, none, any)
|
|
432
|
+
* @param multerOptions - Optional multer options (overrides global config)
|
|
433
|
+
* @default { none: true }
|
|
434
|
+
* @returns MethodDecorator
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* ```typescript
|
|
438
|
+
* // In app.ts - configure globally (optional)
|
|
439
|
+
* this.Middleware.upload({
|
|
440
|
+
* destination: './uploads',
|
|
441
|
+
* limits: { fileSize: 10 * 1024 * 1024 }
|
|
442
|
+
* });
|
|
443
|
+
*
|
|
444
|
+
* // In controller - uses global config automatically
|
|
445
|
+
* @Post('avatar')
|
|
446
|
+
* @FileUpload({ fieldName: 'avatar' })
|
|
447
|
+
* uploadAvatar(req: Request) {
|
|
448
|
+
* return req.file;
|
|
449
|
+
* }
|
|
450
|
+
*
|
|
451
|
+
* // Override global config for specific endpoint
|
|
452
|
+
* @Post('document')
|
|
453
|
+
* @FileUpload({ fieldName: 'doc' }, { limits: { fileSize: 50 * 1024 * 1024 } })
|
|
454
|
+
* uploadDocument(req: Request) {
|
|
455
|
+
* return req.file;
|
|
456
|
+
* }
|
|
457
|
+
* ```
|
|
458
|
+
*
|
|
459
|
+
* @public API
|
|
460
|
+
*/
|
|
461
|
+
export function FileUpload(options, multerOptions) {
|
|
462
|
+
const multer = packageResolver("multer");
|
|
463
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
464
|
+
let upload;
|
|
465
|
+
let method = "none";
|
|
466
|
+
if (multer) {
|
|
467
|
+
if (options === undefined) {
|
|
468
|
+
options = { none: true };
|
|
469
|
+
}
|
|
470
|
+
// Get global upload configuration (set via Middleware.upload())
|
|
471
|
+
const globalConfig = getGlobalUploadConfig();
|
|
472
|
+
// Build final multer options, merging global config with local options
|
|
473
|
+
// Local options always take precedence over global config
|
|
474
|
+
const finalMulterOptions = {};
|
|
475
|
+
// Apply global config as defaults
|
|
476
|
+
if (globalConfig) {
|
|
477
|
+
if (globalConfig.destination) {
|
|
478
|
+
finalMulterOptions.dest = globalConfig.destination;
|
|
479
|
+
}
|
|
480
|
+
if (globalConfig.limits) {
|
|
481
|
+
finalMulterOptions.limits = globalConfig.limits;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Apply local options (overrides global)
|
|
485
|
+
if (multerOptions) {
|
|
486
|
+
if (multerOptions.dest) {
|
|
487
|
+
finalMulterOptions.dest = multerOptions.dest;
|
|
488
|
+
}
|
|
489
|
+
if (multerOptions.limits) {
|
|
490
|
+
// Merge limits - local takes precedence
|
|
491
|
+
finalMulterOptions.limits = {
|
|
492
|
+
...finalMulterOptions.limits,
|
|
493
|
+
...multerOptions.limits,
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
if (multerOptions.storage) {
|
|
497
|
+
finalMulterOptions.storage = multerOptions.storage;
|
|
498
|
+
}
|
|
499
|
+
if (multerOptions.fileFilter) {
|
|
500
|
+
finalMulterOptions.fileFilter = multerOptions.fileFilter;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
upload = multer(finalMulterOptions);
|
|
504
|
+
method = inferMulterMethod(options);
|
|
505
|
+
}
|
|
506
|
+
return function (target, propertyKey, descriptor) {
|
|
507
|
+
const originalMethod = descriptor.value;
|
|
508
|
+
descriptor.value = function (...args) {
|
|
509
|
+
const req = args.find(isRequest);
|
|
510
|
+
const res = args.find(isResponse);
|
|
511
|
+
const multerMiddleware = getMulterMiddleware(upload, options, method);
|
|
512
|
+
multerMiddleware(req, res, (err) => {
|
|
513
|
+
if (err) {
|
|
514
|
+
return res.status(400).json({ error: err.message });
|
|
515
|
+
}
|
|
516
|
+
const result = originalMethod.apply(this, args);
|
|
517
|
+
if (res &&
|
|
518
|
+
result &&
|
|
519
|
+
typeof result != "undefined" &&
|
|
520
|
+
!isRequest(result) &&
|
|
521
|
+
!isResponse(result)) {
|
|
522
|
+
return res.send(result);
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
};
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Infer the multer method to use based on the provided options
|
|
530
|
+
* @param options
|
|
531
|
+
* @returns
|
|
532
|
+
*/
|
|
533
|
+
function inferMulterMethod(options) {
|
|
534
|
+
const report = new Report();
|
|
535
|
+
if (options.none)
|
|
536
|
+
return "none";
|
|
537
|
+
if (options.any)
|
|
538
|
+
return "any";
|
|
539
|
+
if (Array.isArray(options))
|
|
540
|
+
return "fields";
|
|
541
|
+
if (options.fieldName && options.maxCount !== undefined)
|
|
542
|
+
return "array";
|
|
543
|
+
if (options.fieldName)
|
|
544
|
+
return "single";
|
|
545
|
+
throw report.error("Invalid options provided for FileUpload.", StatusCode.InternalServerError, "multer-decorator");
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Get the multer middleware based on the method
|
|
549
|
+
* @param upload
|
|
550
|
+
* @param options
|
|
551
|
+
* @param method
|
|
552
|
+
* @returns RequestHandler
|
|
553
|
+
*/
|
|
554
|
+
function getMulterMiddleware(upload, options, method) {
|
|
555
|
+
const report = new Report();
|
|
556
|
+
switch (method) {
|
|
557
|
+
case "single":
|
|
558
|
+
return upload.single(options.fieldName);
|
|
559
|
+
case "array":
|
|
560
|
+
return upload.array(options.fieldName, options.maxCount);
|
|
561
|
+
case "fields": {
|
|
562
|
+
const fieldsOptions = options.map((opt) => ({
|
|
563
|
+
name: opt.fieldName,
|
|
564
|
+
maxCount: opt.maxCount,
|
|
565
|
+
}));
|
|
566
|
+
return upload.fields(fieldsOptions);
|
|
567
|
+
}
|
|
568
|
+
case "none":
|
|
569
|
+
return upload.none();
|
|
570
|
+
case "any":
|
|
571
|
+
return upload.any();
|
|
572
|
+
default:
|
|
573
|
+
throw report.error(`Unsupported Multer method: ${method}`, StatusCode.InternalServerError, "multer-decorator");
|
|
574
|
+
}
|
|
575
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import "reflect-metadata";
|
|
14
|
+
import { inject, injectable, Container } from "@expressots/core";
|
|
15
|
+
import { getHttpContext } from "./http-context-store.js";
|
|
16
|
+
/**
|
|
17
|
+
* Factory for creating GuardContext from Express request/response
|
|
18
|
+
*/
|
|
19
|
+
let GuardContextFactory = class GuardContextFactory {
|
|
20
|
+
container;
|
|
21
|
+
scopeExtractor;
|
|
22
|
+
constructor(container, scopeExtractor) {
|
|
23
|
+
this.container = container;
|
|
24
|
+
this.scopeExtractor = scopeExtractor;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create GuardContext from Express request/response
|
|
28
|
+
*/
|
|
29
|
+
async create(req, res) {
|
|
30
|
+
// Get HttpContext (created by InversifyExpressServer's first middleware
|
|
31
|
+
// and stored in a per-request WeakMap; see http-context-store.ts).
|
|
32
|
+
const httpContext = getHttpContext(req);
|
|
33
|
+
if (!httpContext) {
|
|
34
|
+
throw new Error("HttpContext not found on request. Ensure InversifyExpressServer is properly configured.");
|
|
35
|
+
}
|
|
36
|
+
// Extract scope information
|
|
37
|
+
const scope = await this.scopeExtractor.extract(req);
|
|
38
|
+
// Extract route metadata
|
|
39
|
+
const route = {
|
|
40
|
+
controller:
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
req.__expressotsControllerName || "unknown",
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
method: req.__expressotsMethod || "unknown",
|
|
45
|
+
path: req.path,
|
|
46
|
+
params: req.params,
|
|
47
|
+
query: req.query,
|
|
48
|
+
};
|
|
49
|
+
// Create guard context
|
|
50
|
+
// Note: httpContext.user is Principal from adapter-express, but GuardContext expects Principal from core
|
|
51
|
+
// They have the same structure, so this is compatible
|
|
52
|
+
// Note: httpContext.container is inversifyInterfaces.Container, but GuardContext expects Container from core
|
|
53
|
+
// They are compatible, so we cast it
|
|
54
|
+
const context = {
|
|
55
|
+
request: req,
|
|
56
|
+
response: res,
|
|
57
|
+
principal: httpContext.user, // Cast to core Principal type (same structure)
|
|
58
|
+
container: httpContext.container, // Request-scoped child container!
|
|
59
|
+
scope,
|
|
60
|
+
route,
|
|
61
|
+
getScoped: (identifier, scopeName) => {
|
|
62
|
+
// Resolve with scope awareness
|
|
63
|
+
// Note: scopeName is optional and can be used for custom scopes (e.g., tenant)
|
|
64
|
+
if (scopeName) {
|
|
65
|
+
// For custom scopes, use named binding or scope registry
|
|
66
|
+
// For now, fallback to regular get (can be enhanced later)
|
|
67
|
+
return httpContext.container.get(identifier);
|
|
68
|
+
}
|
|
69
|
+
return httpContext.container.get(identifier);
|
|
70
|
+
},
|
|
71
|
+
getTenantId: () => scope.tenant,
|
|
72
|
+
getRequestId: () => scope.request,
|
|
73
|
+
};
|
|
74
|
+
return context;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
GuardContextFactory = __decorate([
|
|
78
|
+
injectable(),
|
|
79
|
+
__param(0, inject(Container)),
|
|
80
|
+
__param(1, inject("IScopeExtractor")),
|
|
81
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
82
|
+
], GuardContextFactory);
|
|
83
|
+
export { GuardContextFactory };
|