@catbee/utils 0.0.8-rc.4 → 1.0.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/build/index.cjs CHANGED
@@ -1660,7 +1660,7 @@ function addSensitiveFields(fields) {
1660
1660
  __name(addSensitiveFields, "addSensitiveFields");
1661
1661
  var _globalThis = typeof globalThis === "object" ? globalThis : global;
1662
1662
  var _global = _globalThis;
1663
- function setupLogger() {
1663
+ function setupLogger(isGlobal = true) {
1664
1664
  const logParams = {
1665
1665
  name: config.logger.name || "@catbee/utils",
1666
1666
  level: config.logger.level || "info",
@@ -1674,14 +1674,14 @@ function setupLogger() {
1674
1674
  ],
1675
1675
  censor: /* @__PURE__ */ __name((value, path3) => redact(value, path3), "censor")
1676
1676
  },
1677
- // serializers: {
1678
- // req: pino.stdSerializers.req,
1679
- // request: pino.stdSerializers.req,
1680
- // res: pino.stdSerializers.res,
1681
- // response: pino.stdSerializers.res,
1682
- // err: pino.stdSerializers.err,
1683
- // error: pino.stdSerializers.err
1684
- // },
1677
+ serializers: {
1678
+ req: pino__default.default.stdSerializers.req,
1679
+ request: pino__default.default.stdSerializers.req,
1680
+ res: pino__default.default.stdSerializers.res,
1681
+ response: pino__default.default.stdSerializers.res,
1682
+ err: pino__default.default.stdSerializers.err,
1683
+ error: pino__default.default.stdSerializers.err
1684
+ },
1685
1685
  timestamp: pino.stdTimeFunctions.isoTime
1686
1686
  };
1687
1687
  const logger2 = config.logger.pretty && Env.isDev() ? pino__default.default(logParams, pino__default.default.transport({
@@ -1694,11 +1694,17 @@ function setupLogger() {
1694
1694
  levelFirst: true
1695
1695
  }
1696
1696
  })) : pino__default.default(logParams);
1697
- _global[GLOBAL_LOGGER_KEY] = logger2;
1698
- _global[GLOBAL_LOGGER_KEY]?.debug("Logger initialized");
1697
+ if (isGlobal) {
1698
+ _global[GLOBAL_LOGGER_KEY] = logger2;
1699
+ _global[GLOBAL_LOGGER_KEY]?.debug("Logger initialized");
1700
+ }
1701
+ return logger2;
1699
1702
  }
1700
1703
  __name(setupLogger, "setupLogger");
1701
- function getLogger() {
1704
+ function getLogger(newInstance = false) {
1705
+ if (newInstance) {
1706
+ return setupLogger(false);
1707
+ }
1702
1708
  const logger2 = ContextStore.get(StoreKeys.LOGGER);
1703
1709
  if (logger2) return logger2;
1704
1710
  if (!_global[GLOBAL_LOGGER_KEY]) {
@@ -1707,7 +1713,7 @@ function getLogger() {
1707
1713
  return _global[GLOBAL_LOGGER_KEY];
1708
1714
  }
1709
1715
  __name(getLogger, "getLogger");
1710
- var logger = getLogger();
1716
+ var logger = getLogger(false);
1711
1717
  function createChildLogger(bindings, parentLogger) {
1712
1718
  const logger2 = parentLogger || getLogger();
1713
1719
  return logger2.child(bindings);
@@ -2751,338 +2757,761 @@ var HttpStatusCodes = /* @__PURE__ */ (function(HttpStatusCodes2) {
2751
2757
  HttpStatusCodes2[HttpStatusCodes2["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
2752
2758
  return HttpStatusCodes2;
2753
2759
  })({});
2754
- var ROUTES_KEY = Symbol("routes");
2755
- var MIDDLEWARE_KEY = Symbol("middlewares");
2756
- var PARAMS_KEY = Symbol("params");
2757
- var HTTP_CODE_KEY = Symbol("httpCode");
2758
- var HEADER_KEY = Symbol("headers");
2759
- var BEFORE_KEY = Symbol("before");
2760
- var AFTER_KEY = Symbol("after");
2761
- var ROLES_KEY = Symbol("roles");
2762
- var REDIRECT_KEY = Symbol("redirect");
2763
- var CACHE_KEY = Symbol("cache");
2764
- var RATE_LIMIT_KEY = Symbol("rateLimit");
2765
- var CONTENT_TYPE_KEY = Symbol("contentType");
2766
- var VERSION_KEY = Symbol("version");
2767
- var TIMEOUT_KEY = Symbol("timeout");
2768
- var LOG_KEY = Symbol("log");
2769
- var RateLimiterCache = class RateLimiterCache2 {
2760
+
2761
+ // src/utils/exception.utils.ts
2762
+ var HttpError = class extends ErrorResponse {
2770
2763
  static {
2771
- __name(this, "RateLimiterCache");
2764
+ __name(this, "HttpError");
2772
2765
  }
2773
- cache;
2774
- constructor(maxSize = 100, ttlMs = 5 * 60 * 1e3) {
2775
- this.cache = new TTLCache({
2776
- maxSize,
2777
- ttlMs
2778
- });
2766
+ /**
2767
+ * Creates a new HTTP error instance.
2768
+ * @param status - A valid HTTP status code (e.g., 400, 500).
2769
+ * @param message - The error message to return to the client.
2770
+ */
2771
+ constructor(status, message) {
2772
+ super(message);
2773
+ this.status = status;
2779
2774
  }
2780
- generateKey(options) {
2781
- return `${options.max}:${options.windowMs}:${options.standardHeaders}:${options.legacyHeaders}`;
2775
+ };
2776
+ var InternalServerErrorException = class extends ErrorResponse {
2777
+ static {
2778
+ __name(this, "InternalServerErrorException");
2782
2779
  }
2783
- get(options) {
2784
- const key = this.generateKey(options);
2785
- const cached = this.cache.get(key);
2786
- if (cached) {
2787
- return cached.limiter;
2788
- }
2789
- const limiter = expressRateLimit.rateLimit({
2790
- ...options,
2791
- handler: /* @__PURE__ */ __name((req, res) => {
2792
- const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.TOO_MANY_REQUESTS, "Too Many Requests");
2793
- res.status(HttpStatusCodes.TOO_MANY_REQUESTS).json(errorResponse);
2794
- }, "handler")
2795
- });
2796
- this.cache.set(key, {
2797
- limiter,
2798
- config: key
2799
- });
2800
- return limiter;
2780
+ /**
2781
+ * @param message - Optional custom message. Defaults to "Internal server error".
2782
+ */
2783
+ constructor(message = "Internal server error") {
2784
+ super(message);
2785
+ this.status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
2801
2786
  }
2802
- clear() {
2803
- this.cache.clear();
2787
+ };
2788
+ var UnauthorizedException = class extends ErrorResponse {
2789
+ static {
2790
+ __name(this, "UnauthorizedException");
2804
2791
  }
2805
- size() {
2806
- return this.cache.size();
2792
+ /**
2793
+ * @param message - Optional custom message. Defaults to "Unauthorized".
2794
+ */
2795
+ constructor(message = "Unauthorized") {
2796
+ super(message);
2797
+ this.status = HttpStatusCodes.UNAUTHORIZED;
2807
2798
  }
2808
- destroy() {
2809
- this.cache.destroy();
2799
+ };
2800
+ var BadRequestException = class extends ErrorResponse {
2801
+ static {
2802
+ __name(this, "BadRequestException");
2803
+ }
2804
+ /**
2805
+ * @param message - Optional custom message. Defaults to "Bad request".
2806
+ */
2807
+ constructor(message = "Bad request") {
2808
+ super(message);
2809
+ this.status = HttpStatusCodes.BAD_REQUEST;
2810
2810
  }
2811
2811
  };
2812
- var rateLimiterCache = new RateLimiterCache();
2813
- var DIContainer = class {
2812
+ var NotFoundException = class extends ErrorResponse {
2814
2813
  static {
2815
- __name(this, "DIContainer");
2814
+ __name(this, "NotFoundException");
2816
2815
  }
2817
- instances = /* @__PURE__ */ new Map();
2818
- constructing = /* @__PURE__ */ new Map();
2819
- register(target) {
2820
- if (!this.instances.has(target) && !this.constructing.has(target)) ;
2816
+ /**
2817
+ * @param message - Optional custom message. Defaults to "Resource not found".
2818
+ */
2819
+ constructor(message = "Resource not found") {
2820
+ super(message);
2821
+ this.status = HttpStatusCodes.NOT_FOUND;
2821
2822
  }
2822
- get(target) {
2823
- if (this.instances.has(target)) {
2824
- return this.instances.get(target);
2825
- }
2826
- if (this.constructing.has(target)) {
2827
- return this.constructing.get(target);
2828
- }
2829
- let proxy = {};
2830
- this.constructing.set(target, proxy);
2831
- const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
2832
- const dependencies = paramTypes.map((dep) => this.get(dep));
2833
- const instance = new target(...dependencies);
2834
- Object.assign(proxy, instance);
2835
- this.instances.set(target, proxy);
2836
- this.constructing.delete(target);
2837
- Object.setPrototypeOf(proxy, target.prototype);
2838
- return proxy;
2823
+ };
2824
+ var ForbiddenException = class extends ErrorResponse {
2825
+ static {
2826
+ __name(this, "ForbiddenException");
2839
2827
  }
2840
- clear() {
2841
- this.instances.clear();
2842
- this.constructing.clear();
2828
+ /**
2829
+ * @param message - Optional custom message. Defaults to "Forbidden".
2830
+ */
2831
+ constructor(message = "Forbidden") {
2832
+ super(message);
2833
+ this.status = HttpStatusCodes.FORBIDDEN;
2843
2834
  }
2844
2835
  };
2845
- var diContainer = new DIContainer();
2846
- function normalizeHeaderValue(value) {
2847
- if (typeof value === "undefined") return void 0;
2848
- if (typeof value === "string") return value;
2849
- if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
2850
- return value;
2836
+ var ConflictException = class extends ErrorResponse {
2837
+ static {
2838
+ __name(this, "ConflictException");
2851
2839
  }
2852
- return String(value);
2853
- }
2854
- __name(normalizeHeaderValue, "normalizeHeaderValue");
2855
- function Injectable() {
2856
- return (target) => {
2857
- Reflect.defineMetadata("injectable", true, target);
2858
- diContainer.register(target);
2859
- };
2860
- }
2861
- __name(Injectable, "Injectable");
2862
- function Inject(targetClass) {
2863
- return (target, propertyKey) => {
2864
- Object.defineProperty(target, propertyKey, {
2865
- get: /* @__PURE__ */ __name(function() {
2866
- return diContainer.get(targetClass);
2867
- }, "get"),
2868
- enumerable: true,
2869
- configurable: true
2870
- });
2871
- };
2872
- }
2873
- __name(Inject, "Inject");
2874
- function createRouteDecorator(method) {
2875
- return (path3) => {
2876
- return (target, propertyKey, _descriptor) => {
2877
- const routes = Reflect.getMetadata(ROUTES_KEY, target.constructor) || [];
2878
- routes.push({
2879
- path: path3,
2880
- method,
2881
- handlerName: propertyKey
2882
- });
2883
- Reflect.defineMetadata(ROUTES_KEY, routes, target.constructor);
2884
- };
2885
- };
2886
- }
2887
- __name(createRouteDecorator, "createRouteDecorator");
2888
- var Get = createRouteDecorator("get");
2889
- var Post = createRouteDecorator("post");
2890
- var Put = createRouteDecorator("put");
2891
- var Patch = createRouteDecorator("patch");
2892
- var Delete = createRouteDecorator("delete");
2893
- var Options = createRouteDecorator("options");
2894
- var Head = createRouteDecorator("head");
2895
- var Trace = createRouteDecorator("trace");
2896
- var Connect = createRouteDecorator("connect");
2897
- function Controller(basePath) {
2898
- return (target) => {
2899
- Reflect.defineMetadata("basePath", basePath, target);
2900
- };
2901
- }
2902
- __name(Controller, "Controller");
2903
- function Use(...middlewares) {
2904
- return (target, propertyKey, _descriptor) => {
2905
- const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target, propertyKey) || [];
2906
- Reflect.defineMetadata(MIDDLEWARE_KEY, [
2907
- ...existing,
2908
- ...middlewares
2909
- ], target, propertyKey);
2910
- };
2911
- }
2912
- __name(Use, "Use");
2913
- function createParamDecorator(type, key) {
2914
- return (paramKey) => {
2915
- return (target, propertyKey, parameterIndex) => {
2916
- const params = Reflect.getMetadata(PARAMS_KEY, target, propertyKey) || [];
2917
- params.push({
2918
- index: parameterIndex,
2919
- type,
2920
- key: paramKey || key
2921
- });
2922
- params.sort((a, b) => a.index - b.index);
2923
- Reflect.defineMetadata(PARAMS_KEY, params, target, propertyKey);
2924
- };
2925
- };
2926
- }
2927
- __name(createParamDecorator, "createParamDecorator");
2928
- var Query = createParamDecorator("query");
2929
- var Param = createParamDecorator("param");
2930
- var Body = createParamDecorator("body");
2931
- var Req = createParamDecorator("req");
2932
- var Res = createParamDecorator("res");
2933
- function HttpCode(status) {
2934
- return (target, propertyKey, _descriptor) => {
2935
- Reflect.defineMetadata(HTTP_CODE_KEY, status, target, propertyKey);
2936
- };
2937
- }
2938
- __name(HttpCode, "HttpCode");
2939
- function Header(name, value) {
2940
- return Headers(name, value);
2941
- }
2942
- __name(Header, "Header");
2943
- function Headers(headers, value) {
2944
- return (target, propertyKey) => {
2945
- if (typeof propertyKey === "undefined") {
2946
- const existing = Reflect.getMetadata(HEADER_KEY, target) || {};
2947
- const newHeaders = typeof headers === "string" ? {
2948
- [headers]: value
2949
- } : headers;
2950
- Reflect.defineMetadata(HEADER_KEY, {
2951
- ...existing,
2952
- ...newHeaders
2953
- }, target);
2954
- } else {
2955
- const existing = Reflect.getMetadata(HEADER_KEY, target, propertyKey) || {};
2956
- const newHeaders = typeof headers === "string" ? {
2957
- [headers]: value
2958
- } : headers;
2959
- Reflect.defineMetadata(HEADER_KEY, {
2960
- ...existing,
2961
- ...newHeaders
2962
- }, target, propertyKey);
2963
- }
2964
- };
2965
- }
2966
- __name(Headers, "Headers");
2967
- function Before(fn) {
2968
- return (target, propertyKey, _descriptor) => {
2969
- const hooks = Reflect.getMetadata(BEFORE_KEY, target, propertyKey) || [];
2970
- hooks.push(fn);
2971
- Reflect.defineMetadata(BEFORE_KEY, hooks, target, propertyKey);
2972
- };
2973
- }
2974
- __name(Before, "Before");
2975
- function After(fn) {
2976
- return (target, propertyKey, _descriptor) => {
2977
- const hooks = Reflect.getMetadata(AFTER_KEY, target, propertyKey) || [];
2978
- hooks.push(fn);
2979
- Reflect.defineMetadata(AFTER_KEY, hooks, target, propertyKey);
2980
- };
2840
+ /**
2841
+ * @param message - Optional custom message. Defaults to "Conflict".
2842
+ */
2843
+ constructor(message = "Conflict") {
2844
+ super(message);
2845
+ this.status = HttpStatusCodes.CONFLICT;
2846
+ }
2847
+ };
2848
+ var BadGatewayException = class extends ErrorResponse {
2849
+ static {
2850
+ __name(this, "BadGatewayException");
2851
+ }
2852
+ /**
2853
+ * @param message - Optional custom message. Defaults to "Bad Gateway".
2854
+ */
2855
+ constructor(message = "Bad Gateway") {
2856
+ super(message);
2857
+ this.status = HttpStatusCodes.BAD_GATEWAY;
2858
+ }
2859
+ };
2860
+ var TooManyRequestsException = class extends ErrorResponse {
2861
+ static {
2862
+ __name(this, "TooManyRequestsException");
2863
+ }
2864
+ /**
2865
+ * @param message - Optional custom message. Defaults to "Too many requests".
2866
+ */
2867
+ constructor(message = "Too many requests") {
2868
+ super(message);
2869
+ this.status = HttpStatusCodes.TOO_MANY_REQUESTS;
2870
+ }
2871
+ };
2872
+ var ServiceUnavailableException = class extends ErrorResponse {
2873
+ static {
2874
+ __name(this, "ServiceUnavailableException");
2875
+ }
2876
+ /**
2877
+ * @param message - Optional custom message. Defaults to "Service Unavailable".
2878
+ */
2879
+ constructor(message = "Service Unavailable") {
2880
+ super(message);
2881
+ this.status = HttpStatusCodes.SERVICE_UNAVAILABLE;
2882
+ }
2883
+ };
2884
+ var GatewayTimeoutException = class extends ErrorResponse {
2885
+ static {
2886
+ __name(this, "GatewayTimeoutException");
2887
+ }
2888
+ /**
2889
+ * @param message - Optional custom message. Defaults to "Gateway Timeout".
2890
+ */
2891
+ constructor(message = "Gateway Timeout") {
2892
+ super(message);
2893
+ this.status = HttpStatusCodes.GATEWAY_TIMEOUT;
2894
+ }
2895
+ };
2896
+ var UnprocessableEntityException = class extends ErrorResponse {
2897
+ static {
2898
+ __name(this, "UnprocessableEntityException");
2899
+ }
2900
+ details;
2901
+ /**
2902
+ * @param message - Optional custom message. Defaults to "Unprocessable Entity".
2903
+ * @param details - Optional validation details or additional error context.
2904
+ */
2905
+ constructor(message = "Unprocessable Entity", details) {
2906
+ super(message), this.details = details;
2907
+ this.status = HttpStatusCodes.UNPROCESSABLE_ENTITY;
2908
+ }
2909
+ };
2910
+ var MethodNotAllowedException = class extends ErrorResponse {
2911
+ static {
2912
+ __name(this, "MethodNotAllowedException");
2913
+ }
2914
+ allowedMethods;
2915
+ /**
2916
+ * @param message - Optional custom message. Defaults to "Method Not Allowed".
2917
+ * @param allowedMethods - Optional array of allowed HTTP methods.
2918
+ */
2919
+ constructor(message = "Method Not Allowed", allowedMethods) {
2920
+ super(message), this.allowedMethods = allowedMethods;
2921
+ this.status = HttpStatusCodes.METHOD_NOT_ALLOWED;
2922
+ }
2923
+ };
2924
+ var NotAcceptableException = class extends ErrorResponse {
2925
+ static {
2926
+ __name(this, "NotAcceptableException");
2927
+ }
2928
+ /**
2929
+ * @param message - Optional custom message. Defaults to "Not Acceptable".
2930
+ */
2931
+ constructor(message = "Not Acceptable") {
2932
+ super(message);
2933
+ this.status = HttpStatusCodes.NOT_ACCEPTABLE;
2934
+ }
2935
+ };
2936
+ var RequestTimeoutException = class extends ErrorResponse {
2937
+ static {
2938
+ __name(this, "RequestTimeoutException");
2939
+ }
2940
+ /**
2941
+ * @param message - Optional custom message. Defaults to "Request Timeout".
2942
+ */
2943
+ constructor(message = "Request Timeout") {
2944
+ super(message);
2945
+ this.status = HttpStatusCodes.REQUEST_TIMEOUT;
2946
+ }
2947
+ };
2948
+ var UnsupportedMediaTypeException = class extends ErrorResponse {
2949
+ static {
2950
+ __name(this, "UnsupportedMediaTypeException");
2951
+ }
2952
+ /**
2953
+ * @param message - Optional custom message. Defaults to "Unsupported Media Type".
2954
+ */
2955
+ constructor(message = "Unsupported Media Type") {
2956
+ super(message);
2957
+ this.status = HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE;
2958
+ }
2959
+ };
2960
+ var PayloadTooLargeException = class extends ErrorResponse {
2961
+ static {
2962
+ __name(this, "PayloadTooLargeException");
2963
+ }
2964
+ /**
2965
+ * @param message - Optional custom message. Defaults to "Payload Too Large".
2966
+ */
2967
+ constructor(message = "Payload Too Large") {
2968
+ super(message);
2969
+ this.status = HttpStatusCodes.PAYLOAD_TOO_LARGE;
2970
+ }
2971
+ };
2972
+ var InsufficientStorageException = class extends ErrorResponse {
2973
+ static {
2974
+ __name(this, "InsufficientStorageException");
2975
+ }
2976
+ /**
2977
+ * @param message - Optional custom message. Defaults to "Insufficient Storage".
2978
+ */
2979
+ constructor(message = "Insufficient Storage") {
2980
+ super(message);
2981
+ this.status = HttpStatusCodes.INSUFFICIENT_STORAGE;
2982
+ }
2983
+ };
2984
+ function isHttpError(error) {
2985
+ return error instanceof ErrorResponse;
2981
2986
  }
2982
- __name(After, "After");
2983
- function Roles(...roles) {
2984
- return (target, propertyKey, _descriptor) => {
2985
- if (typeof propertyKey === "undefined") {
2986
- Reflect.defineMetadata(ROLES_KEY, roles, target);
2987
- } else {
2988
- Reflect.defineMetadata(ROLES_KEY, roles, target, propertyKey);
2989
- }
2990
- };
2987
+ __name(isHttpError, "isHttpError");
2988
+ function createHttpError(status, message) {
2989
+ switch (status) {
2990
+ case HttpStatusCodes.BAD_REQUEST:
2991
+ return new BadRequestException(message);
2992
+ case HttpStatusCodes.UNAUTHORIZED:
2993
+ return new UnauthorizedException(message);
2994
+ case HttpStatusCodes.FORBIDDEN:
2995
+ return new ForbiddenException(message);
2996
+ case HttpStatusCodes.NOT_FOUND:
2997
+ return new NotFoundException(message);
2998
+ case HttpStatusCodes.METHOD_NOT_ALLOWED:
2999
+ return new MethodNotAllowedException(message);
3000
+ case HttpStatusCodes.NOT_ACCEPTABLE:
3001
+ return new NotAcceptableException(message);
3002
+ case HttpStatusCodes.REQUEST_TIMEOUT:
3003
+ return new RequestTimeoutException(message);
3004
+ case HttpStatusCodes.CONFLICT:
3005
+ return new ConflictException(message);
3006
+ case HttpStatusCodes.GONE:
3007
+ return new HttpError(HttpStatusCodes.GONE, message || "Gone");
3008
+ case HttpStatusCodes.PAYLOAD_TOO_LARGE:
3009
+ return new PayloadTooLargeException(message);
3010
+ case HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE:
3011
+ return new UnsupportedMediaTypeException(message);
3012
+ case HttpStatusCodes.UNPROCESSABLE_ENTITY:
3013
+ return new UnprocessableEntityException(message);
3014
+ case HttpStatusCodes.TOO_MANY_REQUESTS:
3015
+ return new TooManyRequestsException(message);
3016
+ case HttpStatusCodes.INTERNAL_SERVER_ERROR:
3017
+ return new InternalServerErrorException(message);
3018
+ case HttpStatusCodes.BAD_GATEWAY:
3019
+ return new BadGatewayException(message);
3020
+ case HttpStatusCodes.SERVICE_UNAVAILABLE:
3021
+ return new ServiceUnavailableException(message);
3022
+ case HttpStatusCodes.GATEWAY_TIMEOUT:
3023
+ return new GatewayTimeoutException(message);
3024
+ case HttpStatusCodes.INSUFFICIENT_STORAGE:
3025
+ return new InsufficientStorageException(message);
3026
+ default:
3027
+ return new HttpError(status, message || `HTTP Error ${status}`);
3028
+ }
2991
3029
  }
2992
- __name(Roles, "Roles");
2993
- function Redirect(url, statusCode = 302) {
2994
- return (target, propertyKey, descriptor) => {
2995
- Reflect.defineMetadata(REDIRECT_KEY, {
2996
- url,
2997
- statusCode
2998
- }, target, propertyKey);
2999
- return descriptor;
3000
- };
3030
+ __name(createHttpError, "createHttpError");
3031
+ function hasErrorShape(error) {
3032
+ return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
3001
3033
  }
3002
- __name(Redirect, "Redirect");
3003
- function Cache(ttlSeconds) {
3004
- return (target, propertyKey, _descriptor) => {
3005
- if (typeof propertyKey === "undefined") {
3006
- Reflect.defineMetadata(CACHE_KEY, {
3007
- ttlSeconds
3008
- }, target);
3009
- } else {
3010
- Reflect.defineMetadata(CACHE_KEY, {
3011
- ttlSeconds
3012
- }, target, propertyKey);
3034
+ __name(hasErrorShape, "hasErrorShape");
3035
+ function getErrorMessage(error) {
3036
+ if (typeof error === "string") {
3037
+ return error;
3038
+ }
3039
+ if (error instanceof Error) {
3040
+ return error.message;
3041
+ }
3042
+ if (hasErrorShape(error)) {
3043
+ return error.message;
3044
+ }
3045
+ return "Unknown error occurred";
3046
+ }
3047
+ __name(getErrorMessage, "getErrorMessage");
3048
+ function withErrorHandling(handler) {
3049
+ return async (...args) => {
3050
+ try {
3051
+ return await handler(...args);
3052
+ } catch (err) {
3053
+ if (isHttpError(err)) {
3054
+ throw err;
3055
+ }
3056
+ getLogger().error({
3057
+ err
3058
+ }, "Caught error in handler");
3059
+ let status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
3060
+ if (hasErrorShape(err) && typeof err.status === "number") {
3061
+ status = err.status;
3062
+ }
3063
+ throw createHttpError(status, getErrorMessage(err));
3013
3064
  }
3014
3065
  };
3015
3066
  }
3016
- __name(Cache, "Cache");
3017
- function RateLimit(options) {
3018
- const opts = {
3019
- standardHeaders: true,
3020
- legacyHeaders: false,
3021
- ...options
3067
+ __name(withErrorHandling, "withErrorHandling");
3068
+
3069
+ // src/utils/decorators.utils.ts
3070
+ var ROUTES_KEY = Symbol("routes");
3071
+ var MIDDLEWARE_KEY = Symbol("middlewares");
3072
+ var PARAMS_KEY = Symbol("params");
3073
+ var HTTP_CODE_KEY = Symbol("httpCode");
3074
+ var HEADER_KEY = Symbol("headers");
3075
+ var BEFORE_KEY = Symbol("before");
3076
+ var AFTER_KEY = Symbol("after");
3077
+ var ROLES_KEY = Symbol("roles");
3078
+ var REDIRECT_KEY = Symbol("redirect");
3079
+ var CACHE_KEY = Symbol("cache");
3080
+ var RATE_LIMIT_KEY = Symbol("rateLimit");
3081
+ var CONTENT_TYPE_KEY = Symbol("contentType");
3082
+ var VERSION_KEY = Symbol("version");
3083
+ var TIMEOUT_KEY = Symbol("timeout");
3084
+ var LOG_KEY = Symbol("log");
3085
+ var RateLimiterCache = class RateLimiterCache2 {
3086
+ static {
3087
+ __name(this, "RateLimiterCache");
3088
+ }
3089
+ cache;
3090
+ constructor(maxSize = 100, ttlMs = 5 * 60 * 1e3) {
3091
+ this.cache = new TTLCache({
3092
+ maxSize,
3093
+ ttlMs
3094
+ });
3095
+ }
3096
+ generateKey(options) {
3097
+ return `${options.max}:${options.windowMs}:${options.standardHeaders}:${options.legacyHeaders}`;
3098
+ }
3099
+ get(options) {
3100
+ const key = this.generateKey(options);
3101
+ const cached = this.cache.get(key);
3102
+ if (cached) {
3103
+ return cached.limiter;
3104
+ }
3105
+ const limiter = expressRateLimit.rateLimit({
3106
+ ...options,
3107
+ handler: /* @__PURE__ */ __name((req, res) => {
3108
+ const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.TOO_MANY_REQUESTS, "Too Many Requests");
3109
+ res.status(HttpStatusCodes.TOO_MANY_REQUESTS).json(errorResponse);
3110
+ }, "handler")
3111
+ });
3112
+ this.cache.set(key, {
3113
+ limiter,
3114
+ config: key
3115
+ });
3116
+ return limiter;
3117
+ }
3118
+ clear() {
3119
+ this.cache.clear();
3120
+ }
3121
+ size() {
3122
+ return this.cache.size();
3123
+ }
3124
+ destroy() {
3125
+ this.cache.destroy();
3126
+ }
3127
+ };
3128
+ var rateLimiterCache = new RateLimiterCache();
3129
+ var DIContainer = class {
3130
+ static {
3131
+ __name(this, "DIContainer");
3132
+ }
3133
+ instances = /* @__PURE__ */ new Map();
3134
+ constructing = /* @__PURE__ */ new Map();
3135
+ propertyInjections = /* @__PURE__ */ new Map();
3136
+ register(target) {
3137
+ if (!this.instances.has(target) && !this.constructing.has(target)) ;
3138
+ }
3139
+ /**
3140
+ * Register a property injection to be resolved when the target class is instantiated
3141
+ */
3142
+ registerPropertyInjection(target, propertyKey, injectClass) {
3143
+ const targetClass = target.constructor;
3144
+ if (!this.propertyInjections.has(targetClass)) {
3145
+ this.propertyInjections.set(targetClass, []);
3146
+ }
3147
+ this.propertyInjections.get(targetClass).push({
3148
+ targetClass: injectClass,
3149
+ propertyKey
3150
+ });
3151
+ }
3152
+ get(target) {
3153
+ if (this.instances.has(target)) {
3154
+ return this.instances.get(target);
3155
+ }
3156
+ if (this.constructing.has(target)) {
3157
+ return this.constructing.get(target);
3158
+ }
3159
+ let proxy = {};
3160
+ this.constructing.set(target, proxy);
3161
+ const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
3162
+ const dependencies = paramTypes.map((dep) => this.get(dep));
3163
+ const instance = new target(...dependencies);
3164
+ this.applyPropertyInjections(target, instance);
3165
+ Object.assign(proxy, instance);
3166
+ this.instances.set(target, proxy);
3167
+ this.constructing.delete(target);
3168
+ Object.setPrototypeOf(proxy, target.prototype);
3169
+ return proxy;
3170
+ }
3171
+ applyPropertyInjections(targetClass, instance) {
3172
+ const injections = this.propertyInjections.get(targetClass) || [];
3173
+ for (const injection of injections) {
3174
+ const dependency = this.get(injection.targetClass);
3175
+ instance[injection.propertyKey] = dependency;
3176
+ }
3177
+ }
3178
+ clear() {
3179
+ this.instances.clear();
3180
+ this.constructing.clear();
3181
+ this.propertyInjections.clear();
3182
+ }
3183
+ };
3184
+ var diContainer = new DIContainer();
3185
+ function normalizeHeaderValue(value) {
3186
+ if (typeof value === "undefined") return void 0;
3187
+ if (typeof value === "string") return value;
3188
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
3189
+ return value;
3190
+ }
3191
+ return String(value);
3192
+ }
3193
+ __name(normalizeHeaderValue, "normalizeHeaderValue");
3194
+ function Injectable() {
3195
+ return (target) => {
3196
+ Reflect.defineMetadata("injectable", true, target);
3197
+ diContainer.register(target);
3198
+ };
3199
+ }
3200
+ __name(Injectable, "Injectable");
3201
+ function Inject(targetClass) {
3202
+ return (target, propertyKey) => {
3203
+ diContainer.registerPropertyInjection(target, propertyKey, targetClass);
3204
+ Object.defineProperty(target, propertyKey, {
3205
+ configurable: true,
3206
+ get: /* @__PURE__ */ __name(function() {
3207
+ const value = Object.getOwnPropertyDescriptor(this, propertyKey)?.value;
3208
+ if (value !== void 0) return value;
3209
+ const injectedValue = diContainer.get(targetClass);
3210
+ Object.defineProperty(this, propertyKey, {
3211
+ value: injectedValue,
3212
+ writable: true,
3213
+ configurable: true
3214
+ });
3215
+ return injectedValue;
3216
+ }, "get"),
3217
+ set: /* @__PURE__ */ __name(function(value) {
3218
+ Object.defineProperty(this, propertyKey, {
3219
+ value,
3220
+ writable: true,
3221
+ configurable: true
3222
+ });
3223
+ }, "set")
3224
+ });
3225
+ };
3226
+ }
3227
+ __name(Inject, "Inject");
3228
+ function inject(targetClass) {
3229
+ return diContainer.get(targetClass);
3230
+ }
3231
+ __name(inject, "inject");
3232
+ function createRouteDecorator(method) {
3233
+ return (path3) => {
3234
+ return (target, propertyKey, _descriptor) => {
3235
+ const routes = Reflect.getMetadata(ROUTES_KEY, target.constructor) || [];
3236
+ routes.push({
3237
+ path: path3,
3238
+ method,
3239
+ handlerName: propertyKey
3240
+ });
3241
+ Reflect.defineMetadata(ROUTES_KEY, routes, target.constructor);
3242
+ };
3022
3243
  };
3244
+ }
3245
+ __name(createRouteDecorator, "createRouteDecorator");
3246
+ var Get = createRouteDecorator("get");
3247
+ var Post = createRouteDecorator("post");
3248
+ var Put = createRouteDecorator("put");
3249
+ var Patch = createRouteDecorator("patch");
3250
+ var Delete = createRouteDecorator("delete");
3251
+ var Options = createRouteDecorator("options");
3252
+ var Head = createRouteDecorator("head");
3253
+ var Trace = createRouteDecorator("trace");
3254
+ var Connect = createRouteDecorator("connect");
3255
+ function Controller(basePath) {
3256
+ return (target) => {
3257
+ Reflect.defineMetadata("basePath", basePath, target);
3258
+ };
3259
+ }
3260
+ __name(Controller, "Controller");
3261
+ function Use(...middlewares) {
3023
3262
  return (target, propertyKey, _descriptor) => {
3024
3263
  if (typeof propertyKey === "undefined") {
3025
- Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target);
3264
+ const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target) || [];
3265
+ Reflect.defineMetadata(MIDDLEWARE_KEY, [
3266
+ ...existing,
3267
+ ...middlewares
3268
+ ], target);
3026
3269
  } else {
3027
- Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target, propertyKey);
3270
+ const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target, propertyKey) || [];
3271
+ Reflect.defineMetadata(MIDDLEWARE_KEY, [
3272
+ ...existing,
3273
+ ...middlewares
3274
+ ], target, propertyKey);
3028
3275
  }
3029
3276
  };
3030
3277
  }
3031
- __name(RateLimit, "RateLimit");
3032
- function ContentType(type) {
3033
- return (target, propertyKey, _descriptor) => {
3034
- Reflect.defineMetadata(CONTENT_TYPE_KEY, {
3035
- type
3036
- }, target, propertyKey);
3278
+ __name(Use, "Use");
3279
+ function defineParamMetadata(target, propertyKey, parameterIndex, type, key) {
3280
+ const params = Reflect.getMetadata(PARAMS_KEY, target, propertyKey) || [];
3281
+ params.push({
3282
+ index: parameterIndex,
3283
+ type,
3284
+ key
3285
+ });
3286
+ params.sort((a, b) => a.index - b.index);
3287
+ Reflect.defineMetadata(PARAMS_KEY, params, target, propertyKey);
3288
+ }
3289
+ __name(defineParamMetadata, "defineParamMetadata");
3290
+ function createParamDecorator(type, key) {
3291
+ return (paramKey) => {
3292
+ return (target, propertyKey, parameterIndex) => {
3293
+ defineParamMetadata(target, propertyKey, parameterIndex, type, paramKey ?? key);
3294
+ };
3037
3295
  };
3038
3296
  }
3039
- __name(ContentType, "ContentType");
3040
- function Version(version, options) {
3041
- const opts = {
3042
- addPrefix: true,
3043
- addHeader: true,
3044
- headerName: "X-API-Version",
3045
- ...options
3297
+ __name(createParamDecorator, "createParamDecorator");
3298
+ function createParamDecoratorWithoutParam(type) {
3299
+ return () => {
3300
+ return (target, propertyKey, parameterIndex) => {
3301
+ defineParamMetadata(target, propertyKey, parameterIndex, type, void 0);
3302
+ };
3303
+ };
3304
+ }
3305
+ __name(createParamDecoratorWithoutParam, "createParamDecoratorWithoutParam");
3306
+ function createApiUrlParamDecorator(type, key) {
3307
+ return (paramKey, options) => {
3308
+ return (target, propertyKey, parameterIndex) => {
3309
+ const params = Reflect.getMetadata(PARAMS_KEY, target, propertyKey) || [];
3310
+ let paramOptions = void 0;
3311
+ if (typeof options === "object") {
3312
+ paramOptions = {};
3313
+ paramOptions.type = "string";
3314
+ paramOptions.dataType = "single";
3315
+ paramOptions.delimiter = ",";
3316
+ paramOptions.required = false;
3317
+ paramOptions.throwError = true;
3318
+ paramOptions = {
3319
+ ...paramOptions,
3320
+ ...options
3321
+ };
3322
+ }
3323
+ params.push({
3324
+ index: parameterIndex,
3325
+ type,
3326
+ key: paramKey || key,
3327
+ options: paramOptions
3328
+ });
3329
+ params.sort((a, b) => a.index - b.index);
3330
+ Reflect.defineMetadata(PARAMS_KEY, params, target, propertyKey);
3331
+ };
3046
3332
  };
3333
+ }
3334
+ __name(createApiUrlParamDecorator, "createApiUrlParamDecorator");
3335
+ var Query = createApiUrlParamDecorator("query");
3336
+ var Param = createApiUrlParamDecorator("param");
3337
+ var Body = createParamDecorator("body");
3338
+ var ReqLogger = createParamDecoratorWithoutParam("logger");
3339
+ var ReqId = createParamDecoratorWithoutParam("reqId");
3340
+ var ReqHeader = createParamDecorator("reqHeader");
3341
+ var ReqCookie = createParamDecorator("cookie");
3342
+ var Req = createParamDecoratorWithoutParam("req");
3343
+ var Res = createParamDecoratorWithoutParam("res");
3344
+ function HttpCode(status) {
3047
3345
  return (target, propertyKey, _descriptor) => {
3346
+ Reflect.defineMetadata(HTTP_CODE_KEY, status, target, propertyKey);
3347
+ };
3348
+ }
3349
+ __name(HttpCode, "HttpCode");
3350
+ function Header(name, value) {
3351
+ return Headers(name, value);
3352
+ }
3353
+ __name(Header, "Header");
3354
+ function Headers(headers, value) {
3355
+ return (target, propertyKey) => {
3048
3356
  if (typeof propertyKey === "undefined") {
3049
- Reflect.defineMetadata(VERSION_KEY, {
3050
- version,
3051
- options: opts
3357
+ const existing = Reflect.getMetadata(HEADER_KEY, target) || {};
3358
+ const newHeaders = typeof headers === "string" ? {
3359
+ [headers]: value
3360
+ } : headers;
3361
+ Reflect.defineMetadata(HEADER_KEY, {
3362
+ ...existing,
3363
+ ...newHeaders
3052
3364
  }, target);
3053
3365
  } else {
3054
- Reflect.defineMetadata(VERSION_KEY, {
3055
- version,
3056
- options: opts
3366
+ const existing = Reflect.getMetadata(HEADER_KEY, target, propertyKey) || {};
3367
+ const newHeaders = typeof headers === "string" ? {
3368
+ [headers]: value
3369
+ } : headers;
3370
+ Reflect.defineMetadata(HEADER_KEY, {
3371
+ ...existing,
3372
+ ...newHeaders
3057
3373
  }, target, propertyKey);
3058
3374
  }
3059
3375
  };
3060
3376
  }
3061
- __name(Version, "Version");
3062
- function Timeout(ms) {
3377
+ __name(Headers, "Headers");
3378
+ function Before(fn) {
3063
3379
  return (target, propertyKey, _descriptor) => {
3064
3380
  if (typeof propertyKey === "undefined") {
3065
- Reflect.defineMetadata(TIMEOUT_KEY, {
3066
- ms
3067
- }, target);
3381
+ const hooks = Reflect.getMetadata(BEFORE_KEY, target) || [];
3382
+ hooks.push(fn);
3383
+ Reflect.defineMetadata(BEFORE_KEY, hooks, target);
3068
3384
  } else {
3069
- Reflect.defineMetadata(TIMEOUT_KEY, {
3070
- ms
3071
- }, target, propertyKey);
3385
+ const hooks = Reflect.getMetadata(BEFORE_KEY, target, propertyKey) || [];
3386
+ hooks.push(fn);
3387
+ Reflect.defineMetadata(BEFORE_KEY, hooks, target, propertyKey);
3072
3388
  }
3073
3389
  };
3074
3390
  }
3075
- __name(Timeout, "Timeout");
3076
- function Log(options) {
3391
+ __name(Before, "Before");
3392
+ function After(fn) {
3077
3393
  return (target, propertyKey, _descriptor) => {
3078
- const config2 = {
3079
- logEntry: true,
3080
- logExit: true,
3081
- logBody: false,
3082
- logParams: false,
3083
- logResponse: false,
3084
- ...options
3085
- };
3394
+ if (typeof propertyKey === "undefined") {
3395
+ const hooks = Reflect.getMetadata(AFTER_KEY, target) || [];
3396
+ hooks.push(fn);
3397
+ Reflect.defineMetadata(AFTER_KEY, hooks, target);
3398
+ } else {
3399
+ const hooks = Reflect.getMetadata(AFTER_KEY, target, propertyKey) || [];
3400
+ hooks.push(fn);
3401
+ Reflect.defineMetadata(AFTER_KEY, hooks, target, propertyKey);
3402
+ }
3403
+ };
3404
+ }
3405
+ __name(After, "After");
3406
+ function Roles(...roles) {
3407
+ return (target, propertyKey, _descriptor) => {
3408
+ if (typeof propertyKey === "undefined") {
3409
+ Reflect.defineMetadata(ROLES_KEY, roles, target);
3410
+ } else {
3411
+ Reflect.defineMetadata(ROLES_KEY, roles, target, propertyKey);
3412
+ }
3413
+ };
3414
+ }
3415
+ __name(Roles, "Roles");
3416
+ function Redirect(url, statusCode = 302) {
3417
+ return (target, propertyKey, descriptor) => {
3418
+ Reflect.defineMetadata(REDIRECT_KEY, {
3419
+ url,
3420
+ statusCode
3421
+ }, target, propertyKey);
3422
+ return descriptor;
3423
+ };
3424
+ }
3425
+ __name(Redirect, "Redirect");
3426
+ function Cache(ttlSeconds) {
3427
+ return (target, propertyKey, _descriptor) => {
3428
+ if (typeof propertyKey === "undefined") {
3429
+ Reflect.defineMetadata(CACHE_KEY, {
3430
+ ttlSeconds
3431
+ }, target);
3432
+ } else {
3433
+ Reflect.defineMetadata(CACHE_KEY, {
3434
+ ttlSeconds
3435
+ }, target, propertyKey);
3436
+ }
3437
+ };
3438
+ }
3439
+ __name(Cache, "Cache");
3440
+ function RateLimit(options) {
3441
+ const opts = {
3442
+ standardHeaders: true,
3443
+ legacyHeaders: false,
3444
+ ...options
3445
+ };
3446
+ return (target, propertyKey, _descriptor) => {
3447
+ if (typeof propertyKey === "undefined") {
3448
+ Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target);
3449
+ } else {
3450
+ Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target, propertyKey);
3451
+ }
3452
+ };
3453
+ }
3454
+ __name(RateLimit, "RateLimit");
3455
+ function ContentType(type) {
3456
+ return (target, propertyKey, _descriptor) => {
3457
+ if (typeof propertyKey === "undefined") {
3458
+ Reflect.defineMetadata(CONTENT_TYPE_KEY, {
3459
+ type
3460
+ }, target);
3461
+ } else {
3462
+ Reflect.defineMetadata(CONTENT_TYPE_KEY, {
3463
+ type
3464
+ }, target, propertyKey);
3465
+ }
3466
+ };
3467
+ }
3468
+ __name(ContentType, "ContentType");
3469
+ function Version(version, options) {
3470
+ const opts = {
3471
+ addPrefix: true,
3472
+ addHeader: true,
3473
+ headerName: "X-API-Version",
3474
+ ...options
3475
+ };
3476
+ return (target, propertyKey, _descriptor) => {
3477
+ if (typeof propertyKey === "undefined") {
3478
+ Reflect.defineMetadata(VERSION_KEY, {
3479
+ version,
3480
+ options: opts
3481
+ }, target);
3482
+ } else {
3483
+ Reflect.defineMetadata(VERSION_KEY, {
3484
+ version,
3485
+ options: opts
3486
+ }, target, propertyKey);
3487
+ }
3488
+ };
3489
+ }
3490
+ __name(Version, "Version");
3491
+ function Timeout(ms) {
3492
+ return (target, propertyKey, _descriptor) => {
3493
+ if (typeof propertyKey === "undefined") {
3494
+ Reflect.defineMetadata(TIMEOUT_KEY, {
3495
+ ms
3496
+ }, target);
3497
+ } else {
3498
+ Reflect.defineMetadata(TIMEOUT_KEY, {
3499
+ ms
3500
+ }, target, propertyKey);
3501
+ }
3502
+ };
3503
+ }
3504
+ __name(Timeout, "Timeout");
3505
+ function Log(options) {
3506
+ return (target, propertyKey, _descriptor) => {
3507
+ const config2 = {
3508
+ logEntry: true,
3509
+ logExit: true,
3510
+ logBody: false,
3511
+ logParams: false,
3512
+ logResponse: false,
3513
+ ...options
3514
+ };
3086
3515
  if (typeof propertyKey === "undefined") {
3087
3516
  Reflect.defineMetadata(LOG_KEY, config2, target);
3088
3517
  } else {
@@ -3093,6 +3522,10 @@ function Log(options) {
3093
3522
  __name(Log, "Log");
3094
3523
  function registerControllers(router, controllers) {
3095
3524
  controllers.forEach((ControllerClass) => {
3525
+ if (!Reflect.getMetadata("injectable", ControllerClass)) {
3526
+ Reflect.defineMetadata("injectable", true, ControllerClass);
3527
+ diContainer.register(ControllerClass);
3528
+ }
3096
3529
  const instance = diContainer.get(ControllerClass);
3097
3530
  const basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
3098
3531
  const routes = Reflect.getMetadata(ROUTES_KEY, ControllerClass) || [];
@@ -3103,8 +3536,12 @@ function registerControllers(router, controllers) {
3103
3536
  const controllerRoles = Reflect.getMetadata(ROLES_KEY, ControllerClass);
3104
3537
  const controllerLogConfig = Reflect.getMetadata(LOG_KEY, ControllerClass);
3105
3538
  const controllerHeaders = Reflect.getMetadata(HEADER_KEY, ControllerClass) || {};
3539
+ const controllerMiddlewares = Reflect.getMetadata(MIDDLEWARE_KEY, ControllerClass) || [];
3540
+ const controllerBeforeHooks = Reflect.getMetadata(BEFORE_KEY, ControllerClass) || [];
3541
+ const controllerAfterHooks = Reflect.getMetadata(AFTER_KEY, ControllerClass) || [];
3542
+ const controllerContentType = Reflect.getMetadata(CONTENT_TYPE_KEY, ControllerClass);
3106
3543
  routes.forEach(({ path: path3, method, handlerName }) => {
3107
- const middlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
3544
+ const methodMiddlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
3108
3545
  const params = Reflect.getMetadata(PARAMS_KEY, instance, handlerName) || [];
3109
3546
  const httpCode = Reflect.getMetadata(HTTP_CODE_KEY, instance, handlerName);
3110
3547
  const methodHeaders = Reflect.getMetadata(HEADER_KEY, instance, handlerName) || {};
@@ -3112,10 +3549,23 @@ function registerControllers(router, controllers) {
3112
3549
  ...controllerHeaders,
3113
3550
  ...methodHeaders
3114
3551
  };
3115
- const beforeHooks = Reflect.getMetadata(BEFORE_KEY, instance, handlerName) || [];
3116
- const afterHooks = Reflect.getMetadata(AFTER_KEY, instance, handlerName) || [];
3552
+ const middlewares = [
3553
+ ...controllerMiddlewares,
3554
+ ...methodMiddlewares
3555
+ ];
3556
+ const methodBeforeHooks = Reflect.getMetadata(BEFORE_KEY, instance, handlerName) || [];
3557
+ const methodAfterHooks = Reflect.getMetadata(AFTER_KEY, instance, handlerName) || [];
3558
+ const beforeHooks = [
3559
+ ...controllerBeforeHooks,
3560
+ ...methodBeforeHooks
3561
+ ];
3562
+ const afterHooks = [
3563
+ ...methodAfterHooks,
3564
+ ...controllerAfterHooks
3565
+ ];
3117
3566
  const redirect = Reflect.getMetadata(REDIRECT_KEY, instance, handlerName);
3118
- const contentType = Reflect.getMetadata(CONTENT_TYPE_KEY, instance, handlerName);
3567
+ const methodContentType = Reflect.getMetadata(CONTENT_TYPE_KEY, instance, handlerName);
3568
+ const contentType = methodContentType || controllerContentType;
3119
3569
  const roles = Reflect.getMetadata(ROLES_KEY, instance, handlerName) || controllerRoles || [];
3120
3570
  const cache = Reflect.getMetadata(CACHE_KEY, instance, handlerName) || controllerCache;
3121
3571
  const rateLimitOptions = Reflect.getMetadata(RATE_LIMIT_KEY, instance, handlerName) || controllerRateLimit;
@@ -3203,13 +3653,16 @@ function registerControllers(router, controllers) {
3203
3653
  for (const fn of beforeHooks) await fn(req, res);
3204
3654
  const args = [];
3205
3655
  if (params.length) {
3206
- params.forEach(({ index, type, key }) => {
3656
+ params.forEach(({ index, type, key, options }) => {
3657
+ let rawValue;
3207
3658
  switch (type) {
3208
3659
  case "query":
3209
- args[index] = key ? req.query[key] : req.query;
3660
+ rawValue = key ? req.query[key] : req.query;
3661
+ args[index] = options ? applyParamOptions(rawValue, options, key) : rawValue;
3210
3662
  break;
3211
3663
  case "param":
3212
- args[index] = key ? req.params[key] : req.params;
3664
+ rawValue = key ? req.params[key] : req.params;
3665
+ args[index] = options ? applyParamOptions(rawValue, options, key) : rawValue;
3213
3666
  break;
3214
3667
  case "body":
3215
3668
  args[index] = key ? req.body?.[key] : req.body;
@@ -3220,6 +3673,18 @@ function registerControllers(router, controllers) {
3220
3673
  case "res":
3221
3674
  args[index] = res;
3222
3675
  break;
3676
+ case "logger":
3677
+ args[index] = getLogger();
3678
+ break;
3679
+ case "reqHeader":
3680
+ args[index] = key ? req.headers[key.toLowerCase()] : req.headers;
3681
+ break;
3682
+ case "reqId":
3683
+ args[index] = req.headers["x-request-id"] || req?.id || void 0;
3684
+ break;
3685
+ case "cookie":
3686
+ args[index] = key ? req.cookies?.[key] : req.cookies;
3687
+ break;
3223
3688
  }
3224
3689
  });
3225
3690
  }
@@ -3264,675 +3729,524 @@ function registerControllers(router, controllers) {
3264
3729
  }
3265
3730
  next(err);
3266
3731
  }
3267
- }, "handler");
3268
- router[method](basePath + finalPath, ...middlewares, handler);
3269
- });
3270
- });
3271
- }
3272
- __name(registerControllers, "registerControllers");
3273
- async function ensureDir(dirPath) {
3274
- await fsp__default.default.mkdir(dirPath, {
3275
- recursive: true
3276
- });
3277
- }
3278
- __name(ensureDir, "ensureDir");
3279
- async function listFiles(dirPath, recursive = false) {
3280
- const entries = await fsp__default.default.readdir(dirPath, {
3281
- withFileTypes: true
3282
- });
3283
- const files = [];
3284
- for (const entry of entries) {
3285
- const fullPath = path__default.default.join(dirPath, entry.name);
3286
- if (entry.isFile()) {
3287
- files.push(fullPath);
3288
- } else if (recursive && entry.isDirectory()) {
3289
- const nestedFiles = await listFiles(fullPath, true);
3290
- files.push(...nestedFiles);
3291
- }
3292
- }
3293
- return files;
3294
- }
3295
- __name(listFiles, "listFiles");
3296
- async function deleteDirRecursive(dirPath) {
3297
- await fsp__default.default.rm(dirPath, {
3298
- recursive: true,
3299
- force: true
3300
- });
3301
- }
3302
- __name(deleteDirRecursive, "deleteDirRecursive");
3303
- async function isDirectory(pathStr) {
3304
- try {
3305
- const stat = await fsp__default.default.stat(pathStr);
3306
- return stat.isDirectory();
3307
- } catch {
3308
- return false;
3309
- }
3310
- }
3311
- __name(isDirectory, "isDirectory");
3312
- async function copyDir(src, dest) {
3313
- await ensureDir(dest);
3314
- const entries = await fsp__default.default.readdir(src, {
3315
- withFileTypes: true
3316
- });
3317
- for (const entry of entries) {
3318
- const srcPath = path__default.default.join(src, entry.name);
3319
- const destPath = path__default.default.join(dest, entry.name);
3320
- if (entry.isDirectory()) {
3321
- await copyDir(srcPath, destPath);
3322
- } else {
3323
- await fsp__default.default.copyFile(srcPath, destPath);
3324
- }
3325
- }
3326
- }
3327
- __name(copyDir, "copyDir");
3328
- async function moveDir(src, dest) {
3329
- await copyDir(src, dest);
3330
- await deleteDirRecursive(src);
3331
- }
3332
- __name(moveDir, "moveDir");
3333
- async function emptyDir(dirPath) {
3334
- const entries = await fsp__default.default.readdir(dirPath, {
3335
- withFileTypes: true
3336
- });
3337
- for (const entry of entries) {
3338
- const entryPath = path__default.default.join(dirPath, entry.name);
3339
- if (entry.isDirectory()) {
3340
- await fsp__default.default.rm(entryPath, {
3341
- recursive: true,
3342
- force: true
3343
- });
3344
- } else {
3345
- await fsp__default.default.unlink(entryPath);
3346
- }
3347
- }
3348
- }
3349
- __name(emptyDir, "emptyDir");
3350
- async function getDirSize(dirPath) {
3351
- let total = 0;
3352
- const entries = await fsp__default.default.readdir(dirPath, {
3353
- withFileTypes: true
3354
- });
3355
- for (const entry of entries) {
3356
- const entryPath = path__default.default.join(dirPath, entry.name);
3357
- if (entry.isDirectory()) {
3358
- total += await getDirSize(entryPath);
3359
- } else {
3360
- const stat = await fsp__default.default.stat(entryPath);
3361
- total += stat.size;
3362
- }
3363
- }
3364
- return total;
3365
- }
3366
- __name(getDirSize, "getDirSize");
3367
- function watchDir(dirPath, callback) {
3368
- const watcher = fs__default.default.watch(dirPath, (eventType, filename) => {
3369
- callback(eventType, filename);
3370
- });
3371
- return () => watcher.close();
3372
- }
3373
- __name(watchDir, "watchDir");
3374
- async function findFilesByPattern(pattern, options = {}) {
3375
- const matchPattern = /* @__PURE__ */ __name((name, pattern2) => {
3376
- let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, "\\$&");
3377
- escaped = escaped.replaceAll("*", ".*").replaceAll("?", ".");
3378
- const regex = new RegExp(`^${escaped}$`);
3379
- return regex.test(name);
3380
- }, "matchPattern");
3381
- const { cwd = process.cwd(), dot = false } = options;
3382
- const segments = pattern.split("/");
3383
- async function walk(dir, segIndex) {
3384
- if (segIndex >= segments.length) return [];
3385
- const segment = segments[segIndex];
3386
- const entries = await fs__default.default.promises.readdir(dir, {
3387
- withFileTypes: true
3388
- });
3389
- let matchedFiles = [];
3390
- for (const entry of entries) {
3391
- const entryName = entry.name;
3392
- if (!dot && entryName.startsWith(".")) continue;
3393
- const fullPath = path__default.default.join(dir, entryName);
3394
- const isLastSegment = segIndex === segments.length - 1;
3395
- if (isLastSegment) {
3396
- if (matchPattern(entryName, segment) && entry.isFile()) {
3397
- matchedFiles.push(fullPath);
3398
- }
3399
- } else if (entry.isDirectory()) {
3400
- if (matchPattern(entryName, segment)) {
3401
- matchedFiles.push(...await walk(fullPath, segIndex + 1));
3402
- }
3403
- }
3404
- }
3405
- return matchedFiles;
3406
- }
3407
- __name(walk, "walk");
3408
- return walk(cwd, 0);
3409
- }
3410
- __name(findFilesByPattern, "findFilesByPattern");
3411
- async function getSubdirectories(dirPath, recursive = false) {
3412
- const entries = await fsp__default.default.readdir(dirPath, {
3413
- withFileTypes: true
3414
- });
3415
- const dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => path__default.default.join(dirPath, entry.name));
3416
- if (recursive && dirs.length > 0) {
3417
- const nestedDirs = await Promise.all(dirs.map((dir) => getSubdirectories(dir, true)));
3418
- return [
3419
- ...dirs,
3420
- ...nestedDirs.flat()
3421
- ];
3422
- }
3423
- return dirs;
3424
- }
3425
- __name(getSubdirectories, "getSubdirectories");
3426
- async function ensureEmptyDir(dirPath) {
3427
- if (await isDirectory(dirPath)) {
3428
- await emptyDir(dirPath);
3429
- } else {
3430
- try {
3431
- await fsp__default.default.unlink(dirPath);
3432
- } catch (error) {
3433
- if (error.code !== "ENOENT") {
3434
- throw error;
3435
- }
3436
- }
3437
- await ensureDir(dirPath);
3438
- }
3439
- }
3440
- __name(ensureEmptyDir, "ensureEmptyDir");
3441
- async function createTempDir(options = {}) {
3442
- const prefix = options.prefix || "tmp-";
3443
- const parentDir = options.parentDir || os__default.default.tmpdir();
3444
- const dirName = `${prefix}${crypto.randomBytes(6).toString("hex")}`;
3445
- const tempDirPath = path__default.default.join(parentDir, dirName);
3446
- await ensureDir(tempDirPath);
3447
- const cleanup = /* @__PURE__ */ __name(async () => {
3448
- try {
3449
- await deleteDirRecursive(tempDirPath);
3450
- } catch {
3451
- }
3452
- }, "cleanup");
3453
- if (options.cleanup) {
3454
- process.once("exit", () => {
3455
- try {
3456
- fs__default.default.rmSync(tempDirPath, {
3457
- recursive: true,
3458
- force: true
3459
- });
3460
- } catch {
3461
- }
3462
- });
3463
- const signals = [
3464
- "SIGINT",
3465
- "SIGTERM",
3466
- "SIGUSR1",
3467
- "SIGUSR2"
3468
- ];
3469
- for (const signal of signals) {
3470
- process.once(signal, () => {
3471
- cleanup().then(() => process.exit());
3472
- });
3473
- }
3474
- }
3475
- return {
3476
- path: tempDirPath,
3477
- cleanup
3478
- };
3479
- }
3480
- __name(createTempDir, "createTempDir");
3481
- async function findNewestFile(dirPath, recursive = false) {
3482
- const files = await listFiles(dirPath, recursive);
3483
- if (files.length === 0) return null;
3484
- const stats = await Promise.all(files.map(async (file) => ({
3485
- path: file,
3486
- mtime: (await fsp__default.default.stat(file)).mtime
3487
- })));
3488
- return stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0].path;
3489
- }
3490
- __name(findNewestFile, "findNewestFile");
3491
- async function findOldestFile(dirPath, recursive = false) {
3492
- const files = await listFiles(dirPath, recursive);
3493
- if (files.length === 0) return null;
3494
- const stats = await Promise.all(files.map(async (file) => ({
3495
- path: file,
3496
- mtime: (await fsp__default.default.stat(file)).mtime
3497
- })));
3498
- return stats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime())[0].path;
3499
- }
3500
- __name(findOldestFile, "findOldestFile");
3501
- async function findInDir(dirPath, predicate, recursive = false) {
3502
- const entries = await fsp__default.default.readdir(dirPath, {
3503
- withFileTypes: true
3504
- });
3505
- const results = [];
3506
- for (const entry of entries) {
3507
- const entryPath = path__default.default.join(dirPath, entry.name);
3508
- const stat = await fsp__default.default.stat(entryPath);
3509
- if (await predicate(entryPath, stat)) {
3510
- results.push(entryPath);
3511
- }
3512
- if (recursive && entry.isDirectory()) {
3513
- const nestedResults = await findInDir(entryPath, predicate, true);
3514
- results.push(...nestedResults);
3515
- }
3516
- }
3517
- return results;
3518
- }
3519
- __name(findInDir, "findInDir");
3520
- async function watchDirRecursive(dirPath, callback, includeSubdirs = true) {
3521
- const normalizedBasePath = path__default.default.normalize(dirPath);
3522
- const watchers = [];
3523
- const addWatcher = /* @__PURE__ */ __name((dir) => {
3524
- try {
3525
- const watcher = fs__default.default.watch(dir, (eventType, filename) => {
3526
- if (!filename) return;
3527
- const fullPath = path__default.default.join(dir, filename);
3528
- const relativePath = path__default.default.relative(normalizedBasePath, fullPath);
3529
- callback(eventType, relativePath);
3530
- if (eventType === "rename" && includeSubdirs) {
3531
- setTimeout(async () => {
3532
- try {
3533
- if (await isDirectory(fullPath)) {
3534
- addWatcher(fullPath);
3535
- }
3536
- } catch {
3537
- }
3538
- }, 100);
3539
- }
3540
- });
3541
- watchers.push(watcher);
3542
- } catch {
3543
- }
3544
- }, "addWatcher");
3545
- addWatcher(normalizedBasePath);
3546
- if (includeSubdirs) {
3547
- const subdirs = await getSubdirectories(normalizedBasePath, true);
3548
- for (const subdir of subdirs) {
3549
- addWatcher(subdir);
3550
- }
3551
- }
3552
- return () => {
3553
- for (const watcher of watchers) {
3554
- watcher.close();
3555
- }
3556
- };
3557
- }
3558
- __name(watchDirRecursive, "watchDirRecursive");
3559
- async function getDirStats(dirPath) {
3560
- let fileCount = 0;
3561
- let dirCount = 0;
3562
- let totalSize = 0;
3563
- async function processDir(currentPath) {
3564
- const entries = await fsp__default.default.readdir(currentPath, {
3565
- withFileTypes: true
3566
- });
3567
- for (const entry of entries) {
3568
- const entryPath = path__default.default.join(currentPath, entry.name);
3569
- if (entry.isDirectory()) {
3570
- dirCount++;
3571
- await processDir(entryPath);
3572
- } else if (entry.isFile()) {
3573
- fileCount++;
3574
- const stat = await fsp__default.default.stat(entryPath);
3575
- totalSize += stat.size;
3576
- }
3577
- }
3578
- }
3579
- __name(processDir, "processDir");
3580
- await processDir(dirPath);
3581
- return {
3582
- fileCount,
3583
- dirCount,
3584
- totalSize
3585
- };
3586
- }
3587
- __name(getDirStats, "getDirStats");
3588
- async function walkDir(dirPath, options) {
3589
- const traversalOrder = options.traversalOrder || "pre";
3590
- const entries = await fsp__default.default.readdir(dirPath, {
3591
- withFileTypes: true
3592
- });
3593
- for (const entry of entries) {
3594
- const entryPath = path__default.default.join(dirPath, entry.name);
3595
- const stats = await fsp__default.default.stat(entryPath);
3596
- const entryInfo = {
3597
- path: entryPath,
3598
- name: entry.name,
3599
- isDirectory: entry.isDirectory(),
3600
- stats
3601
- };
3602
- if (entry.isDirectory()) {
3603
- if (traversalOrder === "pre") {
3604
- const shouldContinue = await options.visitorFn(entryInfo);
3605
- if (shouldContinue !== false) {
3606
- await walkDir(entryPath, options);
3607
- }
3608
- } else {
3609
- await walkDir(entryPath, options);
3610
- await options.visitorFn(entryInfo);
3611
- }
3612
- } else {
3613
- await options.visitorFn(entryInfo);
3614
- }
3615
- }
3616
- if (traversalOrder === "post") {
3617
- const stats = await fsp__default.default.stat(dirPath);
3618
- const entryInfo = {
3619
- path: dirPath,
3620
- name: path__default.default.basename(dirPath),
3621
- isDirectory: true,
3622
- stats
3623
- };
3624
- await options.visitorFn(entryInfo);
3625
- }
3626
- }
3627
- __name(walkDir, "walkDir");
3628
-
3629
- // src/utils/exception.utils.ts
3630
- var HttpError = class extends ErrorResponse {
3631
- static {
3632
- __name(this, "HttpError");
3633
- }
3634
- /**
3635
- * Creates a new HTTP error instance.
3636
- * @param status - A valid HTTP status code (e.g., 400, 500).
3637
- * @param message - The error message to return to the client.
3638
- */
3639
- constructor(status, message) {
3640
- super(message);
3641
- this.status = status;
3642
- }
3643
- };
3644
- var InternalServerErrorException = class extends ErrorResponse {
3645
- static {
3646
- __name(this, "InternalServerErrorException");
3647
- }
3648
- /**
3649
- * @param message - Optional custom message. Defaults to "Internal server error".
3650
- */
3651
- constructor(message = "Internal server error") {
3652
- super(message);
3653
- this.status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
3654
- }
3655
- };
3656
- var UnauthorizedException = class extends ErrorResponse {
3657
- static {
3658
- __name(this, "UnauthorizedException");
3659
- }
3660
- /**
3661
- * @param message - Optional custom message. Defaults to "Unauthorized".
3662
- */
3663
- constructor(message = "Unauthorized") {
3664
- super(message);
3665
- this.status = HttpStatusCodes.UNAUTHORIZED;
3666
- }
3667
- };
3668
- var BadRequestException = class extends ErrorResponse {
3669
- static {
3670
- __name(this, "BadRequestException");
3671
- }
3672
- /**
3673
- * @param message - Optional custom message. Defaults to "Bad request".
3674
- */
3675
- constructor(message = "Bad request") {
3676
- super(message);
3677
- this.status = HttpStatusCodes.BAD_REQUEST;
3678
- }
3679
- };
3680
- var NotFoundException = class extends ErrorResponse {
3681
- static {
3682
- __name(this, "NotFoundException");
3683
- }
3684
- /**
3685
- * @param message - Optional custom message. Defaults to "Resource not found".
3686
- */
3687
- constructor(message = "Resource not found") {
3688
- super(message);
3689
- this.status = HttpStatusCodes.NOT_FOUND;
3690
- }
3691
- };
3692
- var ForbiddenException = class extends ErrorResponse {
3693
- static {
3694
- __name(this, "ForbiddenException");
3695
- }
3696
- /**
3697
- * @param message - Optional custom message. Defaults to "Forbidden".
3698
- */
3699
- constructor(message = "Forbidden") {
3700
- super(message);
3701
- this.status = HttpStatusCodes.FORBIDDEN;
3702
- }
3703
- };
3704
- var ConflictException = class extends ErrorResponse {
3705
- static {
3706
- __name(this, "ConflictException");
3707
- }
3708
- /**
3709
- * @param message - Optional custom message. Defaults to "Conflict".
3710
- */
3711
- constructor(message = "Conflict") {
3712
- super(message);
3713
- this.status = HttpStatusCodes.CONFLICT;
3714
- }
3715
- };
3716
- var BadGatewayException = class extends ErrorResponse {
3717
- static {
3718
- __name(this, "BadGatewayException");
3719
- }
3720
- /**
3721
- * @param message - Optional custom message. Defaults to "Bad Gateway".
3722
- */
3723
- constructor(message = "Bad Gateway") {
3724
- super(message);
3725
- this.status = HttpStatusCodes.BAD_GATEWAY;
3726
- }
3727
- };
3728
- var TooManyRequestsException = class extends ErrorResponse {
3729
- static {
3730
- __name(this, "TooManyRequestsException");
3731
- }
3732
- /**
3733
- * @param message - Optional custom message. Defaults to "Too many requests".
3734
- */
3735
- constructor(message = "Too many requests") {
3736
- super(message);
3737
- this.status = HttpStatusCodes.TOO_MANY_REQUESTS;
3738
- }
3739
- };
3740
- var ServiceUnavailableException = class extends ErrorResponse {
3741
- static {
3742
- __name(this, "ServiceUnavailableException");
3743
- }
3744
- /**
3745
- * @param message - Optional custom message. Defaults to "Service Unavailable".
3746
- */
3747
- constructor(message = "Service Unavailable") {
3748
- super(message);
3749
- this.status = HttpStatusCodes.SERVICE_UNAVAILABLE;
3750
- }
3751
- };
3752
- var GatewayTimeoutException = class extends ErrorResponse {
3753
- static {
3754
- __name(this, "GatewayTimeoutException");
3755
- }
3756
- /**
3757
- * @param message - Optional custom message. Defaults to "Gateway Timeout".
3758
- */
3759
- constructor(message = "Gateway Timeout") {
3760
- super(message);
3761
- this.status = HttpStatusCodes.GATEWAY_TIMEOUT;
3762
- }
3763
- };
3764
- var UnprocessableEntityException = class extends ErrorResponse {
3765
- static {
3766
- __name(this, "UnprocessableEntityException");
3767
- }
3768
- details;
3769
- /**
3770
- * @param message - Optional custom message. Defaults to "Unprocessable Entity".
3771
- * @param details - Optional validation details or additional error context.
3772
- */
3773
- constructor(message = "Unprocessable Entity", details) {
3774
- super(message), this.details = details;
3775
- this.status = HttpStatusCodes.UNPROCESSABLE_ENTITY;
3776
- }
3777
- };
3778
- var MethodNotAllowedException = class extends ErrorResponse {
3779
- static {
3780
- __name(this, "MethodNotAllowedException");
3781
- }
3782
- allowedMethods;
3783
- /**
3784
- * @param message - Optional custom message. Defaults to "Method Not Allowed".
3785
- * @param allowedMethods - Optional array of allowed HTTP methods.
3786
- */
3787
- constructor(message = "Method Not Allowed", allowedMethods) {
3788
- super(message), this.allowedMethods = allowedMethods;
3789
- this.status = HttpStatusCodes.METHOD_NOT_ALLOWED;
3732
+ }, "handler");
3733
+ router[method](basePath + finalPath, ...middlewares, handler);
3734
+ });
3735
+ });
3736
+ }
3737
+ __name(registerControllers, "registerControllers");
3738
+ function applyParamOptions(rawValue, options, key) {
3739
+ if (!options) return rawValue;
3740
+ let value = rawValue;
3741
+ const paramName = key ? `: ${key}` : "";
3742
+ if (value === void 0 || value === null || value === "") {
3743
+ if ("default" in options) {
3744
+ value = options.default;
3745
+ }
3746
+ }
3747
+ if (options.required && (value === void 0 || value === null || value === "")) {
3748
+ throw new BadRequestException(`Required parameter missing${paramName}`);
3749
+ }
3750
+ if (value !== void 0 && value !== null) {
3751
+ if (options.dataType === "array") {
3752
+ const delimiter = options.delimiter || ",";
3753
+ if (typeof value === "string") {
3754
+ value = value.split(delimiter).map((v) => v.trim());
3755
+ } else if (!Array.isArray(value)) {
3756
+ value = [
3757
+ value
3758
+ ];
3759
+ }
3760
+ if (options.type === "string" && options.pattern) {
3761
+ const hasInvalidPattern = value.some((v) => !options.pattern.test(v));
3762
+ if (hasInvalidPattern) {
3763
+ throw new BadRequestException(`Parameter '${key}' array contains values that do not match pattern: ${options.patternName || options.pattern}`);
3764
+ }
3765
+ }
3766
+ if (options.type === "number" && options.pattern) {
3767
+ const hasInvalidPattern = value.some((v) => !options.pattern.test(String(v)));
3768
+ if (hasInvalidPattern) {
3769
+ throw new BadRequestException(`Parameter '${key}' array contains values that do not match pattern: ${options.patternName || options.pattern}`);
3770
+ }
3771
+ }
3772
+ if (options.type === "number" && options.throwError !== false) {
3773
+ const hasInvalidNumber = value.some((v) => isNaN(Number(v)));
3774
+ if (hasInvalidNumber) {
3775
+ throw new BadRequestException(`Type error: expected number array${paramName}`);
3776
+ }
3777
+ if (options.min !== void 0) {
3778
+ const hasBelowMin = value.some((v) => Number(v) < options.min);
3779
+ if (hasBelowMin) {
3780
+ throw new BadRequestException(`Validation error: number array values must be >= ${options.min}${paramName}`);
3781
+ }
3782
+ }
3783
+ if (options.max !== void 0) {
3784
+ const hasAboveMax = value.some((v) => Number(v) > options.max);
3785
+ if (hasAboveMax) {
3786
+ throw new BadRequestException(`Validation error: number array values must be <= ${options.max}${paramName}`);
3787
+ }
3788
+ }
3789
+ }
3790
+ if (options.type === "boolean" && options.throwError !== false) {
3791
+ const hasInvalidBoolean = value.some((v) => !isValidBooleanInput(v));
3792
+ if (hasInvalidBoolean) {
3793
+ throw new BadRequestException(`Type error: expected boolean array${paramName}`);
3794
+ }
3795
+ }
3796
+ if (options.type) {
3797
+ value = value.map((v) => convertType(v, options.type || "string"));
3798
+ }
3799
+ } else if (options.dataType === "object") {
3800
+ if (typeof value === "string") {
3801
+ try {
3802
+ value = JSON.parse(value);
3803
+ } catch (_e) {
3804
+ if (options.throwError !== false) {
3805
+ throw new BadRequestException(`Invalid JSON object${paramName}`);
3806
+ }
3807
+ }
3808
+ }
3809
+ } else if (options.type) {
3810
+ const originalValue = value;
3811
+ value = convertType(value, options.type);
3812
+ if (options.throwError === false) {
3813
+ if (options.type === "number" && typeof value === "number") {
3814
+ if (options.min !== void 0 && value < options.min) {
3815
+ value = void 0;
3816
+ }
3817
+ if (options.max !== void 0 && value > options.max) {
3818
+ value = void 0;
3819
+ }
3820
+ }
3821
+ }
3822
+ if (options.type === "string" && options.pattern && typeof value === "string" && !options.pattern.test(value)) {
3823
+ throw new BadRequestException(`Parameter '${key}' does not match pattern: ${options.patternName || options.pattern}`);
3824
+ } else if (options.type === "number" && options.pattern && typeof value === "number" && !options.pattern.test(String(value))) {
3825
+ throw new BadRequestException(`Parameter '${key}' does not match pattern: ${options.patternName || options.pattern}`);
3826
+ }
3827
+ if (options.throwError !== false) {
3828
+ if (options.type === "number" && typeof value === "number" && isNaN(value)) {
3829
+ throw new BadRequestException(`Type error: expected number${paramName}`);
3830
+ }
3831
+ if (options.type === "number" && typeof value === "number") {
3832
+ if (options.min !== void 0 && value < options.min) {
3833
+ throw new BadRequestException(`Validation error: number must be >= ${options.min}${paramName}`);
3834
+ }
3835
+ if (options.max !== void 0 && value > options.max) {
3836
+ throw new BadRequestException(`Validation error: number must be <= ${options.max}${paramName}`);
3837
+ }
3838
+ }
3839
+ if (options.type === "boolean" && !isValidBooleanInput(originalValue)) {
3840
+ throw new BadRequestException(`Type error: expected boolean${paramName}`);
3841
+ }
3842
+ }
3843
+ }
3790
3844
  }
3791
- };
3792
- var NotAcceptableException = class extends ErrorResponse {
3793
- static {
3794
- __name(this, "NotAcceptableException");
3845
+ if (options.transform && typeof options.transform === "function") {
3846
+ value = options.transform(value);
3795
3847
  }
3796
- /**
3797
- * @param message - Optional custom message. Defaults to "Not Acceptable".
3798
- */
3799
- constructor(message = "Not Acceptable") {
3800
- super(message);
3801
- this.status = HttpStatusCodes.NOT_ACCEPTABLE;
3848
+ if (options.validate && typeof options.validate === "function") {
3849
+ if (!options.validate(value)) {
3850
+ if (options.throwError !== false) {
3851
+ throw new BadRequestException(`Parameter validation failed${paramName}`);
3852
+ }
3853
+ return void 0;
3854
+ }
3802
3855
  }
3803
- };
3804
- var RequestTimeoutException = class extends ErrorResponse {
3805
- static {
3806
- __name(this, "RequestTimeoutException");
3856
+ return value;
3857
+ }
3858
+ __name(applyParamOptions, "applyParamOptions");
3859
+ function isValidBooleanInput(value) {
3860
+ if (typeof value === "boolean") return true;
3861
+ if (typeof value === "number") return value === 0 || value === 1;
3862
+ if (typeof value === "string") {
3863
+ const normalizedValue = value.toLowerCase().trim();
3864
+ return [
3865
+ "true",
3866
+ "false",
3867
+ "0",
3868
+ "1",
3869
+ "yes",
3870
+ "no"
3871
+ ].includes(normalizedValue);
3807
3872
  }
3808
- /**
3809
- * @param message - Optional custom message. Defaults to "Request Timeout".
3810
- */
3811
- constructor(message = "Request Timeout") {
3812
- super(message);
3813
- this.status = HttpStatusCodes.REQUEST_TIMEOUT;
3873
+ return false;
3874
+ }
3875
+ __name(isValidBooleanInput, "isValidBooleanInput");
3876
+ function convertType(value, type) {
3877
+ if (value === void 0 || value === null) {
3878
+ return value;
3814
3879
  }
3815
- };
3816
- var UnsupportedMediaTypeException = class extends ErrorResponse {
3817
- static {
3818
- __name(this, "UnsupportedMediaTypeException");
3880
+ switch (type) {
3881
+ case "number":
3882
+ return Number(value);
3883
+ case "boolean":
3884
+ if (typeof value === "string") {
3885
+ const normalizedValue = value.toLowerCase().trim();
3886
+ return normalizedValue === "true" || normalizedValue === "1" || normalizedValue === "yes";
3887
+ }
3888
+ return value === true || value === 1;
3889
+ case "string":
3890
+ default:
3891
+ return String(value);
3819
3892
  }
3820
- /**
3821
- * @param message - Optional custom message. Defaults to "Unsupported Media Type".
3822
- */
3823
- constructor(message = "Unsupported Media Type") {
3824
- super(message);
3825
- this.status = HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE;
3893
+ }
3894
+ __name(convertType, "convertType");
3895
+ async function ensureDir(dirPath) {
3896
+ await fsp__default.default.mkdir(dirPath, {
3897
+ recursive: true
3898
+ });
3899
+ }
3900
+ __name(ensureDir, "ensureDir");
3901
+ async function listFiles(dirPath, recursive = false) {
3902
+ const entries = await fsp__default.default.readdir(dirPath, {
3903
+ withFileTypes: true
3904
+ });
3905
+ const files = [];
3906
+ for (const entry of entries) {
3907
+ const fullPath = path__default.default.join(dirPath, entry.name);
3908
+ if (entry.isFile()) {
3909
+ files.push(fullPath);
3910
+ } else if (recursive && entry.isDirectory()) {
3911
+ const nestedFiles = await listFiles(fullPath, true);
3912
+ files.push(...nestedFiles);
3913
+ }
3826
3914
  }
3827
- };
3828
- var PayloadTooLargeException = class extends ErrorResponse {
3829
- static {
3830
- __name(this, "PayloadTooLargeException");
3915
+ return files;
3916
+ }
3917
+ __name(listFiles, "listFiles");
3918
+ async function deleteDirRecursive(dirPath) {
3919
+ await fsp__default.default.rm(dirPath, {
3920
+ recursive: true,
3921
+ force: true
3922
+ });
3923
+ }
3924
+ __name(deleteDirRecursive, "deleteDirRecursive");
3925
+ async function isDirectory(pathStr) {
3926
+ try {
3927
+ const stat = await fsp__default.default.stat(pathStr);
3928
+ return stat.isDirectory();
3929
+ } catch {
3930
+ return false;
3831
3931
  }
3832
- /**
3833
- * @param message - Optional custom message. Defaults to "Payload Too Large".
3834
- */
3835
- constructor(message = "Payload Too Large") {
3836
- super(message);
3837
- this.status = HttpStatusCodes.PAYLOAD_TOO_LARGE;
3932
+ }
3933
+ __name(isDirectory, "isDirectory");
3934
+ async function copyDir(src, dest) {
3935
+ await ensureDir(dest);
3936
+ const entries = await fsp__default.default.readdir(src, {
3937
+ withFileTypes: true
3938
+ });
3939
+ for (const entry of entries) {
3940
+ const srcPath = path__default.default.join(src, entry.name);
3941
+ const destPath = path__default.default.join(dest, entry.name);
3942
+ if (entry.isDirectory()) {
3943
+ await copyDir(srcPath, destPath);
3944
+ } else {
3945
+ await fsp__default.default.copyFile(srcPath, destPath);
3946
+ }
3838
3947
  }
3839
- };
3840
- var InsufficientStorageException = class extends ErrorResponse {
3841
- static {
3842
- __name(this, "InsufficientStorageException");
3948
+ }
3949
+ __name(copyDir, "copyDir");
3950
+ async function moveDir(src, dest) {
3951
+ await copyDir(src, dest);
3952
+ await deleteDirRecursive(src);
3953
+ }
3954
+ __name(moveDir, "moveDir");
3955
+ async function emptyDir(dirPath) {
3956
+ const entries = await fsp__default.default.readdir(dirPath, {
3957
+ withFileTypes: true
3958
+ });
3959
+ for (const entry of entries) {
3960
+ const entryPath = path__default.default.join(dirPath, entry.name);
3961
+ if (entry.isDirectory()) {
3962
+ await fsp__default.default.rm(entryPath, {
3963
+ recursive: true,
3964
+ force: true
3965
+ });
3966
+ } else {
3967
+ await fsp__default.default.unlink(entryPath);
3968
+ }
3843
3969
  }
3844
- /**
3845
- * @param message - Optional custom message. Defaults to "Insufficient Storage".
3846
- */
3847
- constructor(message = "Insufficient Storage") {
3848
- super(message);
3849
- this.status = HttpStatusCodes.INSUFFICIENT_STORAGE;
3970
+ }
3971
+ __name(emptyDir, "emptyDir");
3972
+ async function getDirSize(dirPath) {
3973
+ let total = 0;
3974
+ const entries = await fsp__default.default.readdir(dirPath, {
3975
+ withFileTypes: true
3976
+ });
3977
+ for (const entry of entries) {
3978
+ const entryPath = path__default.default.join(dirPath, entry.name);
3979
+ if (entry.isDirectory()) {
3980
+ total += await getDirSize(entryPath);
3981
+ } else {
3982
+ const stat = await fsp__default.default.stat(entryPath);
3983
+ total += stat.size;
3984
+ }
3850
3985
  }
3851
- };
3852
- function isHttpError(error) {
3853
- return error instanceof ErrorResponse;
3986
+ return total;
3854
3987
  }
3855
- __name(isHttpError, "isHttpError");
3856
- function createHttpError(status, message) {
3857
- switch (status) {
3858
- case HttpStatusCodes.BAD_REQUEST:
3859
- return new BadRequestException(message);
3860
- case HttpStatusCodes.UNAUTHORIZED:
3861
- return new UnauthorizedException(message);
3862
- case HttpStatusCodes.FORBIDDEN:
3863
- return new ForbiddenException(message);
3864
- case HttpStatusCodes.NOT_FOUND:
3865
- return new NotFoundException(message);
3866
- case HttpStatusCodes.METHOD_NOT_ALLOWED:
3867
- return new MethodNotAllowedException(message);
3868
- case HttpStatusCodes.NOT_ACCEPTABLE:
3869
- return new NotAcceptableException(message);
3870
- case HttpStatusCodes.REQUEST_TIMEOUT:
3871
- return new RequestTimeoutException(message);
3872
- case HttpStatusCodes.CONFLICT:
3873
- return new ConflictException(message);
3874
- case HttpStatusCodes.GONE:
3875
- return new HttpError(HttpStatusCodes.GONE, message || "Gone");
3876
- case HttpStatusCodes.PAYLOAD_TOO_LARGE:
3877
- return new PayloadTooLargeException(message);
3878
- case HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE:
3879
- return new UnsupportedMediaTypeException(message);
3880
- case HttpStatusCodes.UNPROCESSABLE_ENTITY:
3881
- return new UnprocessableEntityException(message);
3882
- case HttpStatusCodes.TOO_MANY_REQUESTS:
3883
- return new TooManyRequestsException(message);
3884
- case HttpStatusCodes.INTERNAL_SERVER_ERROR:
3885
- return new InternalServerErrorException(message);
3886
- case HttpStatusCodes.BAD_GATEWAY:
3887
- return new BadGatewayException(message);
3888
- case HttpStatusCodes.SERVICE_UNAVAILABLE:
3889
- return new ServiceUnavailableException(message);
3890
- case HttpStatusCodes.GATEWAY_TIMEOUT:
3891
- return new GatewayTimeoutException(message);
3892
- case HttpStatusCodes.INSUFFICIENT_STORAGE:
3893
- return new InsufficientStorageException(message);
3894
- default:
3895
- return new HttpError(status, message || `HTTP Error ${status}`);
3988
+ __name(getDirSize, "getDirSize");
3989
+ function watchDir(dirPath, callback) {
3990
+ const watcher = fs__default.default.watch(dirPath, (eventType, filename) => {
3991
+ callback(eventType, filename);
3992
+ });
3993
+ return () => watcher.close();
3994
+ }
3995
+ __name(watchDir, "watchDir");
3996
+ async function findFilesByPattern(pattern, options = {}) {
3997
+ const matchPattern = /* @__PURE__ */ __name((name, pattern2) => {
3998
+ let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, "\\$&");
3999
+ escaped = escaped.replaceAll("*", ".*").replaceAll("?", ".");
4000
+ const regex = new RegExp(`^${escaped}$`);
4001
+ return regex.test(name);
4002
+ }, "matchPattern");
4003
+ const { cwd = process.cwd(), dot = false } = options;
4004
+ const segments = pattern.split("/");
4005
+ async function walk(dir, segIndex) {
4006
+ if (segIndex >= segments.length) return [];
4007
+ const segment = segments[segIndex];
4008
+ const entries = await fs__default.default.promises.readdir(dir, {
4009
+ withFileTypes: true
4010
+ });
4011
+ let matchedFiles = [];
4012
+ for (const entry of entries) {
4013
+ const entryName = entry.name;
4014
+ if (!dot && entryName.startsWith(".")) continue;
4015
+ const fullPath = path__default.default.join(dir, entryName);
4016
+ const isLastSegment = segIndex === segments.length - 1;
4017
+ if (isLastSegment) {
4018
+ if (matchPattern(entryName, segment) && entry.isFile()) {
4019
+ matchedFiles.push(fullPath);
4020
+ }
4021
+ } else if (entry.isDirectory()) {
4022
+ if (matchPattern(entryName, segment)) {
4023
+ matchedFiles.push(...await walk(fullPath, segIndex + 1));
4024
+ }
4025
+ }
4026
+ }
4027
+ return matchedFiles;
3896
4028
  }
4029
+ __name(walk, "walk");
4030
+ return walk(cwd, 0);
3897
4031
  }
3898
- __name(createHttpError, "createHttpError");
3899
- function hasErrorShape(error) {
3900
- return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
4032
+ __name(findFilesByPattern, "findFilesByPattern");
4033
+ async function getSubdirectories(dirPath, recursive = false) {
4034
+ const entries = await fsp__default.default.readdir(dirPath, {
4035
+ withFileTypes: true
4036
+ });
4037
+ const dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => path__default.default.join(dirPath, entry.name));
4038
+ if (recursive && dirs.length > 0) {
4039
+ const nestedDirs = await Promise.all(dirs.map((dir) => getSubdirectories(dir, true)));
4040
+ return [
4041
+ ...dirs,
4042
+ ...nestedDirs.flat()
4043
+ ];
4044
+ }
4045
+ return dirs;
3901
4046
  }
3902
- __name(hasErrorShape, "hasErrorShape");
3903
- function getErrorMessage(error) {
3904
- if (typeof error === "string") {
3905
- return error;
4047
+ __name(getSubdirectories, "getSubdirectories");
4048
+ async function ensureEmptyDir(dirPath) {
4049
+ if (await isDirectory(dirPath)) {
4050
+ await emptyDir(dirPath);
4051
+ } else {
4052
+ try {
4053
+ await fsp__default.default.unlink(dirPath);
4054
+ } catch (error) {
4055
+ if (error.code !== "ENOENT") {
4056
+ throw error;
4057
+ }
4058
+ }
4059
+ await ensureDir(dirPath);
3906
4060
  }
3907
- if (error instanceof Error) {
3908
- return error.message;
4061
+ }
4062
+ __name(ensureEmptyDir, "ensureEmptyDir");
4063
+ async function createTempDir(options = {}) {
4064
+ const prefix = options.prefix || "tmp-";
4065
+ const parentDir = options.parentDir || os__default.default.tmpdir();
4066
+ const dirName = `${prefix}${crypto.randomBytes(6).toString("hex")}`;
4067
+ const tempDirPath = path__default.default.join(parentDir, dirName);
4068
+ await ensureDir(tempDirPath);
4069
+ const cleanup = /* @__PURE__ */ __name(async () => {
4070
+ try {
4071
+ await deleteDirRecursive(tempDirPath);
4072
+ } catch {
4073
+ }
4074
+ }, "cleanup");
4075
+ if (options.cleanup) {
4076
+ process.once("exit", () => {
4077
+ try {
4078
+ fs__default.default.rmSync(tempDirPath, {
4079
+ recursive: true,
4080
+ force: true
4081
+ });
4082
+ } catch {
4083
+ }
4084
+ });
4085
+ const signals = [
4086
+ "SIGINT",
4087
+ "SIGTERM",
4088
+ "SIGUSR1",
4089
+ "SIGUSR2"
4090
+ ];
4091
+ for (const signal of signals) {
4092
+ process.once(signal, () => {
4093
+ cleanup().then(() => process.exit());
4094
+ });
4095
+ }
3909
4096
  }
3910
- if (hasErrorShape(error)) {
3911
- return error.message;
4097
+ return {
4098
+ path: tempDirPath,
4099
+ cleanup
4100
+ };
4101
+ }
4102
+ __name(createTempDir, "createTempDir");
4103
+ async function findNewestFile(dirPath, recursive = false) {
4104
+ const files = await listFiles(dirPath, recursive);
4105
+ if (files.length === 0) return null;
4106
+ const stats = await Promise.all(files.map(async (file) => ({
4107
+ path: file,
4108
+ mtime: (await fsp__default.default.stat(file)).mtime
4109
+ })));
4110
+ return stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0].path;
4111
+ }
4112
+ __name(findNewestFile, "findNewestFile");
4113
+ async function findOldestFile(dirPath, recursive = false) {
4114
+ const files = await listFiles(dirPath, recursive);
4115
+ if (files.length === 0) return null;
4116
+ const stats = await Promise.all(files.map(async (file) => ({
4117
+ path: file,
4118
+ mtime: (await fsp__default.default.stat(file)).mtime
4119
+ })));
4120
+ return stats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime())[0].path;
4121
+ }
4122
+ __name(findOldestFile, "findOldestFile");
4123
+ async function findInDir(dirPath, predicate, recursive = false) {
4124
+ const entries = await fsp__default.default.readdir(dirPath, {
4125
+ withFileTypes: true
4126
+ });
4127
+ const results = [];
4128
+ for (const entry of entries) {
4129
+ const entryPath = path__default.default.join(dirPath, entry.name);
4130
+ const stat = await fsp__default.default.stat(entryPath);
4131
+ if (await predicate(entryPath, stat)) {
4132
+ results.push(entryPath);
4133
+ }
4134
+ if (recursive && entry.isDirectory()) {
4135
+ const nestedResults = await findInDir(entryPath, predicate, true);
4136
+ results.push(...nestedResults);
4137
+ }
3912
4138
  }
3913
- return "Unknown error occurred";
4139
+ return results;
3914
4140
  }
3915
- __name(getErrorMessage, "getErrorMessage");
3916
- function withErrorHandling(handler) {
3917
- return async (...args) => {
4141
+ __name(findInDir, "findInDir");
4142
+ async function watchDirRecursive(dirPath, callback, includeSubdirs = true) {
4143
+ const normalizedBasePath = path__default.default.normalize(dirPath);
4144
+ const watchers = [];
4145
+ const addWatcher = /* @__PURE__ */ __name((dir) => {
3918
4146
  try {
3919
- return await handler(...args);
3920
- } catch (err) {
3921
- if (isHttpError(err)) {
3922
- throw err;
3923
- }
3924
- getLogger().error({
3925
- err
3926
- }, "Caught error in handler");
3927
- let status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
3928
- if (hasErrorShape(err) && typeof err.status === "number") {
3929
- status = err.status;
4147
+ const watcher = fs__default.default.watch(dir, (eventType, filename) => {
4148
+ if (!filename) return;
4149
+ const fullPath = path__default.default.join(dir, filename);
4150
+ const relativePath = path__default.default.relative(normalizedBasePath, fullPath);
4151
+ callback(eventType, relativePath);
4152
+ if (eventType === "rename" && includeSubdirs) {
4153
+ setTimeout(async () => {
4154
+ try {
4155
+ if (await isDirectory(fullPath)) {
4156
+ addWatcher(fullPath);
4157
+ }
4158
+ } catch {
4159
+ }
4160
+ }, 100);
4161
+ }
4162
+ });
4163
+ watchers.push(watcher);
4164
+ } catch {
4165
+ }
4166
+ }, "addWatcher");
4167
+ addWatcher(normalizedBasePath);
4168
+ if (includeSubdirs) {
4169
+ const subdirs = await getSubdirectories(normalizedBasePath, true);
4170
+ for (const subdir of subdirs) {
4171
+ addWatcher(subdir);
4172
+ }
4173
+ }
4174
+ return () => {
4175
+ for (const watcher of watchers) {
4176
+ watcher.close();
4177
+ }
4178
+ };
4179
+ }
4180
+ __name(watchDirRecursive, "watchDirRecursive");
4181
+ async function getDirStats(dirPath) {
4182
+ let fileCount = 0;
4183
+ let dirCount = 0;
4184
+ let totalSize = 0;
4185
+ async function processDir(currentPath) {
4186
+ const entries = await fsp__default.default.readdir(currentPath, {
4187
+ withFileTypes: true
4188
+ });
4189
+ for (const entry of entries) {
4190
+ const entryPath = path__default.default.join(currentPath, entry.name);
4191
+ if (entry.isDirectory()) {
4192
+ dirCount++;
4193
+ await processDir(entryPath);
4194
+ } else if (entry.isFile()) {
4195
+ fileCount++;
4196
+ const stat = await fsp__default.default.stat(entryPath);
4197
+ totalSize += stat.size;
3930
4198
  }
3931
- throw createHttpError(status, getErrorMessage(err));
3932
4199
  }
4200
+ }
4201
+ __name(processDir, "processDir");
4202
+ await processDir(dirPath);
4203
+ return {
4204
+ fileCount,
4205
+ dirCount,
4206
+ totalSize
3933
4207
  };
3934
4208
  }
3935
- __name(withErrorHandling, "withErrorHandling");
4209
+ __name(getDirStats, "getDirStats");
4210
+ async function walkDir(dirPath, options) {
4211
+ const traversalOrder = options.traversalOrder || "pre";
4212
+ const entries = await fsp__default.default.readdir(dirPath, {
4213
+ withFileTypes: true
4214
+ });
4215
+ for (const entry of entries) {
4216
+ const entryPath = path__default.default.join(dirPath, entry.name);
4217
+ const stats = await fsp__default.default.stat(entryPath);
4218
+ const entryInfo = {
4219
+ path: entryPath,
4220
+ name: entry.name,
4221
+ isDirectory: entry.isDirectory(),
4222
+ stats
4223
+ };
4224
+ if (entry.isDirectory()) {
4225
+ if (traversalOrder === "pre") {
4226
+ const shouldContinue = await options.visitorFn(entryInfo);
4227
+ if (shouldContinue !== false) {
4228
+ await walkDir(entryPath, options);
4229
+ }
4230
+ } else {
4231
+ await walkDir(entryPath, options);
4232
+ await options.visitorFn(entryInfo);
4233
+ }
4234
+ } else {
4235
+ await options.visitorFn(entryInfo);
4236
+ }
4237
+ }
4238
+ if (traversalOrder === "post") {
4239
+ const stats = await fsp__default.default.stat(dirPath);
4240
+ const entryInfo = {
4241
+ path: dirPath,
4242
+ name: path__default.default.basename(dirPath),
4243
+ isDirectory: true,
4244
+ stats
4245
+ };
4246
+ await options.visitorFn(entryInfo);
4247
+ }
4248
+ }
4249
+ __name(walkDir, "walkDir");
3936
4250
  async function fileExists(path3) {
3937
4251
  try {
3938
4252
  await fsp__default.default.access(path3);
@@ -6380,6 +6694,10 @@ exports.RateLimit = RateLimit;
6380
6694
  exports.Redirect = Redirect;
6381
6695
  exports.RedirectResponse = RedirectResponse;
6382
6696
  exports.Req = Req;
6697
+ exports.ReqCookie = ReqCookie;
6698
+ exports.ReqHeader = ReqHeader;
6699
+ exports.ReqId = ReqId;
6700
+ exports.ReqLogger = ReqLogger;
6383
6701
  exports.RequestTimeoutException = RequestTimeoutException;
6384
6702
  exports.Res = Res;
6385
6703
  exports.Roles = Roles;
@@ -6419,6 +6737,8 @@ exports.createErrorResponse = createErrorResponse;
6419
6737
  exports.createFinalErrorResponse = createFinalErrorResponse;
6420
6738
  exports.createHttpError = createHttpError;
6421
6739
  exports.createPaginatedResponse = createPaginatedResponse;
6740
+ exports.createParamDecorator = createParamDecorator;
6741
+ exports.createParamDecoratorWithoutParam = createParamDecoratorWithoutParam;
6422
6742
  exports.createRequestLogger = createRequestLogger;
6423
6743
  exports.createSignedToken = createSignedToken;
6424
6744
  exports.createSuccessResponse = createSuccessResponse;
@@ -6477,6 +6797,7 @@ exports.hasRequiredProps = hasRequiredProps;
6477
6797
  exports.hash = hash;
6478
6798
  exports.healthCheck = healthCheck;
6479
6799
  exports.hmac = hmac;
6800
+ exports.inject = inject;
6480
6801
  exports.intersect = intersect;
6481
6802
  exports.isAlpha = isAlpha;
6482
6803
  exports.isAlphanumeric = isAlphanumeric;