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