@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/README.md +3 -2
- package/build/index.cjs +1271 -950
- package/build/index.d.ts +176 -23
- package/build/index.mjs +1265 -951
- package/package.json +1 -1
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
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
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
|
-
|
|
1698
|
-
|
|
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
|
-
|
|
2755
|
-
|
|
2756
|
-
var
|
|
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, "
|
|
2764
|
+
__name(this, "HttpError");
|
|
2772
2765
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
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
|
-
|
|
2781
|
-
|
|
2775
|
+
};
|
|
2776
|
+
var InternalServerErrorException = class extends ErrorResponse {
|
|
2777
|
+
static {
|
|
2778
|
+
__name(this, "InternalServerErrorException");
|
|
2782
2779
|
}
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
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
|
-
|
|
2803
|
-
|
|
2787
|
+
};
|
|
2788
|
+
var UnauthorizedException = class extends ErrorResponse {
|
|
2789
|
+
static {
|
|
2790
|
+
__name(this, "UnauthorizedException");
|
|
2804
2791
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
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
|
-
|
|
2809
|
-
|
|
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
|
|
2813
|
-
var DIContainer = class {
|
|
2812
|
+
var NotFoundException = class extends ErrorResponse {
|
|
2814
2813
|
static {
|
|
2815
|
-
__name(this, "
|
|
2814
|
+
__name(this, "NotFoundException");
|
|
2816
2815
|
}
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
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
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
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
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
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
|
|
2846
|
-
|
|
2847
|
-
|
|
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
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
var
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
}
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
}
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
__name(
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
__name(
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
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(
|
|
2983
|
-
function
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
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(
|
|
2993
|
-
function
|
|
2994
|
-
return
|
|
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(
|
|
3003
|
-
function
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
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(
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
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.
|
|
3264
|
+
const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target) || [];
|
|
3265
|
+
Reflect.defineMetadata(MIDDLEWARE_KEY, [
|
|
3266
|
+
...existing,
|
|
3267
|
+
...middlewares
|
|
3268
|
+
], target);
|
|
3026
3269
|
} else {
|
|
3027
|
-
Reflect.
|
|
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(
|
|
3032
|
-
function
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
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(
|
|
3040
|
-
function
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
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.
|
|
3050
|
-
|
|
3051
|
-
|
|
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.
|
|
3055
|
-
|
|
3056
|
-
|
|
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(
|
|
3062
|
-
function
|
|
3377
|
+
__name(Headers, "Headers");
|
|
3378
|
+
function Before(fn) {
|
|
3063
3379
|
return (target, propertyKey, _descriptor) => {
|
|
3064
3380
|
if (typeof propertyKey === "undefined") {
|
|
3065
|
-
Reflect.
|
|
3066
|
-
|
|
3067
|
-
|
|
3381
|
+
const hooks = Reflect.getMetadata(BEFORE_KEY, target) || [];
|
|
3382
|
+
hooks.push(fn);
|
|
3383
|
+
Reflect.defineMetadata(BEFORE_KEY, hooks, target);
|
|
3068
3384
|
} else {
|
|
3069
|
-
Reflect.
|
|
3070
|
-
|
|
3071
|
-
|
|
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(
|
|
3076
|
-
function
|
|
3391
|
+
__name(Before, "Before");
|
|
3392
|
+
function After(fn) {
|
|
3077
3393
|
return (target, propertyKey, _descriptor) => {
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
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
|
|
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
|
|
3116
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
}
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
if (
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
}
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
}
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
}
|
|
3344
|
-
} else {
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
}
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
}
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
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
|
-
|
|
3793
|
-
static {
|
|
3794
|
-
__name(this, "NotAcceptableException");
|
|
3845
|
+
if (options.transform && typeof options.transform === "function") {
|
|
3846
|
+
value = options.transform(value);
|
|
3795
3847
|
}
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
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
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
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
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
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
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
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
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
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
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
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
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
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
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
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
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
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(
|
|
3856
|
-
function
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
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(
|
|
3899
|
-
function
|
|
3900
|
-
|
|
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(
|
|
3903
|
-
function
|
|
3904
|
-
if (
|
|
3905
|
-
|
|
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
|
-
|
|
3908
|
-
|
|
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
|
-
|
|
3911
|
-
|
|
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
|
|
4139
|
+
return results;
|
|
3914
4140
|
}
|
|
3915
|
-
__name(
|
|
3916
|
-
function
|
|
3917
|
-
|
|
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
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
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(
|
|
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;
|