@catbee/utils 0.0.8-rc.4 → 1.0.2
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 +2078 -1108
- package/build/index.d.ts +648 -23
- package/build/index.mjs +2044 -1109
- package/package.json +1 -1
package/build/index.cjs
CHANGED
|
@@ -11,6 +11,7 @@ var expressRateLimit = require('express-rate-limit');
|
|
|
11
11
|
var os = require('os');
|
|
12
12
|
var fsp = require('fs/promises');
|
|
13
13
|
var promises = require('stream/promises');
|
|
14
|
+
var stream = require('stream');
|
|
14
15
|
var url = require('url');
|
|
15
16
|
var express = require('express');
|
|
16
17
|
var https = require('https');
|
|
@@ -1660,7 +1661,7 @@ function addSensitiveFields(fields) {
|
|
|
1660
1661
|
__name(addSensitiveFields, "addSensitiveFields");
|
|
1661
1662
|
var _globalThis = typeof globalThis === "object" ? globalThis : global;
|
|
1662
1663
|
var _global = _globalThis;
|
|
1663
|
-
function setupLogger() {
|
|
1664
|
+
function setupLogger(isGlobal = true) {
|
|
1664
1665
|
const logParams = {
|
|
1665
1666
|
name: config.logger.name || "@catbee/utils",
|
|
1666
1667
|
level: config.logger.level || "info",
|
|
@@ -1674,14 +1675,14 @@ function setupLogger() {
|
|
|
1674
1675
|
],
|
|
1675
1676
|
censor: /* @__PURE__ */ __name((value, path3) => redact(value, path3), "censor")
|
|
1676
1677
|
},
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1678
|
+
serializers: {
|
|
1679
|
+
req: pino__default.default.stdSerializers.req,
|
|
1680
|
+
request: pino__default.default.stdSerializers.req,
|
|
1681
|
+
res: pino__default.default.stdSerializers.res,
|
|
1682
|
+
response: pino__default.default.stdSerializers.res,
|
|
1683
|
+
err: pino__default.default.stdSerializers.err,
|
|
1684
|
+
error: pino__default.default.stdSerializers.err
|
|
1685
|
+
},
|
|
1685
1686
|
timestamp: pino.stdTimeFunctions.isoTime
|
|
1686
1687
|
};
|
|
1687
1688
|
const logger2 = config.logger.pretty && Env.isDev() ? pino__default.default(logParams, pino__default.default.transport({
|
|
@@ -1694,11 +1695,17 @@ function setupLogger() {
|
|
|
1694
1695
|
levelFirst: true
|
|
1695
1696
|
}
|
|
1696
1697
|
})) : pino__default.default(logParams);
|
|
1697
|
-
|
|
1698
|
-
|
|
1698
|
+
if (isGlobal) {
|
|
1699
|
+
_global[GLOBAL_LOGGER_KEY] = logger2;
|
|
1700
|
+
_global[GLOBAL_LOGGER_KEY]?.debug("Logger initialized");
|
|
1701
|
+
}
|
|
1702
|
+
return logger2;
|
|
1699
1703
|
}
|
|
1700
1704
|
__name(setupLogger, "setupLogger");
|
|
1701
|
-
function getLogger() {
|
|
1705
|
+
function getLogger(newInstance = false) {
|
|
1706
|
+
if (newInstance) {
|
|
1707
|
+
return setupLogger(false);
|
|
1708
|
+
}
|
|
1702
1709
|
const logger2 = ContextStore.get(StoreKeys.LOGGER);
|
|
1703
1710
|
if (logger2) return logger2;
|
|
1704
1711
|
if (!_global[GLOBAL_LOGGER_KEY]) {
|
|
@@ -1707,7 +1714,7 @@ function getLogger() {
|
|
|
1707
1714
|
return _global[GLOBAL_LOGGER_KEY];
|
|
1708
1715
|
}
|
|
1709
1716
|
__name(getLogger, "getLogger");
|
|
1710
|
-
var logger = getLogger();
|
|
1717
|
+
var logger = getLogger(false);
|
|
1711
1718
|
function createChildLogger(bindings, parentLogger) {
|
|
1712
1719
|
const logger2 = parentLogger || getLogger();
|
|
1713
1720
|
return logger2.child(bindings);
|
|
@@ -2498,6 +2505,234 @@ function verifySignedToken(token, secret) {
|
|
|
2498
2505
|
}
|
|
2499
2506
|
__name(verifySignedToken, "verifySignedToken");
|
|
2500
2507
|
|
|
2508
|
+
// src/utils/date.utils.ts
|
|
2509
|
+
function formatDate(date, options = {}) {
|
|
2510
|
+
const { format = "yyyy-MM-dd", locale, timeZone } = options;
|
|
2511
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
2512
|
+
if (format === "yyyy-MM-dd") {
|
|
2513
|
+
const yyyy = d.getFullYear();
|
|
2514
|
+
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
|
2515
|
+
const dd = String(d.getDate()).padStart(2, "0");
|
|
2516
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
2517
|
+
}
|
|
2518
|
+
if (format === "yyyy-MM-dd HH:mm:ss") {
|
|
2519
|
+
const yyyy = d.getFullYear();
|
|
2520
|
+
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
|
2521
|
+
const dd = String(d.getDate()).padStart(2, "0");
|
|
2522
|
+
const HH = String(d.getHours()).padStart(2, "0");
|
|
2523
|
+
const MM = String(d.getMinutes()).padStart(2, "0");
|
|
2524
|
+
const SS = String(d.getSeconds()).padStart(2, "0");
|
|
2525
|
+
return `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`;
|
|
2526
|
+
}
|
|
2527
|
+
if (format === "relative") {
|
|
2528
|
+
return formatRelativeTime(date);
|
|
2529
|
+
}
|
|
2530
|
+
return new Intl.DateTimeFormat(locale, {
|
|
2531
|
+
timeZone,
|
|
2532
|
+
year: format.includes("yyyy") || format.includes("y") ? "numeric" : void 0,
|
|
2533
|
+
month: format.includes("MM") || format.includes("M") ? "numeric" : void 0,
|
|
2534
|
+
day: format.includes("dd") || format.includes("d") ? "numeric" : void 0,
|
|
2535
|
+
hour: format.includes("HH") || format.includes("H") ? "numeric" : void 0,
|
|
2536
|
+
minute: format.includes("mm") || format.includes("m") ? "numeric" : void 0,
|
|
2537
|
+
second: format.includes("ss") || format.includes("s") ? "numeric" : void 0,
|
|
2538
|
+
hour12: !format.includes("HH") && !format.includes("H")
|
|
2539
|
+
}).format(d);
|
|
2540
|
+
}
|
|
2541
|
+
__name(formatDate, "formatDate");
|
|
2542
|
+
function formatRelativeTime(date, now = /* @__PURE__ */ new Date(), locale) {
|
|
2543
|
+
const d1 = date instanceof Date ? date : new Date(date);
|
|
2544
|
+
const d2 = now instanceof Date ? now : new Date(now);
|
|
2545
|
+
const diffMs = d1.getTime() - d2.getTime();
|
|
2546
|
+
const diffSecs = Math.round(diffMs / 1e3);
|
|
2547
|
+
const diffMins = Math.round(diffSecs / 60);
|
|
2548
|
+
const diffHours = Math.round(diffMins / 60);
|
|
2549
|
+
const diffDays = Math.round(diffHours / 24);
|
|
2550
|
+
const diffMonths = Math.round(diffDays / 30);
|
|
2551
|
+
const diffYears = Math.round(diffDays / 365);
|
|
2552
|
+
const formatter = new Intl.RelativeTimeFormat(locale, {
|
|
2553
|
+
numeric: "auto"
|
|
2554
|
+
});
|
|
2555
|
+
if (Math.abs(diffSecs) < 60) return formatter.format(diffSecs, "second");
|
|
2556
|
+
if (Math.abs(diffMins) < 60) return formatter.format(diffMins, "minute");
|
|
2557
|
+
if (Math.abs(diffHours) < 24) return formatter.format(diffHours, "hour");
|
|
2558
|
+
if (Math.abs(diffDays) < 30) return formatter.format(diffDays, "day");
|
|
2559
|
+
if (Math.abs(diffMonths) < 12) return formatter.format(diffMonths, "month");
|
|
2560
|
+
return formatter.format(diffYears, "year");
|
|
2561
|
+
}
|
|
2562
|
+
__name(formatRelativeTime, "formatRelativeTime");
|
|
2563
|
+
function parseDate(input, fallback) {
|
|
2564
|
+
if (typeof input === "number") {
|
|
2565
|
+
return new Date(input);
|
|
2566
|
+
}
|
|
2567
|
+
try {
|
|
2568
|
+
const date = new Date(input);
|
|
2569
|
+
if (isNaN(date.getTime())) {
|
|
2570
|
+
return fallback || null;
|
|
2571
|
+
}
|
|
2572
|
+
return date;
|
|
2573
|
+
} catch {
|
|
2574
|
+
return fallback || null;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
__name(parseDate, "parseDate");
|
|
2578
|
+
function dateDiff(date1, date2 = /* @__PURE__ */ new Date(), unit = "days") {
|
|
2579
|
+
const d1 = date1 instanceof Date ? date1 : new Date(date1);
|
|
2580
|
+
const d2 = date2 instanceof Date ? date2 : new Date(date2);
|
|
2581
|
+
const diffMs = d1.getTime() - d2.getTime();
|
|
2582
|
+
switch (unit) {
|
|
2583
|
+
case "milliseconds":
|
|
2584
|
+
return diffMs;
|
|
2585
|
+
case "seconds":
|
|
2586
|
+
return diffMs / 1e3;
|
|
2587
|
+
case "minutes":
|
|
2588
|
+
return diffMs / (1e3 * 60);
|
|
2589
|
+
case "hours":
|
|
2590
|
+
return diffMs / (1e3 * 60 * 60);
|
|
2591
|
+
case "days":
|
|
2592
|
+
return diffMs / (1e3 * 60 * 60 * 24);
|
|
2593
|
+
case "months":
|
|
2594
|
+
return (d1.getFullYear() - d2.getFullYear()) * 12 + d1.getMonth() - d2.getMonth();
|
|
2595
|
+
case "years":
|
|
2596
|
+
return d1.getFullYear() - d2.getFullYear();
|
|
2597
|
+
default:
|
|
2598
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
__name(dateDiff, "dateDiff");
|
|
2602
|
+
function addToDate(date, amount, unit) {
|
|
2603
|
+
const d = date instanceof Date ? new Date(date) : new Date(date);
|
|
2604
|
+
switch (unit) {
|
|
2605
|
+
case "milliseconds":
|
|
2606
|
+
d.setMilliseconds(d.getMilliseconds() + amount);
|
|
2607
|
+
break;
|
|
2608
|
+
case "seconds":
|
|
2609
|
+
d.setSeconds(d.getSeconds() + amount);
|
|
2610
|
+
break;
|
|
2611
|
+
case "minutes":
|
|
2612
|
+
d.setMinutes(d.getMinutes() + amount);
|
|
2613
|
+
break;
|
|
2614
|
+
case "hours":
|
|
2615
|
+
d.setHours(d.getHours() + amount);
|
|
2616
|
+
break;
|
|
2617
|
+
case "days":
|
|
2618
|
+
d.setDate(d.getDate() + amount);
|
|
2619
|
+
break;
|
|
2620
|
+
case "months": {
|
|
2621
|
+
const origDate = d.getDate();
|
|
2622
|
+
const origMonth = d.getMonth();
|
|
2623
|
+
d.setDate(1);
|
|
2624
|
+
d.setMonth(origMonth + amount);
|
|
2625
|
+
const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
|
|
2626
|
+
d.setDate(Math.min(origDate, lastDay));
|
|
2627
|
+
break;
|
|
2628
|
+
}
|
|
2629
|
+
case "years":
|
|
2630
|
+
d.setFullYear(d.getFullYear() + amount);
|
|
2631
|
+
break;
|
|
2632
|
+
default:
|
|
2633
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
2634
|
+
}
|
|
2635
|
+
return d;
|
|
2636
|
+
}
|
|
2637
|
+
__name(addToDate, "addToDate");
|
|
2638
|
+
function startOf(date, unit) {
|
|
2639
|
+
const d = date instanceof Date ? new Date(date) : new Date(date);
|
|
2640
|
+
switch (unit) {
|
|
2641
|
+
case "second":
|
|
2642
|
+
d.setMilliseconds(0);
|
|
2643
|
+
break;
|
|
2644
|
+
case "minute":
|
|
2645
|
+
d.setSeconds(0, 0);
|
|
2646
|
+
break;
|
|
2647
|
+
case "hour":
|
|
2648
|
+
d.setMinutes(0, 0, 0);
|
|
2649
|
+
break;
|
|
2650
|
+
case "day":
|
|
2651
|
+
d.setHours(0, 0, 0, 0);
|
|
2652
|
+
break;
|
|
2653
|
+
case "week":
|
|
2654
|
+
d.setHours(0, 0, 0, 0);
|
|
2655
|
+
d.setDate(d.getDate() - d.getDay());
|
|
2656
|
+
break;
|
|
2657
|
+
case "month":
|
|
2658
|
+
d.setDate(1);
|
|
2659
|
+
d.setHours(0, 0, 0, 0);
|
|
2660
|
+
break;
|
|
2661
|
+
case "quarter":
|
|
2662
|
+
d.setMonth(Math.floor(d.getMonth() / 3) * 3, 1);
|
|
2663
|
+
d.setHours(0, 0, 0, 0);
|
|
2664
|
+
break;
|
|
2665
|
+
case "year":
|
|
2666
|
+
d.setMonth(0, 1);
|
|
2667
|
+
d.setHours(0, 0, 0, 0);
|
|
2668
|
+
break;
|
|
2669
|
+
default:
|
|
2670
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
2671
|
+
}
|
|
2672
|
+
return d;
|
|
2673
|
+
}
|
|
2674
|
+
__name(startOf, "startOf");
|
|
2675
|
+
function endOf(date, unit) {
|
|
2676
|
+
const d = date instanceof Date ? new Date(date) : new Date(date);
|
|
2677
|
+
switch (unit) {
|
|
2678
|
+
case "second":
|
|
2679
|
+
d.setMilliseconds(999);
|
|
2680
|
+
break;
|
|
2681
|
+
case "minute":
|
|
2682
|
+
d.setSeconds(59, 999);
|
|
2683
|
+
break;
|
|
2684
|
+
case "hour":
|
|
2685
|
+
d.setMinutes(59, 59, 999);
|
|
2686
|
+
break;
|
|
2687
|
+
case "day":
|
|
2688
|
+
d.setHours(23, 59, 59, 999);
|
|
2689
|
+
break;
|
|
2690
|
+
case "week":
|
|
2691
|
+
d.setDate(d.getDate() - d.getDay() + 6);
|
|
2692
|
+
d.setHours(23, 59, 59, 999);
|
|
2693
|
+
break;
|
|
2694
|
+
case "month":
|
|
2695
|
+
d.setMonth(d.getMonth() + 1, 0);
|
|
2696
|
+
d.setHours(23, 59, 59, 999);
|
|
2697
|
+
break;
|
|
2698
|
+
case "quarter":
|
|
2699
|
+
d.setMonth(Math.floor(d.getMonth() / 3) * 3 + 3, 0);
|
|
2700
|
+
d.setHours(23, 59, 59, 999);
|
|
2701
|
+
break;
|
|
2702
|
+
case "year":
|
|
2703
|
+
d.setMonth(11, 31);
|
|
2704
|
+
d.setHours(23, 59, 59, 999);
|
|
2705
|
+
break;
|
|
2706
|
+
default:
|
|
2707
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
2708
|
+
}
|
|
2709
|
+
return d;
|
|
2710
|
+
}
|
|
2711
|
+
__name(endOf, "endOf");
|
|
2712
|
+
function isBetween(date, start, end, inclusive = true) {
|
|
2713
|
+
const d = date instanceof Date ? date.getTime() : date;
|
|
2714
|
+
const s = start instanceof Date ? start.getTime() : start;
|
|
2715
|
+
const e = end instanceof Date ? end.getTime() : end;
|
|
2716
|
+
return inclusive ? d >= s && d <= e : d > s && d < e;
|
|
2717
|
+
}
|
|
2718
|
+
__name(isBetween, "isBetween");
|
|
2719
|
+
function isLeapYear(year) {
|
|
2720
|
+
const y = year instanceof Date ? year.getFullYear() : year;
|
|
2721
|
+
return y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;
|
|
2722
|
+
}
|
|
2723
|
+
__name(isLeapYear, "isLeapYear");
|
|
2724
|
+
function daysInMonth(year, month) {
|
|
2725
|
+
if (year instanceof Date) {
|
|
2726
|
+
month = year.getMonth();
|
|
2727
|
+
year = year.getFullYear();
|
|
2728
|
+
}
|
|
2729
|
+
if (month === void 0) {
|
|
2730
|
+
throw new Error("Month is required when year is a number");
|
|
2731
|
+
}
|
|
2732
|
+
return new Date(year, month + 1, 0).getDate();
|
|
2733
|
+
}
|
|
2734
|
+
__name(daysInMonth, "daysInMonth");
|
|
2735
|
+
|
|
2501
2736
|
// src/utils/response.utils.ts
|
|
2502
2737
|
var SuccessResponse = class {
|
|
2503
2738
|
static {
|
|
@@ -2751,1188 +2986,1500 @@ var HttpStatusCodes = /* @__PURE__ */ (function(HttpStatusCodes2) {
|
|
|
2751
2986
|
HttpStatusCodes2[HttpStatusCodes2["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
|
|
2752
2987
|
return HttpStatusCodes2;
|
|
2753
2988
|
})({});
|
|
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 {
|
|
2989
|
+
|
|
2990
|
+
// src/utils/exception.utils.ts
|
|
2991
|
+
var HttpError = class extends ErrorResponse {
|
|
2770
2992
|
static {
|
|
2771
|
-
__name(this, "
|
|
2993
|
+
__name(this, "HttpError");
|
|
2772
2994
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2995
|
+
/**
|
|
2996
|
+
* Creates a new HTTP error instance.
|
|
2997
|
+
* @param status - A valid HTTP status code (e.g., 400, 500).
|
|
2998
|
+
* @param message - The error message to return to the client.
|
|
2999
|
+
*/
|
|
3000
|
+
constructor(status, message) {
|
|
3001
|
+
super(message);
|
|
3002
|
+
this.status = status;
|
|
2779
3003
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
3004
|
+
};
|
|
3005
|
+
var InternalServerErrorException = class extends ErrorResponse {
|
|
3006
|
+
static {
|
|
3007
|
+
__name(this, "InternalServerErrorException");
|
|
2782
3008
|
}
|
|
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;
|
|
3009
|
+
/**
|
|
3010
|
+
* @param message - Optional custom message. Defaults to "Internal server error".
|
|
3011
|
+
*/
|
|
3012
|
+
constructor(message = "Internal server error") {
|
|
3013
|
+
super(message);
|
|
3014
|
+
this.status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
|
|
2801
3015
|
}
|
|
2802
|
-
|
|
2803
|
-
|
|
3016
|
+
};
|
|
3017
|
+
var UnauthorizedException = class extends ErrorResponse {
|
|
3018
|
+
static {
|
|
3019
|
+
__name(this, "UnauthorizedException");
|
|
2804
3020
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
3021
|
+
/**
|
|
3022
|
+
* @param message - Optional custom message. Defaults to "Unauthorized".
|
|
3023
|
+
*/
|
|
3024
|
+
constructor(message = "Unauthorized") {
|
|
3025
|
+
super(message);
|
|
3026
|
+
this.status = HttpStatusCodes.UNAUTHORIZED;
|
|
2807
3027
|
}
|
|
2808
|
-
|
|
2809
|
-
|
|
3028
|
+
};
|
|
3029
|
+
var BadRequestException = class extends ErrorResponse {
|
|
3030
|
+
static {
|
|
3031
|
+
__name(this, "BadRequestException");
|
|
3032
|
+
}
|
|
3033
|
+
/**
|
|
3034
|
+
* @param message - Optional custom message. Defaults to "Bad request".
|
|
3035
|
+
*/
|
|
3036
|
+
constructor(message = "Bad request") {
|
|
3037
|
+
super(message);
|
|
3038
|
+
this.status = HttpStatusCodes.BAD_REQUEST;
|
|
2810
3039
|
}
|
|
2811
3040
|
};
|
|
2812
|
-
var
|
|
2813
|
-
var DIContainer = class {
|
|
3041
|
+
var NotFoundException = class extends ErrorResponse {
|
|
2814
3042
|
static {
|
|
2815
|
-
__name(this, "
|
|
3043
|
+
__name(this, "NotFoundException");
|
|
2816
3044
|
}
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
3045
|
+
/**
|
|
3046
|
+
* @param message - Optional custom message. Defaults to "Resource not found".
|
|
3047
|
+
*/
|
|
3048
|
+
constructor(message = "Resource not found") {
|
|
3049
|
+
super(message);
|
|
3050
|
+
this.status = HttpStatusCodes.NOT_FOUND;
|
|
2821
3051
|
}
|
|
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;
|
|
3052
|
+
};
|
|
3053
|
+
var ForbiddenException = class extends ErrorResponse {
|
|
3054
|
+
static {
|
|
3055
|
+
__name(this, "ForbiddenException");
|
|
2839
3056
|
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
3057
|
+
/**
|
|
3058
|
+
* @param message - Optional custom message. Defaults to "Forbidden".
|
|
3059
|
+
*/
|
|
3060
|
+
constructor(message = "Forbidden") {
|
|
3061
|
+
super(message);
|
|
3062
|
+
this.status = HttpStatusCodes.FORBIDDEN;
|
|
2843
3063
|
}
|
|
2844
3064
|
};
|
|
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;
|
|
3065
|
+
var ConflictException = class extends ErrorResponse {
|
|
3066
|
+
static {
|
|
3067
|
+
__name(this, "ConflictException");
|
|
2851
3068
|
}
|
|
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
|
-
|
|
3069
|
+
/**
|
|
3070
|
+
* @param message - Optional custom message. Defaults to "Conflict".
|
|
3071
|
+
*/
|
|
3072
|
+
constructor(message = "Conflict") {
|
|
3073
|
+
super(message);
|
|
3074
|
+
this.status = HttpStatusCodes.CONFLICT;
|
|
3075
|
+
}
|
|
3076
|
+
};
|
|
3077
|
+
var BadGatewayException = class extends ErrorResponse {
|
|
3078
|
+
static {
|
|
3079
|
+
__name(this, "BadGatewayException");
|
|
3080
|
+
}
|
|
3081
|
+
/**
|
|
3082
|
+
* @param message - Optional custom message. Defaults to "Bad Gateway".
|
|
3083
|
+
*/
|
|
3084
|
+
constructor(message = "Bad Gateway") {
|
|
3085
|
+
super(message);
|
|
3086
|
+
this.status = HttpStatusCodes.BAD_GATEWAY;
|
|
3087
|
+
}
|
|
3088
|
+
};
|
|
3089
|
+
var TooManyRequestsException = class extends ErrorResponse {
|
|
3090
|
+
static {
|
|
3091
|
+
__name(this, "TooManyRequestsException");
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
* @param message - Optional custom message. Defaults to "Too many requests".
|
|
3095
|
+
*/
|
|
3096
|
+
constructor(message = "Too many requests") {
|
|
3097
|
+
super(message);
|
|
3098
|
+
this.status = HttpStatusCodes.TOO_MANY_REQUESTS;
|
|
3099
|
+
}
|
|
3100
|
+
};
|
|
3101
|
+
var ServiceUnavailableException = class extends ErrorResponse {
|
|
3102
|
+
static {
|
|
3103
|
+
__name(this, "ServiceUnavailableException");
|
|
3104
|
+
}
|
|
3105
|
+
/**
|
|
3106
|
+
* @param message - Optional custom message. Defaults to "Service Unavailable".
|
|
3107
|
+
*/
|
|
3108
|
+
constructor(message = "Service Unavailable") {
|
|
3109
|
+
super(message);
|
|
3110
|
+
this.status = HttpStatusCodes.SERVICE_UNAVAILABLE;
|
|
3111
|
+
}
|
|
3112
|
+
};
|
|
3113
|
+
var GatewayTimeoutException = class extends ErrorResponse {
|
|
3114
|
+
static {
|
|
3115
|
+
__name(this, "GatewayTimeoutException");
|
|
3116
|
+
}
|
|
3117
|
+
/**
|
|
3118
|
+
* @param message - Optional custom message. Defaults to "Gateway Timeout".
|
|
3119
|
+
*/
|
|
3120
|
+
constructor(message = "Gateway Timeout") {
|
|
3121
|
+
super(message);
|
|
3122
|
+
this.status = HttpStatusCodes.GATEWAY_TIMEOUT;
|
|
3123
|
+
}
|
|
3124
|
+
};
|
|
3125
|
+
var UnprocessableEntityException = class extends ErrorResponse {
|
|
3126
|
+
static {
|
|
3127
|
+
__name(this, "UnprocessableEntityException");
|
|
3128
|
+
}
|
|
3129
|
+
details;
|
|
3130
|
+
/**
|
|
3131
|
+
* @param message - Optional custom message. Defaults to "Unprocessable Entity".
|
|
3132
|
+
* @param details - Optional validation details or additional error context.
|
|
3133
|
+
*/
|
|
3134
|
+
constructor(message = "Unprocessable Entity", details) {
|
|
3135
|
+
super(message), this.details = details;
|
|
3136
|
+
this.status = HttpStatusCodes.UNPROCESSABLE_ENTITY;
|
|
3137
|
+
}
|
|
3138
|
+
};
|
|
3139
|
+
var MethodNotAllowedException = class extends ErrorResponse {
|
|
3140
|
+
static {
|
|
3141
|
+
__name(this, "MethodNotAllowedException");
|
|
3142
|
+
}
|
|
3143
|
+
allowedMethods;
|
|
3144
|
+
/**
|
|
3145
|
+
* @param message - Optional custom message. Defaults to "Method Not Allowed".
|
|
3146
|
+
* @param allowedMethods - Optional array of allowed HTTP methods.
|
|
3147
|
+
*/
|
|
3148
|
+
constructor(message = "Method Not Allowed", allowedMethods) {
|
|
3149
|
+
super(message), this.allowedMethods = allowedMethods;
|
|
3150
|
+
this.status = HttpStatusCodes.METHOD_NOT_ALLOWED;
|
|
3151
|
+
}
|
|
3152
|
+
};
|
|
3153
|
+
var NotAcceptableException = class extends ErrorResponse {
|
|
3154
|
+
static {
|
|
3155
|
+
__name(this, "NotAcceptableException");
|
|
3156
|
+
}
|
|
3157
|
+
/**
|
|
3158
|
+
* @param message - Optional custom message. Defaults to "Not Acceptable".
|
|
3159
|
+
*/
|
|
3160
|
+
constructor(message = "Not Acceptable") {
|
|
3161
|
+
super(message);
|
|
3162
|
+
this.status = HttpStatusCodes.NOT_ACCEPTABLE;
|
|
3163
|
+
}
|
|
3164
|
+
};
|
|
3165
|
+
var RequestTimeoutException = class extends ErrorResponse {
|
|
3166
|
+
static {
|
|
3167
|
+
__name(this, "RequestTimeoutException");
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* @param message - Optional custom message. Defaults to "Request Timeout".
|
|
3171
|
+
*/
|
|
3172
|
+
constructor(message = "Request Timeout") {
|
|
3173
|
+
super(message);
|
|
3174
|
+
this.status = HttpStatusCodes.REQUEST_TIMEOUT;
|
|
3175
|
+
}
|
|
3176
|
+
};
|
|
3177
|
+
var UnsupportedMediaTypeException = class extends ErrorResponse {
|
|
3178
|
+
static {
|
|
3179
|
+
__name(this, "UnsupportedMediaTypeException");
|
|
3180
|
+
}
|
|
3181
|
+
/**
|
|
3182
|
+
* @param message - Optional custom message. Defaults to "Unsupported Media Type".
|
|
3183
|
+
*/
|
|
3184
|
+
constructor(message = "Unsupported Media Type") {
|
|
3185
|
+
super(message);
|
|
3186
|
+
this.status = HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE;
|
|
3187
|
+
}
|
|
3188
|
+
};
|
|
3189
|
+
var PayloadTooLargeException = class extends ErrorResponse {
|
|
3190
|
+
static {
|
|
3191
|
+
__name(this, "PayloadTooLargeException");
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* @param message - Optional custom message. Defaults to "Payload Too Large".
|
|
3195
|
+
*/
|
|
3196
|
+
constructor(message = "Payload Too Large") {
|
|
3197
|
+
super(message);
|
|
3198
|
+
this.status = HttpStatusCodes.PAYLOAD_TOO_LARGE;
|
|
3199
|
+
}
|
|
3200
|
+
};
|
|
3201
|
+
var InsufficientStorageException = class extends ErrorResponse {
|
|
3202
|
+
static {
|
|
3203
|
+
__name(this, "InsufficientStorageException");
|
|
3204
|
+
}
|
|
3205
|
+
/**
|
|
3206
|
+
* @param message - Optional custom message. Defaults to "Insufficient Storage".
|
|
3207
|
+
*/
|
|
3208
|
+
constructor(message = "Insufficient Storage") {
|
|
3209
|
+
super(message);
|
|
3210
|
+
this.status = HttpStatusCodes.INSUFFICIENT_STORAGE;
|
|
3211
|
+
}
|
|
3212
|
+
};
|
|
3213
|
+
function isHttpError(error) {
|
|
3214
|
+
return error instanceof ErrorResponse;
|
|
2965
3215
|
}
|
|
2966
|
-
__name(
|
|
2967
|
-
function
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
3216
|
+
__name(isHttpError, "isHttpError");
|
|
3217
|
+
function createHttpError(status, message) {
|
|
3218
|
+
switch (status) {
|
|
3219
|
+
case HttpStatusCodes.BAD_REQUEST:
|
|
3220
|
+
return new BadRequestException(message);
|
|
3221
|
+
case HttpStatusCodes.UNAUTHORIZED:
|
|
3222
|
+
return new UnauthorizedException(message);
|
|
3223
|
+
case HttpStatusCodes.FORBIDDEN:
|
|
3224
|
+
return new ForbiddenException(message);
|
|
3225
|
+
case HttpStatusCodes.NOT_FOUND:
|
|
3226
|
+
return new NotFoundException(message);
|
|
3227
|
+
case HttpStatusCodes.METHOD_NOT_ALLOWED:
|
|
3228
|
+
return new MethodNotAllowedException(message);
|
|
3229
|
+
case HttpStatusCodes.NOT_ACCEPTABLE:
|
|
3230
|
+
return new NotAcceptableException(message);
|
|
3231
|
+
case HttpStatusCodes.REQUEST_TIMEOUT:
|
|
3232
|
+
return new RequestTimeoutException(message);
|
|
3233
|
+
case HttpStatusCodes.CONFLICT:
|
|
3234
|
+
return new ConflictException(message);
|
|
3235
|
+
case HttpStatusCodes.GONE:
|
|
3236
|
+
return new HttpError(HttpStatusCodes.GONE, message || "Gone");
|
|
3237
|
+
case HttpStatusCodes.PAYLOAD_TOO_LARGE:
|
|
3238
|
+
return new PayloadTooLargeException(message);
|
|
3239
|
+
case HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE:
|
|
3240
|
+
return new UnsupportedMediaTypeException(message);
|
|
3241
|
+
case HttpStatusCodes.UNPROCESSABLE_ENTITY:
|
|
3242
|
+
return new UnprocessableEntityException(message);
|
|
3243
|
+
case HttpStatusCodes.TOO_MANY_REQUESTS:
|
|
3244
|
+
return new TooManyRequestsException(message);
|
|
3245
|
+
case HttpStatusCodes.INTERNAL_SERVER_ERROR:
|
|
3246
|
+
return new InternalServerErrorException(message);
|
|
3247
|
+
case HttpStatusCodes.BAD_GATEWAY:
|
|
3248
|
+
return new BadGatewayException(message);
|
|
3249
|
+
case HttpStatusCodes.SERVICE_UNAVAILABLE:
|
|
3250
|
+
return new ServiceUnavailableException(message);
|
|
3251
|
+
case HttpStatusCodes.GATEWAY_TIMEOUT:
|
|
3252
|
+
return new GatewayTimeoutException(message);
|
|
3253
|
+
case HttpStatusCodes.INSUFFICIENT_STORAGE:
|
|
3254
|
+
return new InsufficientStorageException(message);
|
|
3255
|
+
default:
|
|
3256
|
+
return new HttpError(status, message || `HTTP Error ${status}`);
|
|
3257
|
+
}
|
|
2973
3258
|
}
|
|
2974
|
-
__name(
|
|
2975
|
-
function
|
|
2976
|
-
return
|
|
2977
|
-
const hooks = Reflect.getMetadata(AFTER_KEY, target, propertyKey) || [];
|
|
2978
|
-
hooks.push(fn);
|
|
2979
|
-
Reflect.defineMetadata(AFTER_KEY, hooks, target, propertyKey);
|
|
2980
|
-
};
|
|
3259
|
+
__name(createHttpError, "createHttpError");
|
|
3260
|
+
function hasErrorShape(error) {
|
|
3261
|
+
return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
|
|
2981
3262
|
}
|
|
2982
|
-
__name(
|
|
2983
|
-
function
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
3263
|
+
__name(hasErrorShape, "hasErrorShape");
|
|
3264
|
+
function getErrorMessage(error) {
|
|
3265
|
+
if (typeof error === "string") {
|
|
3266
|
+
return error;
|
|
3267
|
+
}
|
|
3268
|
+
if (error instanceof Error) {
|
|
3269
|
+
return error.message;
|
|
3270
|
+
}
|
|
3271
|
+
if (hasErrorShape(error)) {
|
|
3272
|
+
return error.message;
|
|
3273
|
+
}
|
|
3274
|
+
return "Unknown error occurred";
|
|
3275
|
+
}
|
|
3276
|
+
__name(getErrorMessage, "getErrorMessage");
|
|
3277
|
+
function withErrorHandling(handler) {
|
|
3278
|
+
return async (...args) => {
|
|
3279
|
+
try {
|
|
3280
|
+
return await handler(...args);
|
|
3281
|
+
} catch (err) {
|
|
3282
|
+
if (isHttpError(err)) {
|
|
3283
|
+
throw err;
|
|
3284
|
+
}
|
|
3285
|
+
getLogger().error({
|
|
3286
|
+
err
|
|
3287
|
+
}, "Caught error in handler");
|
|
3288
|
+
let status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
|
|
3289
|
+
if (hasErrorShape(err) && typeof err.status === "number") {
|
|
3290
|
+
status = err.status;
|
|
3291
|
+
}
|
|
3292
|
+
throw createHttpError(status, getErrorMessage(err));
|
|
2989
3293
|
}
|
|
2990
3294
|
};
|
|
2991
3295
|
}
|
|
2992
|
-
__name(
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
}, target, propertyKey);
|
|
3037
|
-
};
|
|
3038
|
-
}
|
|
3039
|
-
__name(ContentType, "ContentType");
|
|
3040
|
-
function Version(version, options) {
|
|
3041
|
-
const opts = {
|
|
3042
|
-
addPrefix: true,
|
|
3043
|
-
addHeader: true,
|
|
3044
|
-
headerName: "X-API-Version",
|
|
3045
|
-
...options
|
|
3046
|
-
};
|
|
3047
|
-
return (target, propertyKey, _descriptor) => {
|
|
3048
|
-
if (typeof propertyKey === "undefined") {
|
|
3049
|
-
Reflect.defineMetadata(VERSION_KEY, {
|
|
3050
|
-
version,
|
|
3051
|
-
options: opts
|
|
3052
|
-
}, target);
|
|
3053
|
-
} else {
|
|
3054
|
-
Reflect.defineMetadata(VERSION_KEY, {
|
|
3055
|
-
version,
|
|
3056
|
-
options: opts
|
|
3057
|
-
}, target, propertyKey);
|
|
3058
|
-
}
|
|
3059
|
-
};
|
|
3060
|
-
}
|
|
3061
|
-
__name(Version, "Version");
|
|
3062
|
-
function Timeout(ms) {
|
|
3063
|
-
return (target, propertyKey, _descriptor) => {
|
|
3064
|
-
if (typeof propertyKey === "undefined") {
|
|
3065
|
-
Reflect.defineMetadata(TIMEOUT_KEY, {
|
|
3066
|
-
ms
|
|
3067
|
-
}, target);
|
|
3068
|
-
} else {
|
|
3069
|
-
Reflect.defineMetadata(TIMEOUT_KEY, {
|
|
3070
|
-
ms
|
|
3071
|
-
}, target, propertyKey);
|
|
3072
|
-
}
|
|
3073
|
-
};
|
|
3074
|
-
}
|
|
3075
|
-
__name(Timeout, "Timeout");
|
|
3076
|
-
function Log(options) {
|
|
3077
|
-
return (target, propertyKey, _descriptor) => {
|
|
3078
|
-
const config2 = {
|
|
3079
|
-
logEntry: true,
|
|
3080
|
-
logExit: true,
|
|
3081
|
-
logBody: false,
|
|
3082
|
-
logParams: false,
|
|
3083
|
-
logResponse: false,
|
|
3084
|
-
...options
|
|
3085
|
-
};
|
|
3086
|
-
if (typeof propertyKey === "undefined") {
|
|
3087
|
-
Reflect.defineMetadata(LOG_KEY, config2, target);
|
|
3088
|
-
} else {
|
|
3089
|
-
Reflect.defineMetadata(LOG_KEY, config2, target, propertyKey);
|
|
3090
|
-
}
|
|
3091
|
-
};
|
|
3092
|
-
}
|
|
3093
|
-
__name(Log, "Log");
|
|
3094
|
-
function registerControllers(router, controllers) {
|
|
3095
|
-
controllers.forEach((ControllerClass) => {
|
|
3096
|
-
const instance = diContainer.get(ControllerClass);
|
|
3097
|
-
const basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
|
|
3098
|
-
const routes = Reflect.getMetadata(ROUTES_KEY, ControllerClass) || [];
|
|
3099
|
-
const controllerRateLimit = Reflect.getMetadata(RATE_LIMIT_KEY, ControllerClass);
|
|
3100
|
-
const controllerCache = Reflect.getMetadata(CACHE_KEY, ControllerClass);
|
|
3101
|
-
const controllerTimeout = Reflect.getMetadata(TIMEOUT_KEY, ControllerClass);
|
|
3102
|
-
const controllerVersion = Reflect.getMetadata(VERSION_KEY, ControllerClass);
|
|
3103
|
-
const controllerRoles = Reflect.getMetadata(ROLES_KEY, ControllerClass);
|
|
3104
|
-
const controllerLogConfig = Reflect.getMetadata(LOG_KEY, ControllerClass);
|
|
3105
|
-
const controllerHeaders = Reflect.getMetadata(HEADER_KEY, ControllerClass) || {};
|
|
3106
|
-
routes.forEach(({ path: path3, method, handlerName }) => {
|
|
3107
|
-
const middlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
|
|
3108
|
-
const params = Reflect.getMetadata(PARAMS_KEY, instance, handlerName) || [];
|
|
3109
|
-
const httpCode = Reflect.getMetadata(HTTP_CODE_KEY, instance, handlerName);
|
|
3110
|
-
const methodHeaders = Reflect.getMetadata(HEADER_KEY, instance, handlerName) || {};
|
|
3111
|
-
const headers = {
|
|
3112
|
-
...controllerHeaders,
|
|
3113
|
-
...methodHeaders
|
|
3114
|
-
};
|
|
3115
|
-
const beforeHooks = Reflect.getMetadata(BEFORE_KEY, instance, handlerName) || [];
|
|
3116
|
-
const afterHooks = Reflect.getMetadata(AFTER_KEY, instance, handlerName) || [];
|
|
3117
|
-
const redirect = Reflect.getMetadata(REDIRECT_KEY, instance, handlerName);
|
|
3118
|
-
const contentType = Reflect.getMetadata(CONTENT_TYPE_KEY, instance, handlerName);
|
|
3119
|
-
const roles = Reflect.getMetadata(ROLES_KEY, instance, handlerName) || controllerRoles || [];
|
|
3120
|
-
const cache = Reflect.getMetadata(CACHE_KEY, instance, handlerName) || controllerCache;
|
|
3121
|
-
const rateLimitOptions = Reflect.getMetadata(RATE_LIMIT_KEY, instance, handlerName) || controllerRateLimit;
|
|
3122
|
-
const version = Reflect.getMetadata(VERSION_KEY, instance, handlerName) || controllerVersion;
|
|
3123
|
-
const timeout2 = Reflect.getMetadata(TIMEOUT_KEY, instance, handlerName) || controllerTimeout;
|
|
3124
|
-
const logConfig = Reflect.getMetadata(LOG_KEY, instance, handlerName) || controllerLogConfig;
|
|
3125
|
-
let rateLimiter = null;
|
|
3126
|
-
if (rateLimitOptions) {
|
|
3127
|
-
try {
|
|
3128
|
-
rateLimiter = rateLimiterCache.get(rateLimitOptions);
|
|
3129
|
-
} catch (err) {
|
|
3130
|
-
getLogger().warn({
|
|
3131
|
-
err
|
|
3132
|
-
}, "express-rate-limit not available, skipping rate limiting for this route");
|
|
3133
|
-
}
|
|
3134
|
-
}
|
|
3135
|
-
let finalPath = path3;
|
|
3136
|
-
if (version?.options?.addPrefix) {
|
|
3137
|
-
finalPath = `/${version.version}${path3}`;
|
|
3138
|
-
}
|
|
3139
|
-
const handler = /* @__PURE__ */ __name(async (req, res, next) => {
|
|
3140
|
-
req["startTime"] = Date.now();
|
|
3141
|
-
let timeoutId;
|
|
3142
|
-
let timedOut = false;
|
|
3143
|
-
try {
|
|
3144
|
-
if (timeout2) {
|
|
3145
|
-
timeoutId = setTimeout(() => {
|
|
3146
|
-
if (!res.headersSent && !timedOut) {
|
|
3147
|
-
timedOut = true;
|
|
3148
|
-
const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.REQUEST_TIMEOUT, "Request timed out");
|
|
3149
|
-
res.status(HttpStatusCodes.REQUEST_TIMEOUT).json(errorResponse);
|
|
3150
|
-
}
|
|
3151
|
-
}, timeout2.ms);
|
|
3152
|
-
}
|
|
3153
|
-
if (timedOut) return;
|
|
3154
|
-
if (rateLimiter) {
|
|
3155
|
-
await new Promise((resolve2, reject) => {
|
|
3156
|
-
rateLimiter(req, res, (err) => {
|
|
3157
|
-
if (err) reject(err);
|
|
3158
|
-
else resolve2();
|
|
3159
|
-
});
|
|
3160
|
-
});
|
|
3161
|
-
}
|
|
3162
|
-
if (!res.headersSent && contentType) {
|
|
3163
|
-
res.setHeader("Content-Type", contentType.type);
|
|
3164
|
-
}
|
|
3165
|
-
if (version?.options?.addHeader && version?.options?.headerName && version?.version) {
|
|
3166
|
-
if (!res.headersSent) {
|
|
3167
|
-
res.setHeader(version.options.headerName, version.version);
|
|
3168
|
-
}
|
|
3169
|
-
}
|
|
3170
|
-
if (cache && !res.headersSent) {
|
|
3171
|
-
res.setHeader("Cache-Control", `public, max-age=${cache.ttlSeconds}`);
|
|
3172
|
-
}
|
|
3173
|
-
if (logConfig?.logEntry) {
|
|
3174
|
-
const logger2 = getLogger();
|
|
3175
|
-
const logData = {
|
|
3176
|
-
method: req.method,
|
|
3177
|
-
url: req.originalUrl || req.url,
|
|
3178
|
-
userAgent: req.get("User-Agent")
|
|
3179
|
-
};
|
|
3180
|
-
if (logConfig.logParams) {
|
|
3181
|
-
logData.params = req.params;
|
|
3182
|
-
logData.query = req.query;
|
|
3183
|
-
}
|
|
3184
|
-
if (logConfig.logBody) logData.body = req.body;
|
|
3185
|
-
logger2.info({
|
|
3186
|
-
entry: logData
|
|
3187
|
-
}, "Route Entry:");
|
|
3188
|
-
}
|
|
3189
|
-
if (roles.length && !req?.user?.roles?.some((role) => roles.includes(role))) {
|
|
3190
|
-
const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.FORBIDDEN, "Forbidden Insufficient Roles");
|
|
3191
|
-
res.status(HttpStatusCodes.FORBIDDEN).json(errorResponse);
|
|
3192
|
-
if (timeoutId) {
|
|
3193
|
-
clearTimeout(timeoutId);
|
|
3194
|
-
}
|
|
3195
|
-
return;
|
|
3196
|
-
}
|
|
3197
|
-
if (redirect && redirect.url) {
|
|
3198
|
-
if (timeoutId) {
|
|
3199
|
-
clearTimeout(timeoutId);
|
|
3200
|
-
}
|
|
3201
|
-
return res.redirect(redirect.statusCode, redirect.url);
|
|
3202
|
-
}
|
|
3203
|
-
for (const fn of beforeHooks) await fn(req, res);
|
|
3204
|
-
const args = [];
|
|
3205
|
-
if (params.length) {
|
|
3206
|
-
params.forEach(({ index, type, key }) => {
|
|
3207
|
-
switch (type) {
|
|
3208
|
-
case "query":
|
|
3209
|
-
args[index] = key ? req.query[key] : req.query;
|
|
3210
|
-
break;
|
|
3211
|
-
case "param":
|
|
3212
|
-
args[index] = key ? req.params[key] : req.params;
|
|
3213
|
-
break;
|
|
3214
|
-
case "body":
|
|
3215
|
-
args[index] = key ? req.body?.[key] : req.body;
|
|
3216
|
-
break;
|
|
3217
|
-
case "req":
|
|
3218
|
-
args[index] = req;
|
|
3219
|
-
break;
|
|
3220
|
-
case "res":
|
|
3221
|
-
args[index] = res;
|
|
3222
|
-
break;
|
|
3223
|
-
}
|
|
3224
|
-
});
|
|
3225
|
-
}
|
|
3226
|
-
const result = instance[handlerName](...args);
|
|
3227
|
-
const awaited = result instanceof Promise ? await result : result;
|
|
3228
|
-
if (timeoutId) {
|
|
3229
|
-
clearTimeout(timeoutId);
|
|
3230
|
-
}
|
|
3231
|
-
if (timedOut) return;
|
|
3232
|
-
if (redirect && awaited && typeof awaited === "object" && "url" in awaited) {
|
|
3233
|
-
const redirectUrl = awaited.url;
|
|
3234
|
-
const redirectStatus = awaited.statusCode || redirect.statusCode;
|
|
3235
|
-
return res.redirect(redirectStatus, redirectUrl);
|
|
3236
|
-
}
|
|
3237
|
-
if (!res.headersSent && typeof awaited !== "undefined") {
|
|
3238
|
-
if (httpCode) res.status(httpCode);
|
|
3239
|
-
for (const [k, v] of Object.entries(headers)) {
|
|
3240
|
-
const normalized = normalizeHeaderValue(v);
|
|
3241
|
-
if (typeof normalized !== "undefined") {
|
|
3242
|
-
res.set(k, normalized);
|
|
3243
|
-
}
|
|
3244
|
-
}
|
|
3245
|
-
res.json(awaited);
|
|
3246
|
-
}
|
|
3247
|
-
if (logConfig?.logExit) {
|
|
3248
|
-
const logger2 = getLogger();
|
|
3249
|
-
const logData = {
|
|
3250
|
-
method: req.method,
|
|
3251
|
-
url: req.originalUrl || req.url,
|
|
3252
|
-
statusCode: res.statusCode,
|
|
3253
|
-
duration: `${Date.now() - req.startTime}ms`
|
|
3254
|
-
};
|
|
3255
|
-
if (logConfig.logResponse) logData.response = awaited;
|
|
3256
|
-
logger2.info({
|
|
3257
|
-
exit: logData
|
|
3258
|
-
}, "Route Exit:");
|
|
3259
|
-
}
|
|
3260
|
-
for (const fn of afterHooks) await fn(req, res, awaited);
|
|
3261
|
-
} catch (err) {
|
|
3262
|
-
if (timeoutId) {
|
|
3263
|
-
clearTimeout(timeoutId);
|
|
3264
|
-
}
|
|
3265
|
-
next(err);
|
|
3266
|
-
}
|
|
3267
|
-
}, "handler");
|
|
3268
|
-
router[method](basePath + finalPath, ...middlewares, handler);
|
|
3296
|
+
__name(withErrorHandling, "withErrorHandling");
|
|
3297
|
+
|
|
3298
|
+
// src/utils/decorators.utils.ts
|
|
3299
|
+
var ROUTES_KEY = Symbol("routes");
|
|
3300
|
+
var MIDDLEWARE_KEY = Symbol("middlewares");
|
|
3301
|
+
var PARAMS_KEY = Symbol("params");
|
|
3302
|
+
var HTTP_CODE_KEY = Symbol("httpCode");
|
|
3303
|
+
var HEADER_KEY = Symbol("headers");
|
|
3304
|
+
var BEFORE_KEY = Symbol("before");
|
|
3305
|
+
var AFTER_KEY = Symbol("after");
|
|
3306
|
+
var ROLES_KEY = Symbol("roles");
|
|
3307
|
+
var REDIRECT_KEY = Symbol("redirect");
|
|
3308
|
+
var CACHE_KEY = Symbol("cache");
|
|
3309
|
+
var RATE_LIMIT_KEY = Symbol("rateLimit");
|
|
3310
|
+
var CONTENT_TYPE_KEY = Symbol("contentType");
|
|
3311
|
+
var VERSION_KEY = Symbol("version");
|
|
3312
|
+
var TIMEOUT_KEY = Symbol("timeout");
|
|
3313
|
+
var LOG_KEY = Symbol("log");
|
|
3314
|
+
var RateLimiterCache = class RateLimiterCache2 {
|
|
3315
|
+
static {
|
|
3316
|
+
__name(this, "RateLimiterCache");
|
|
3317
|
+
}
|
|
3318
|
+
cache;
|
|
3319
|
+
constructor(maxSize = 100, ttlMs = 5 * 60 * 1e3) {
|
|
3320
|
+
this.cache = new TTLCache({
|
|
3321
|
+
maxSize,
|
|
3322
|
+
ttlMs
|
|
3323
|
+
});
|
|
3324
|
+
}
|
|
3325
|
+
generateKey(options) {
|
|
3326
|
+
return `${options.max}:${options.windowMs}:${options.standardHeaders}:${options.legacyHeaders}`;
|
|
3327
|
+
}
|
|
3328
|
+
get(options) {
|
|
3329
|
+
const key = this.generateKey(options);
|
|
3330
|
+
const cached = this.cache.get(key);
|
|
3331
|
+
if (cached) {
|
|
3332
|
+
return cached.limiter;
|
|
3333
|
+
}
|
|
3334
|
+
const limiter = expressRateLimit.rateLimit({
|
|
3335
|
+
...options,
|
|
3336
|
+
handler: /* @__PURE__ */ __name((req, res) => {
|
|
3337
|
+
const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.TOO_MANY_REQUESTS, "Too Many Requests");
|
|
3338
|
+
res.status(HttpStatusCodes.TOO_MANY_REQUESTS).json(errorResponse);
|
|
3339
|
+
}, "handler")
|
|
3269
3340
|
});
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3341
|
+
this.cache.set(key, {
|
|
3342
|
+
limiter,
|
|
3343
|
+
config: key
|
|
3344
|
+
});
|
|
3345
|
+
return limiter;
|
|
3346
|
+
}
|
|
3347
|
+
clear() {
|
|
3348
|
+
this.cache.clear();
|
|
3349
|
+
}
|
|
3350
|
+
size() {
|
|
3351
|
+
return this.cache.size();
|
|
3352
|
+
}
|
|
3353
|
+
destroy() {
|
|
3354
|
+
this.cache.destroy();
|
|
3355
|
+
}
|
|
3356
|
+
};
|
|
3357
|
+
var rateLimiterCache = new RateLimiterCache();
|
|
3358
|
+
var DIContainer = class {
|
|
3359
|
+
static {
|
|
3360
|
+
__name(this, "DIContainer");
|
|
3361
|
+
}
|
|
3362
|
+
instances = /* @__PURE__ */ new Map();
|
|
3363
|
+
constructing = /* @__PURE__ */ new Map();
|
|
3364
|
+
propertyInjections = /* @__PURE__ */ new Map();
|
|
3365
|
+
register(target) {
|
|
3366
|
+
if (!this.instances.has(target) && !this.constructing.has(target)) ;
|
|
3367
|
+
}
|
|
3368
|
+
/**
|
|
3369
|
+
* Register a property injection to be resolved when the target class is instantiated
|
|
3370
|
+
*/
|
|
3371
|
+
registerPropertyInjection(target, propertyKey, injectClass) {
|
|
3372
|
+
const targetClass = target.constructor;
|
|
3373
|
+
if (!this.propertyInjections.has(targetClass)) {
|
|
3374
|
+
this.propertyInjections.set(targetClass, []);
|
|
3291
3375
|
}
|
|
3376
|
+
this.propertyInjections.get(targetClass).push({
|
|
3377
|
+
targetClass: injectClass,
|
|
3378
|
+
propertyKey
|
|
3379
|
+
});
|
|
3292
3380
|
}
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3381
|
+
get(target) {
|
|
3382
|
+
if (this.instances.has(target)) {
|
|
3383
|
+
return this.instances.get(target);
|
|
3384
|
+
}
|
|
3385
|
+
if (this.constructing.has(target)) {
|
|
3386
|
+
return this.constructing.get(target);
|
|
3387
|
+
}
|
|
3388
|
+
let proxy = {};
|
|
3389
|
+
this.constructing.set(target, proxy);
|
|
3390
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
3391
|
+
const dependencies = paramTypes.map((dep) => this.get(dep));
|
|
3392
|
+
const instance = new target(...dependencies);
|
|
3393
|
+
this.applyPropertyInjections(target, instance);
|
|
3394
|
+
Object.assign(proxy, instance);
|
|
3395
|
+
this.instances.set(target, proxy);
|
|
3396
|
+
this.constructing.delete(target);
|
|
3397
|
+
Object.setPrototypeOf(proxy, target.prototype);
|
|
3398
|
+
return proxy;
|
|
3309
3399
|
}
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
withFileTypes: true
|
|
3316
|
-
});
|
|
3317
|
-
for (const entry of entries) {
|
|
3318
|
-
const srcPath = path__default.default.join(src, entry.name);
|
|
3319
|
-
const destPath = path__default.default.join(dest, entry.name);
|
|
3320
|
-
if (entry.isDirectory()) {
|
|
3321
|
-
await copyDir(srcPath, destPath);
|
|
3322
|
-
} else {
|
|
3323
|
-
await fsp__default.default.copyFile(srcPath, destPath);
|
|
3400
|
+
applyPropertyInjections(targetClass, instance) {
|
|
3401
|
+
const injections = this.propertyInjections.get(targetClass) || [];
|
|
3402
|
+
for (const injection of injections) {
|
|
3403
|
+
const dependency = this.get(injection.targetClass);
|
|
3404
|
+
instance[injection.propertyKey] = dependency;
|
|
3324
3405
|
}
|
|
3325
3406
|
}
|
|
3407
|
+
clear() {
|
|
3408
|
+
this.instances.clear();
|
|
3409
|
+
this.constructing.clear();
|
|
3410
|
+
this.propertyInjections.clear();
|
|
3411
|
+
}
|
|
3412
|
+
};
|
|
3413
|
+
var diContainer = new DIContainer();
|
|
3414
|
+
function normalizeHeaderValue(value) {
|
|
3415
|
+
if (typeof value === "undefined") return void 0;
|
|
3416
|
+
if (typeof value === "string") return value;
|
|
3417
|
+
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
|
|
3418
|
+
return value;
|
|
3419
|
+
}
|
|
3420
|
+
return String(value);
|
|
3326
3421
|
}
|
|
3327
|
-
__name(
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3422
|
+
__name(normalizeHeaderValue, "normalizeHeaderValue");
|
|
3423
|
+
function Injectable() {
|
|
3424
|
+
return (target) => {
|
|
3425
|
+
Reflect.defineMetadata("injectable", true, target);
|
|
3426
|
+
diContainer.register(target);
|
|
3427
|
+
};
|
|
3331
3428
|
}
|
|
3332
|
-
__name(
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3429
|
+
__name(Injectable, "Injectable");
|
|
3430
|
+
function Inject(targetClass) {
|
|
3431
|
+
return (target, propertyKey) => {
|
|
3432
|
+
diContainer.registerPropertyInjection(target, propertyKey, targetClass);
|
|
3433
|
+
Object.defineProperty(target, propertyKey, {
|
|
3434
|
+
configurable: true,
|
|
3435
|
+
get: /* @__PURE__ */ __name(function() {
|
|
3436
|
+
const value = Object.getOwnPropertyDescriptor(this, propertyKey)?.value;
|
|
3437
|
+
if (value !== void 0) return value;
|
|
3438
|
+
const injectedValue = diContainer.get(targetClass);
|
|
3439
|
+
Object.defineProperty(this, propertyKey, {
|
|
3440
|
+
value: injectedValue,
|
|
3441
|
+
writable: true,
|
|
3442
|
+
configurable: true
|
|
3443
|
+
});
|
|
3444
|
+
return injectedValue;
|
|
3445
|
+
}, "get"),
|
|
3446
|
+
set: /* @__PURE__ */ __name(function(value) {
|
|
3447
|
+
Object.defineProperty(this, propertyKey, {
|
|
3448
|
+
value,
|
|
3449
|
+
writable: true,
|
|
3450
|
+
configurable: true
|
|
3451
|
+
});
|
|
3452
|
+
}, "set")
|
|
3453
|
+
});
|
|
3454
|
+
};
|
|
3455
|
+
}
|
|
3456
|
+
__name(Inject, "Inject");
|
|
3457
|
+
function inject(targetClass) {
|
|
3458
|
+
return diContainer.get(targetClass);
|
|
3459
|
+
}
|
|
3460
|
+
__name(inject, "inject");
|
|
3461
|
+
function createRouteDecorator(method) {
|
|
3462
|
+
return (path3) => {
|
|
3463
|
+
return (target, propertyKey, _descriptor) => {
|
|
3464
|
+
const routes = Reflect.getMetadata(ROUTES_KEY, target.constructor) || [];
|
|
3465
|
+
routes.push({
|
|
3466
|
+
path: path3,
|
|
3467
|
+
method,
|
|
3468
|
+
handlerName: propertyKey
|
|
3343
3469
|
});
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
}
|
|
3470
|
+
Reflect.defineMetadata(ROUTES_KEY, routes, target.constructor);
|
|
3471
|
+
};
|
|
3472
|
+
};
|
|
3348
3473
|
}
|
|
3349
|
-
__name(
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3474
|
+
__name(createRouteDecorator, "createRouteDecorator");
|
|
3475
|
+
var Get = createRouteDecorator("get");
|
|
3476
|
+
var Post = createRouteDecorator("post");
|
|
3477
|
+
var Put = createRouteDecorator("put");
|
|
3478
|
+
var Patch = createRouteDecorator("patch");
|
|
3479
|
+
var Delete = createRouteDecorator("delete");
|
|
3480
|
+
var Options = createRouteDecorator("options");
|
|
3481
|
+
var Head = createRouteDecorator("head");
|
|
3482
|
+
var Trace = createRouteDecorator("trace");
|
|
3483
|
+
var Connect = createRouteDecorator("connect");
|
|
3484
|
+
function Controller(basePath) {
|
|
3485
|
+
return (target) => {
|
|
3486
|
+
Reflect.defineMetadata("basePath", basePath, target);
|
|
3487
|
+
};
|
|
3488
|
+
}
|
|
3489
|
+
__name(Controller, "Controller");
|
|
3490
|
+
function Use(...middlewares) {
|
|
3491
|
+
return (target, propertyKey, _descriptor) => {
|
|
3492
|
+
if (typeof propertyKey === "undefined") {
|
|
3493
|
+
const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target) || [];
|
|
3494
|
+
Reflect.defineMetadata(MIDDLEWARE_KEY, [
|
|
3495
|
+
...existing,
|
|
3496
|
+
...middlewares
|
|
3497
|
+
], target);
|
|
3359
3498
|
} else {
|
|
3360
|
-
const
|
|
3361
|
-
|
|
3499
|
+
const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target, propertyKey) || [];
|
|
3500
|
+
Reflect.defineMetadata(MIDDLEWARE_KEY, [
|
|
3501
|
+
...existing,
|
|
3502
|
+
...middlewares
|
|
3503
|
+
], target, propertyKey);
|
|
3362
3504
|
}
|
|
3363
|
-
}
|
|
3364
|
-
return total;
|
|
3505
|
+
};
|
|
3365
3506
|
}
|
|
3366
|
-
__name(
|
|
3367
|
-
function
|
|
3368
|
-
const
|
|
3369
|
-
|
|
3507
|
+
__name(Use, "Use");
|
|
3508
|
+
function defineParamMetadata(target, propertyKey, parameterIndex, type, key) {
|
|
3509
|
+
const params = Reflect.getMetadata(PARAMS_KEY, target, propertyKey) || [];
|
|
3510
|
+
params.push({
|
|
3511
|
+
index: parameterIndex,
|
|
3512
|
+
type,
|
|
3513
|
+
key
|
|
3370
3514
|
});
|
|
3371
|
-
|
|
3515
|
+
params.sort((a, b) => a.index - b.index);
|
|
3516
|
+
Reflect.defineMetadata(PARAMS_KEY, params, target, propertyKey);
|
|
3372
3517
|
}
|
|
3373
|
-
__name(
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
if (
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3518
|
+
__name(defineParamMetadata, "defineParamMetadata");
|
|
3519
|
+
function createParamDecorator(type, key) {
|
|
3520
|
+
return (paramKey) => {
|
|
3521
|
+
return (target, propertyKey, parameterIndex) => {
|
|
3522
|
+
defineParamMetadata(target, propertyKey, parameterIndex, type, paramKey ?? key);
|
|
3523
|
+
};
|
|
3524
|
+
};
|
|
3525
|
+
}
|
|
3526
|
+
__name(createParamDecorator, "createParamDecorator");
|
|
3527
|
+
function createParamDecoratorWithoutParam(type) {
|
|
3528
|
+
return () => {
|
|
3529
|
+
return (target, propertyKey, parameterIndex) => {
|
|
3530
|
+
defineParamMetadata(target, propertyKey, parameterIndex, type, void 0);
|
|
3531
|
+
};
|
|
3532
|
+
};
|
|
3533
|
+
}
|
|
3534
|
+
__name(createParamDecoratorWithoutParam, "createParamDecoratorWithoutParam");
|
|
3535
|
+
function createApiUrlParamDecorator(type, key) {
|
|
3536
|
+
return (paramKey, options) => {
|
|
3537
|
+
return (target, propertyKey, parameterIndex) => {
|
|
3538
|
+
const params = Reflect.getMetadata(PARAMS_KEY, target, propertyKey) || [];
|
|
3539
|
+
let paramOptions = void 0;
|
|
3540
|
+
if (typeof options === "object") {
|
|
3541
|
+
paramOptions = {};
|
|
3542
|
+
paramOptions.type = "string";
|
|
3543
|
+
paramOptions.dataType = "single";
|
|
3544
|
+
paramOptions.delimiter = ",";
|
|
3545
|
+
paramOptions.required = false;
|
|
3546
|
+
paramOptions.throwError = true;
|
|
3547
|
+
paramOptions = {
|
|
3548
|
+
...paramOptions,
|
|
3549
|
+
...options
|
|
3550
|
+
};
|
|
3403
3551
|
}
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3552
|
+
params.push({
|
|
3553
|
+
index: parameterIndex,
|
|
3554
|
+
type,
|
|
3555
|
+
key: paramKey || key,
|
|
3556
|
+
options: paramOptions
|
|
3557
|
+
});
|
|
3558
|
+
params.sort((a, b) => a.index - b.index);
|
|
3559
|
+
Reflect.defineMetadata(PARAMS_KEY, params, target, propertyKey);
|
|
3560
|
+
};
|
|
3561
|
+
};
|
|
3409
3562
|
}
|
|
3410
|
-
__name(
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3563
|
+
__name(createApiUrlParamDecorator, "createApiUrlParamDecorator");
|
|
3564
|
+
var Query = createApiUrlParamDecorator("query");
|
|
3565
|
+
var Param = createApiUrlParamDecorator("param");
|
|
3566
|
+
var Body = createParamDecorator("body");
|
|
3567
|
+
var ReqLogger = createParamDecoratorWithoutParam("logger");
|
|
3568
|
+
var ReqId = createParamDecoratorWithoutParam("reqId");
|
|
3569
|
+
var ReqHeader = createParamDecorator("reqHeader");
|
|
3570
|
+
var ReqCookie = createParamDecorator("cookie");
|
|
3571
|
+
var Req = createParamDecoratorWithoutParam("req");
|
|
3572
|
+
var Res = createParamDecoratorWithoutParam("res");
|
|
3573
|
+
function HttpCode(status) {
|
|
3574
|
+
return (target, propertyKey, _descriptor) => {
|
|
3575
|
+
Reflect.defineMetadata(HTTP_CODE_KEY, status, target, propertyKey);
|
|
3576
|
+
};
|
|
3424
3577
|
}
|
|
3425
|
-
__name(
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3578
|
+
__name(HttpCode, "HttpCode");
|
|
3579
|
+
function Header(name, value) {
|
|
3580
|
+
return Headers(name, value);
|
|
3581
|
+
}
|
|
3582
|
+
__name(Header, "Header");
|
|
3583
|
+
function Headers(headers, value) {
|
|
3584
|
+
return (target, propertyKey) => {
|
|
3585
|
+
if (typeof propertyKey === "undefined") {
|
|
3586
|
+
const existing = Reflect.getMetadata(HEADER_KEY, target) || {};
|
|
3587
|
+
const newHeaders = typeof headers === "string" ? {
|
|
3588
|
+
[headers]: value
|
|
3589
|
+
} : headers;
|
|
3590
|
+
Reflect.defineMetadata(HEADER_KEY, {
|
|
3591
|
+
...existing,
|
|
3592
|
+
...newHeaders
|
|
3593
|
+
}, target);
|
|
3594
|
+
} else {
|
|
3595
|
+
const existing = Reflect.getMetadata(HEADER_KEY, target, propertyKey) || {};
|
|
3596
|
+
const newHeaders = typeof headers === "string" ? {
|
|
3597
|
+
[headers]: value
|
|
3598
|
+
} : headers;
|
|
3599
|
+
Reflect.defineMetadata(HEADER_KEY, {
|
|
3600
|
+
...existing,
|
|
3601
|
+
...newHeaders
|
|
3602
|
+
}, target, propertyKey);
|
|
3436
3603
|
}
|
|
3437
|
-
|
|
3438
|
-
}
|
|
3604
|
+
};
|
|
3439
3605
|
}
|
|
3440
|
-
__name(
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3606
|
+
__name(Headers, "Headers");
|
|
3607
|
+
function Before(fn) {
|
|
3608
|
+
return (target, propertyKey, _descriptor) => {
|
|
3609
|
+
if (typeof propertyKey === "undefined") {
|
|
3610
|
+
const hooks = Reflect.getMetadata(BEFORE_KEY, target) || [];
|
|
3611
|
+
hooks.push(fn);
|
|
3612
|
+
Reflect.defineMetadata(BEFORE_KEY, hooks, target);
|
|
3613
|
+
} else {
|
|
3614
|
+
const hooks = Reflect.getMetadata(BEFORE_KEY, target, propertyKey) || [];
|
|
3615
|
+
hooks.push(fn);
|
|
3616
|
+
Reflect.defineMetadata(BEFORE_KEY, hooks, target, propertyKey);
|
|
3451
3617
|
}
|
|
3452
|
-
}
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
"SIGTERM",
|
|
3466
|
-
"SIGUSR1",
|
|
3467
|
-
"SIGUSR2"
|
|
3468
|
-
];
|
|
3469
|
-
for (const signal of signals) {
|
|
3470
|
-
process.once(signal, () => {
|
|
3471
|
-
cleanup().then(() => process.exit());
|
|
3472
|
-
});
|
|
3618
|
+
};
|
|
3619
|
+
}
|
|
3620
|
+
__name(Before, "Before");
|
|
3621
|
+
function After(fn) {
|
|
3622
|
+
return (target, propertyKey, _descriptor) => {
|
|
3623
|
+
if (typeof propertyKey === "undefined") {
|
|
3624
|
+
const hooks = Reflect.getMetadata(AFTER_KEY, target) || [];
|
|
3625
|
+
hooks.push(fn);
|
|
3626
|
+
Reflect.defineMetadata(AFTER_KEY, hooks, target);
|
|
3627
|
+
} else {
|
|
3628
|
+
const hooks = Reflect.getMetadata(AFTER_KEY, target, propertyKey) || [];
|
|
3629
|
+
hooks.push(fn);
|
|
3630
|
+
Reflect.defineMetadata(AFTER_KEY, hooks, target, propertyKey);
|
|
3473
3631
|
}
|
|
3474
|
-
}
|
|
3475
|
-
return {
|
|
3476
|
-
path: tempDirPath,
|
|
3477
|
-
cleanup
|
|
3478
3632
|
};
|
|
3479
3633
|
}
|
|
3480
|
-
__name(
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3634
|
+
__name(After, "After");
|
|
3635
|
+
function Roles(...roles) {
|
|
3636
|
+
return (target, propertyKey, _descriptor) => {
|
|
3637
|
+
if (typeof propertyKey === "undefined") {
|
|
3638
|
+
Reflect.defineMetadata(ROLES_KEY, roles, target);
|
|
3639
|
+
} else {
|
|
3640
|
+
Reflect.defineMetadata(ROLES_KEY, roles, target, propertyKey);
|
|
3641
|
+
}
|
|
3642
|
+
};
|
|
3489
3643
|
}
|
|
3490
|
-
__name(
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3644
|
+
__name(Roles, "Roles");
|
|
3645
|
+
function Redirect(url, statusCode = 302) {
|
|
3646
|
+
return (target, propertyKey, descriptor) => {
|
|
3647
|
+
Reflect.defineMetadata(REDIRECT_KEY, {
|
|
3648
|
+
url,
|
|
3649
|
+
statusCode
|
|
3650
|
+
}, target, propertyKey);
|
|
3651
|
+
return descriptor;
|
|
3652
|
+
};
|
|
3499
3653
|
}
|
|
3500
|
-
__name(
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3654
|
+
__name(Redirect, "Redirect");
|
|
3655
|
+
function Cache(ttlSeconds) {
|
|
3656
|
+
return (target, propertyKey, _descriptor) => {
|
|
3657
|
+
if (typeof propertyKey === "undefined") {
|
|
3658
|
+
Reflect.defineMetadata(CACHE_KEY, {
|
|
3659
|
+
ttlSeconds
|
|
3660
|
+
}, target);
|
|
3661
|
+
} else {
|
|
3662
|
+
Reflect.defineMetadata(CACHE_KEY, {
|
|
3663
|
+
ttlSeconds
|
|
3664
|
+
}, target, propertyKey);
|
|
3511
3665
|
}
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3666
|
+
};
|
|
3667
|
+
}
|
|
3668
|
+
__name(Cache, "Cache");
|
|
3669
|
+
function RateLimit(options) {
|
|
3670
|
+
const opts = {
|
|
3671
|
+
standardHeaders: true,
|
|
3672
|
+
legacyHeaders: false,
|
|
3673
|
+
...options
|
|
3674
|
+
};
|
|
3675
|
+
return (target, propertyKey, _descriptor) => {
|
|
3676
|
+
if (typeof propertyKey === "undefined") {
|
|
3677
|
+
Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target);
|
|
3678
|
+
} else {
|
|
3679
|
+
Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target, propertyKey);
|
|
3515
3680
|
}
|
|
3516
|
-
}
|
|
3517
|
-
return results;
|
|
3681
|
+
};
|
|
3518
3682
|
}
|
|
3519
|
-
__name(
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
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 {
|
|
3683
|
+
__name(RateLimit, "RateLimit");
|
|
3684
|
+
function ContentType(type) {
|
|
3685
|
+
return (target, propertyKey, _descriptor) => {
|
|
3686
|
+
if (typeof propertyKey === "undefined") {
|
|
3687
|
+
Reflect.defineMetadata(CONTENT_TYPE_KEY, {
|
|
3688
|
+
type
|
|
3689
|
+
}, target);
|
|
3690
|
+
} else {
|
|
3691
|
+
Reflect.defineMetadata(CONTENT_TYPE_KEY, {
|
|
3692
|
+
type
|
|
3693
|
+
}, target, propertyKey);
|
|
3543
3694
|
}
|
|
3544
|
-
}
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3695
|
+
};
|
|
3696
|
+
}
|
|
3697
|
+
__name(ContentType, "ContentType");
|
|
3698
|
+
function Version(version, options) {
|
|
3699
|
+
const opts = {
|
|
3700
|
+
addPrefix: true,
|
|
3701
|
+
addHeader: true,
|
|
3702
|
+
headerName: "X-API-Version",
|
|
3703
|
+
...options
|
|
3704
|
+
};
|
|
3705
|
+
return (target, propertyKey, _descriptor) => {
|
|
3706
|
+
if (typeof propertyKey === "undefined") {
|
|
3707
|
+
Reflect.defineMetadata(VERSION_KEY, {
|
|
3708
|
+
version,
|
|
3709
|
+
options: opts
|
|
3710
|
+
}, target);
|
|
3711
|
+
} else {
|
|
3712
|
+
Reflect.defineMetadata(VERSION_KEY, {
|
|
3713
|
+
version,
|
|
3714
|
+
options: opts
|
|
3715
|
+
}, target, propertyKey);
|
|
3550
3716
|
}
|
|
3551
|
-
}
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3717
|
+
};
|
|
3718
|
+
}
|
|
3719
|
+
__name(Version, "Version");
|
|
3720
|
+
function Timeout(ms) {
|
|
3721
|
+
return (target, propertyKey, _descriptor) => {
|
|
3722
|
+
if (typeof propertyKey === "undefined") {
|
|
3723
|
+
Reflect.defineMetadata(TIMEOUT_KEY, {
|
|
3724
|
+
ms
|
|
3725
|
+
}, target);
|
|
3726
|
+
} else {
|
|
3727
|
+
Reflect.defineMetadata(TIMEOUT_KEY, {
|
|
3728
|
+
ms
|
|
3729
|
+
}, target, propertyKey);
|
|
3555
3730
|
}
|
|
3556
3731
|
};
|
|
3557
3732
|
}
|
|
3558
|
-
__name(
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
fileCount++;
|
|
3574
|
-
const stat = await fsp__default.default.stat(entryPath);
|
|
3575
|
-
totalSize += stat.size;
|
|
3576
|
-
}
|
|
3733
|
+
__name(Timeout, "Timeout");
|
|
3734
|
+
function Log(options) {
|
|
3735
|
+
return (target, propertyKey, _descriptor) => {
|
|
3736
|
+
const config2 = {
|
|
3737
|
+
logEntry: true,
|
|
3738
|
+
logExit: true,
|
|
3739
|
+
logBody: false,
|
|
3740
|
+
logParams: false,
|
|
3741
|
+
logResponse: false,
|
|
3742
|
+
...options
|
|
3743
|
+
};
|
|
3744
|
+
if (typeof propertyKey === "undefined") {
|
|
3745
|
+
Reflect.defineMetadata(LOG_KEY, config2, target);
|
|
3746
|
+
} else {
|
|
3747
|
+
Reflect.defineMetadata(LOG_KEY, config2, target, propertyKey);
|
|
3577
3748
|
}
|
|
3578
|
-
}
|
|
3579
|
-
__name(processDir, "processDir");
|
|
3580
|
-
await processDir(dirPath);
|
|
3581
|
-
return {
|
|
3582
|
-
fileCount,
|
|
3583
|
-
dirCount,
|
|
3584
|
-
totalSize
|
|
3585
3749
|
};
|
|
3586
3750
|
}
|
|
3587
|
-
__name(
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3751
|
+
__name(Log, "Log");
|
|
3752
|
+
function registerControllers(router, controllers) {
|
|
3753
|
+
controllers.forEach((ControllerClass) => {
|
|
3754
|
+
if (!Reflect.getMetadata("injectable", ControllerClass)) {
|
|
3755
|
+
Reflect.defineMetadata("injectable", true, ControllerClass);
|
|
3756
|
+
diContainer.register(ControllerClass);
|
|
3757
|
+
}
|
|
3758
|
+
const instance = diContainer.get(ControllerClass);
|
|
3759
|
+
let basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
|
|
3760
|
+
const routes = Reflect.getMetadata(ROUTES_KEY, ControllerClass) || [];
|
|
3761
|
+
const controllerRateLimit = Reflect.getMetadata(RATE_LIMIT_KEY, ControllerClass);
|
|
3762
|
+
const controllerCache = Reflect.getMetadata(CACHE_KEY, ControllerClass);
|
|
3763
|
+
const controllerTimeout = Reflect.getMetadata(TIMEOUT_KEY, ControllerClass);
|
|
3764
|
+
const controllerVersion = Reflect.getMetadata(VERSION_KEY, ControllerClass);
|
|
3765
|
+
const controllerRoles = Reflect.getMetadata(ROLES_KEY, ControllerClass);
|
|
3766
|
+
const controllerLogConfig = Reflect.getMetadata(LOG_KEY, ControllerClass);
|
|
3767
|
+
const controllerHeaders = Reflect.getMetadata(HEADER_KEY, ControllerClass) || {};
|
|
3768
|
+
const controllerMiddlewares = Reflect.getMetadata(MIDDLEWARE_KEY, ControllerClass) || [];
|
|
3769
|
+
const controllerBeforeHooks = Reflect.getMetadata(BEFORE_KEY, ControllerClass) || [];
|
|
3770
|
+
const controllerAfterHooks = Reflect.getMetadata(AFTER_KEY, ControllerClass) || [];
|
|
3771
|
+
const controllerContentType = Reflect.getMetadata(CONTENT_TYPE_KEY, ControllerClass);
|
|
3772
|
+
if (controllerVersion?.options?.addPrefix) {
|
|
3773
|
+
basePath = `/${controllerVersion.version}${basePath || ""}`;
|
|
3774
|
+
}
|
|
3775
|
+
routes.forEach(({ path: path3, method, handlerName }) => {
|
|
3776
|
+
const methodMiddlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
|
|
3777
|
+
const params = Reflect.getMetadata(PARAMS_KEY, instance, handlerName) || [];
|
|
3778
|
+
const httpCode = Reflect.getMetadata(HTTP_CODE_KEY, instance, handlerName);
|
|
3779
|
+
const methodHeaders = Reflect.getMetadata(HEADER_KEY, instance, handlerName) || {};
|
|
3780
|
+
const headers = {
|
|
3781
|
+
...controllerHeaders,
|
|
3782
|
+
...methodHeaders
|
|
3783
|
+
};
|
|
3784
|
+
const middlewares = [
|
|
3785
|
+
...controllerMiddlewares,
|
|
3786
|
+
...methodMiddlewares
|
|
3787
|
+
];
|
|
3788
|
+
const methodBeforeHooks = Reflect.getMetadata(BEFORE_KEY, instance, handlerName) || [];
|
|
3789
|
+
const methodAfterHooks = Reflect.getMetadata(AFTER_KEY, instance, handlerName) || [];
|
|
3790
|
+
const beforeHooks = [
|
|
3791
|
+
...controllerBeforeHooks,
|
|
3792
|
+
...methodBeforeHooks
|
|
3793
|
+
];
|
|
3794
|
+
const afterHooks = [
|
|
3795
|
+
...methodAfterHooks,
|
|
3796
|
+
...controllerAfterHooks
|
|
3797
|
+
];
|
|
3798
|
+
const redirect = Reflect.getMetadata(REDIRECT_KEY, instance, handlerName);
|
|
3799
|
+
const methodContentType = Reflect.getMetadata(CONTENT_TYPE_KEY, instance, handlerName);
|
|
3800
|
+
const contentType = methodContentType || controllerContentType;
|
|
3801
|
+
const roles = Reflect.getMetadata(ROLES_KEY, instance, handlerName) || controllerRoles || [];
|
|
3802
|
+
const cache = Reflect.getMetadata(CACHE_KEY, instance, handlerName) || controllerCache;
|
|
3803
|
+
const rateLimitOptions = Reflect.getMetadata(RATE_LIMIT_KEY, instance, handlerName) || controllerRateLimit;
|
|
3804
|
+
const methodVersion = Reflect.getMetadata(VERSION_KEY, instance, handlerName);
|
|
3805
|
+
const version = methodVersion || controllerVersion;
|
|
3806
|
+
const timeout2 = Reflect.getMetadata(TIMEOUT_KEY, instance, handlerName) || controllerTimeout;
|
|
3807
|
+
const logConfig = Reflect.getMetadata(LOG_KEY, instance, handlerName) || controllerLogConfig;
|
|
3808
|
+
let rateLimiter = null;
|
|
3809
|
+
if (rateLimitOptions) {
|
|
3810
|
+
try {
|
|
3811
|
+
rateLimiter = rateLimiterCache.get(rateLimitOptions);
|
|
3812
|
+
} catch (err) {
|
|
3813
|
+
getLogger().warn({
|
|
3814
|
+
err
|
|
3815
|
+
}, "express-rate-limit not available, skipping rate limiting for this route");
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
let finalPath = path3;
|
|
3819
|
+
if (methodVersion?.options?.addPrefix && methodVersion.version !== controllerVersion?.version) {
|
|
3820
|
+
finalPath = `/${methodVersion.version}${path3}`;
|
|
3821
|
+
}
|
|
3822
|
+
const handler = /* @__PURE__ */ __name(async (req, res, next) => {
|
|
3823
|
+
req["startTime"] = Date.now();
|
|
3824
|
+
let timeoutId;
|
|
3825
|
+
let timedOut = false;
|
|
3826
|
+
try {
|
|
3827
|
+
if (timeout2) {
|
|
3828
|
+
timeoutId = setTimeout(() => {
|
|
3829
|
+
if (!res.headersSent && !timedOut) {
|
|
3830
|
+
timedOut = true;
|
|
3831
|
+
const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.REQUEST_TIMEOUT, "Request timed out");
|
|
3832
|
+
res.status(HttpStatusCodes.REQUEST_TIMEOUT).json(errorResponse);
|
|
3833
|
+
}
|
|
3834
|
+
}, timeout2.ms);
|
|
3835
|
+
}
|
|
3836
|
+
if (timedOut) return;
|
|
3837
|
+
if (rateLimiter) {
|
|
3838
|
+
await new Promise((resolve2, reject) => {
|
|
3839
|
+
rateLimiter(req, res, (err) => {
|
|
3840
|
+
if (err) reject(err);
|
|
3841
|
+
else resolve2();
|
|
3842
|
+
});
|
|
3843
|
+
});
|
|
3844
|
+
}
|
|
3845
|
+
if (!res.headersSent && contentType) {
|
|
3846
|
+
res.setHeader("Content-Type", contentType.type);
|
|
3847
|
+
}
|
|
3848
|
+
if (version?.options?.addHeader && version?.options?.headerName && version?.version) {
|
|
3849
|
+
if (!res.headersSent) {
|
|
3850
|
+
res.setHeader(version.options.headerName, version.version);
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
if (cache && !res.headersSent) {
|
|
3854
|
+
res.setHeader("Cache-Control", `public, max-age=${cache.ttlSeconds}`);
|
|
3855
|
+
}
|
|
3856
|
+
if (logConfig?.logEntry) {
|
|
3857
|
+
const logger2 = getLogger();
|
|
3858
|
+
const logData = {
|
|
3859
|
+
method: req.method,
|
|
3860
|
+
url: req.originalUrl || req.url,
|
|
3861
|
+
userAgent: req.get("User-Agent")
|
|
3862
|
+
};
|
|
3863
|
+
if (logConfig.logParams) {
|
|
3864
|
+
logData.params = req.params;
|
|
3865
|
+
logData.query = req.query;
|
|
3866
|
+
}
|
|
3867
|
+
if (logConfig.logBody) logData.body = req.body;
|
|
3868
|
+
logger2.info({
|
|
3869
|
+
entry: logData
|
|
3870
|
+
}, "Route Entry:");
|
|
3871
|
+
}
|
|
3872
|
+
if (roles.length && !req?.user?.roles?.some((role) => roles.includes(role))) {
|
|
3873
|
+
const errorResponse = createFinalErrorResponse(req, HttpStatusCodes.FORBIDDEN, "Forbidden Insufficient Roles");
|
|
3874
|
+
res.status(HttpStatusCodes.FORBIDDEN).json(errorResponse);
|
|
3875
|
+
if (timeoutId) {
|
|
3876
|
+
clearTimeout(timeoutId);
|
|
3877
|
+
}
|
|
3878
|
+
return;
|
|
3879
|
+
}
|
|
3880
|
+
if (redirect && redirect.url) {
|
|
3881
|
+
if (timeoutId) {
|
|
3882
|
+
clearTimeout(timeoutId);
|
|
3883
|
+
}
|
|
3884
|
+
return res.redirect(redirect.statusCode, redirect.url);
|
|
3885
|
+
}
|
|
3886
|
+
for (const fn of beforeHooks) await fn(req, res);
|
|
3887
|
+
const args = [];
|
|
3888
|
+
if (params.length) {
|
|
3889
|
+
params.forEach(({ index, type, key, options }) => {
|
|
3890
|
+
let rawValue;
|
|
3891
|
+
switch (type) {
|
|
3892
|
+
case "query":
|
|
3893
|
+
rawValue = key ? req.query[key] : req.query;
|
|
3894
|
+
args[index] = options ? applyParamOptions(rawValue, options, key) : rawValue;
|
|
3895
|
+
break;
|
|
3896
|
+
case "param":
|
|
3897
|
+
rawValue = key ? req.params[key] : req.params;
|
|
3898
|
+
args[index] = options ? applyParamOptions(rawValue, options, key) : rawValue;
|
|
3899
|
+
break;
|
|
3900
|
+
case "body":
|
|
3901
|
+
args[index] = key ? req.body?.[key] : req.body;
|
|
3902
|
+
break;
|
|
3903
|
+
case "req":
|
|
3904
|
+
args[index] = req;
|
|
3905
|
+
break;
|
|
3906
|
+
case "res":
|
|
3907
|
+
args[index] = res;
|
|
3908
|
+
break;
|
|
3909
|
+
case "logger":
|
|
3910
|
+
args[index] = getLogger();
|
|
3911
|
+
break;
|
|
3912
|
+
case "reqHeader":
|
|
3913
|
+
args[index] = key ? req.headers[key.toLowerCase()] : req.headers;
|
|
3914
|
+
break;
|
|
3915
|
+
case "reqId":
|
|
3916
|
+
args[index] = req.headers["x-request-id"] || req?.id || void 0;
|
|
3917
|
+
break;
|
|
3918
|
+
case "cookie":
|
|
3919
|
+
args[index] = key ? req.cookies?.[key] : req.cookies;
|
|
3920
|
+
break;
|
|
3921
|
+
}
|
|
3922
|
+
});
|
|
3923
|
+
}
|
|
3924
|
+
const result = instance[handlerName](...args);
|
|
3925
|
+
const awaited = result instanceof Promise ? await result : result;
|
|
3926
|
+
if (timeoutId) {
|
|
3927
|
+
clearTimeout(timeoutId);
|
|
3928
|
+
}
|
|
3929
|
+
if (timedOut) return;
|
|
3930
|
+
if (redirect && awaited && typeof awaited === "object" && "url" in awaited) {
|
|
3931
|
+
const redirectUrl = awaited.url;
|
|
3932
|
+
const redirectStatus = awaited.statusCode || redirect.statusCode;
|
|
3933
|
+
return res.redirect(redirectStatus, redirectUrl);
|
|
3934
|
+
}
|
|
3935
|
+
if (!res.headersSent && typeof awaited !== "undefined") {
|
|
3936
|
+
if (httpCode) res.status(httpCode);
|
|
3937
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
3938
|
+
const normalized = normalizeHeaderValue(v);
|
|
3939
|
+
if (typeof normalized !== "undefined") {
|
|
3940
|
+
res.set(k, normalized);
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
res.json(awaited);
|
|
3944
|
+
}
|
|
3945
|
+
if (logConfig?.logExit) {
|
|
3946
|
+
const logger2 = getLogger();
|
|
3947
|
+
const logData = {
|
|
3948
|
+
method: req.method,
|
|
3949
|
+
url: req.originalUrl || req.url,
|
|
3950
|
+
statusCode: res.statusCode,
|
|
3951
|
+
duration: `${Date.now() - req.startTime}ms`
|
|
3952
|
+
};
|
|
3953
|
+
if (logConfig.logResponse) logData.response = awaited;
|
|
3954
|
+
logger2.info({
|
|
3955
|
+
exit: logData
|
|
3956
|
+
}, "Route Exit:");
|
|
3957
|
+
}
|
|
3958
|
+
for (const fn of afterHooks) await fn(req, res, awaited);
|
|
3959
|
+
} catch (err) {
|
|
3960
|
+
if (timeoutId) {
|
|
3961
|
+
clearTimeout(timeoutId);
|
|
3962
|
+
}
|
|
3963
|
+
next(err);
|
|
3964
|
+
}
|
|
3965
|
+
}, "handler");
|
|
3966
|
+
router[method](basePath + finalPath, ...middlewares, handler);
|
|
3967
|
+
});
|
|
3592
3968
|
});
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3969
|
+
}
|
|
3970
|
+
__name(registerControllers, "registerControllers");
|
|
3971
|
+
function applyParamOptions(rawValue, options, key) {
|
|
3972
|
+
if (!options) return rawValue;
|
|
3973
|
+
let value = rawValue;
|
|
3974
|
+
const paramName = key ? `: ${key}` : "";
|
|
3975
|
+
if (value === void 0 || value === null || value === "") {
|
|
3976
|
+
if ("default" in options) {
|
|
3977
|
+
value = options.default;
|
|
3978
|
+
}
|
|
3979
|
+
}
|
|
3980
|
+
if (options.required && (value === void 0 || value === null || value === "")) {
|
|
3981
|
+
throw new BadRequestException(`Required parameter missing${paramName}`);
|
|
3982
|
+
}
|
|
3983
|
+
if (value !== void 0 && value !== null) {
|
|
3984
|
+
if (options.dataType === "array") {
|
|
3985
|
+
const delimiter = options.delimiter || ",";
|
|
3986
|
+
if (typeof value === "string") {
|
|
3987
|
+
value = value.split(delimiter).map((v) => v.trim());
|
|
3988
|
+
} else if (!Array.isArray(value)) {
|
|
3989
|
+
value = [
|
|
3990
|
+
value
|
|
3991
|
+
];
|
|
3992
|
+
}
|
|
3993
|
+
if (options.type === "string" && options.pattern) {
|
|
3994
|
+
const hasInvalidPattern = value.some((v) => !options.pattern.test(v));
|
|
3995
|
+
if (hasInvalidPattern) {
|
|
3996
|
+
throw new BadRequestException(`Parameter '${key}' array contains values that do not match pattern: ${options.patternName || options.pattern}`);
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
if (options.type === "number" && options.pattern) {
|
|
4000
|
+
const hasInvalidPattern = value.some((v) => !options.pattern.test(String(v)));
|
|
4001
|
+
if (hasInvalidPattern) {
|
|
4002
|
+
throw new BadRequestException(`Parameter '${key}' array contains values that do not match pattern: ${options.patternName || options.pattern}`);
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
if (options.type === "number" && options.throwError !== false) {
|
|
4006
|
+
const hasInvalidNumber = value.some((v) => isNaN(Number(v)));
|
|
4007
|
+
if (hasInvalidNumber) {
|
|
4008
|
+
throw new BadRequestException(`Type error: expected number array${paramName}`);
|
|
4009
|
+
}
|
|
4010
|
+
if (options.min !== void 0) {
|
|
4011
|
+
const hasBelowMin = value.some((v) => Number(v) < options.min);
|
|
4012
|
+
if (hasBelowMin) {
|
|
4013
|
+
throw new BadRequestException(`Validation error: number array values must be >= ${options.min}${paramName}`);
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
if (options.max !== void 0) {
|
|
4017
|
+
const hasAboveMax = value.some((v) => Number(v) > options.max);
|
|
4018
|
+
if (hasAboveMax) {
|
|
4019
|
+
throw new BadRequestException(`Validation error: number array values must be <= ${options.max}${paramName}`);
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
if (options.type === "boolean" && options.throwError !== false) {
|
|
4024
|
+
const hasInvalidBoolean = value.some((v) => !isValidBooleanInput(v));
|
|
4025
|
+
if (hasInvalidBoolean) {
|
|
4026
|
+
throw new BadRequestException(`Type error: expected boolean array${paramName}`);
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
if (options.type) {
|
|
4030
|
+
value = value.map((v) => convertType(v, options.type || "string"));
|
|
4031
|
+
}
|
|
4032
|
+
} else if (options.dataType === "object") {
|
|
4033
|
+
if (typeof value === "string") {
|
|
4034
|
+
try {
|
|
4035
|
+
value = JSON.parse(value);
|
|
4036
|
+
} catch (_e) {
|
|
4037
|
+
if (options.throwError !== false) {
|
|
4038
|
+
throw new BadRequestException(`Invalid JSON object${paramName}`);
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
} else if (options.type) {
|
|
4043
|
+
const originalValue = value;
|
|
4044
|
+
value = convertType(value, options.type);
|
|
4045
|
+
if (options.throwError === false) {
|
|
4046
|
+
if (options.type === "number" && typeof value === "number") {
|
|
4047
|
+
if (options.min !== void 0 && value < options.min) {
|
|
4048
|
+
value = void 0;
|
|
4049
|
+
}
|
|
4050
|
+
if (options.max !== void 0 && value > options.max) {
|
|
4051
|
+
value = void 0;
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
if (options.type === "string" && options.pattern && typeof value === "string" && !options.pattern.test(value)) {
|
|
4056
|
+
throw new BadRequestException(`Parameter '${key}' does not match pattern: ${options.patternName || options.pattern}`);
|
|
4057
|
+
} else if (options.type === "number" && options.pattern && typeof value === "number" && !options.pattern.test(String(value))) {
|
|
4058
|
+
throw new BadRequestException(`Parameter '${key}' does not match pattern: ${options.patternName || options.pattern}`);
|
|
4059
|
+
}
|
|
4060
|
+
if (options.throwError !== false) {
|
|
4061
|
+
if (options.type === "number" && typeof value === "number" && isNaN(value)) {
|
|
4062
|
+
throw new BadRequestException(`Type error: expected number${paramName}`);
|
|
4063
|
+
}
|
|
4064
|
+
if (options.type === "number" && typeof value === "number") {
|
|
4065
|
+
if (options.min !== void 0 && value < options.min) {
|
|
4066
|
+
throw new BadRequestException(`Validation error: number must be >= ${options.min}${paramName}`);
|
|
4067
|
+
}
|
|
4068
|
+
if (options.max !== void 0 && value > options.max) {
|
|
4069
|
+
throw new BadRequestException(`Validation error: number must be <= ${options.max}${paramName}`);
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
if (options.type === "boolean" && !isValidBooleanInput(originalValue)) {
|
|
4073
|
+
throw new BadRequestException(`Type error: expected boolean${paramName}`);
|
|
3607
4074
|
}
|
|
3608
|
-
} else {
|
|
3609
|
-
await walkDir(entryPath, options);
|
|
3610
|
-
await options.visitorFn(entryInfo);
|
|
3611
4075
|
}
|
|
3612
|
-
} else {
|
|
3613
|
-
await options.visitorFn(entryInfo);
|
|
3614
4076
|
}
|
|
3615
4077
|
}
|
|
3616
|
-
if (
|
|
3617
|
-
|
|
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");
|
|
4078
|
+
if (options.transform && typeof options.transform === "function") {
|
|
4079
|
+
value = options.transform(value);
|
|
3781
4080
|
}
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
this.status = HttpStatusCodes.METHOD_NOT_ALLOWED;
|
|
4081
|
+
if (options.validate && typeof options.validate === "function") {
|
|
4082
|
+
if (!options.validate(value)) {
|
|
4083
|
+
if (options.throwError !== false) {
|
|
4084
|
+
throw new BadRequestException(`Parameter validation failed${paramName}`);
|
|
4085
|
+
}
|
|
4086
|
+
return void 0;
|
|
4087
|
+
}
|
|
3790
4088
|
}
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
4089
|
+
return value;
|
|
4090
|
+
}
|
|
4091
|
+
__name(applyParamOptions, "applyParamOptions");
|
|
4092
|
+
function isValidBooleanInput(value) {
|
|
4093
|
+
if (typeof value === "boolean") return true;
|
|
4094
|
+
if (typeof value === "number") return value === 0 || value === 1;
|
|
4095
|
+
if (typeof value === "string") {
|
|
4096
|
+
const normalizedValue = value.toLowerCase().trim();
|
|
4097
|
+
return [
|
|
4098
|
+
"true",
|
|
4099
|
+
"false",
|
|
4100
|
+
"0",
|
|
4101
|
+
"1",
|
|
4102
|
+
"yes",
|
|
4103
|
+
"no"
|
|
4104
|
+
].includes(normalizedValue);
|
|
3795
4105
|
}
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
4106
|
+
return false;
|
|
4107
|
+
}
|
|
4108
|
+
__name(isValidBooleanInput, "isValidBooleanInput");
|
|
4109
|
+
function convertType(value, type) {
|
|
4110
|
+
if (value === void 0 || value === null) {
|
|
4111
|
+
return value;
|
|
3802
4112
|
}
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
4113
|
+
switch (type) {
|
|
4114
|
+
case "number":
|
|
4115
|
+
return Number(value);
|
|
4116
|
+
case "boolean":
|
|
4117
|
+
if (typeof value === "string") {
|
|
4118
|
+
const normalizedValue = value.toLowerCase().trim();
|
|
4119
|
+
return normalizedValue === "true" || normalizedValue === "1" || normalizedValue === "yes";
|
|
4120
|
+
}
|
|
4121
|
+
return value === true || value === 1;
|
|
4122
|
+
case "string":
|
|
4123
|
+
default:
|
|
4124
|
+
return String(value);
|
|
3807
4125
|
}
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
4126
|
+
}
|
|
4127
|
+
__name(convertType, "convertType");
|
|
4128
|
+
async function ensureDir(dirPath) {
|
|
4129
|
+
await fsp__default.default.mkdir(dirPath, {
|
|
4130
|
+
recursive: true
|
|
4131
|
+
});
|
|
4132
|
+
}
|
|
4133
|
+
__name(ensureDir, "ensureDir");
|
|
4134
|
+
async function listFiles(dirPath, recursive = false) {
|
|
4135
|
+
const entries = await fsp__default.default.readdir(dirPath, {
|
|
4136
|
+
withFileTypes: true
|
|
4137
|
+
});
|
|
4138
|
+
const files = [];
|
|
4139
|
+
for (const entry of entries) {
|
|
4140
|
+
const fullPath = path__default.default.join(dirPath, entry.name);
|
|
4141
|
+
if (entry.isFile()) {
|
|
4142
|
+
files.push(fullPath);
|
|
4143
|
+
} else if (recursive && entry.isDirectory()) {
|
|
4144
|
+
const nestedFiles = await listFiles(fullPath, true);
|
|
4145
|
+
files.push(...nestedFiles);
|
|
4146
|
+
}
|
|
3814
4147
|
}
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
4148
|
+
return files;
|
|
4149
|
+
}
|
|
4150
|
+
__name(listFiles, "listFiles");
|
|
4151
|
+
async function deleteDirRecursive(dirPath) {
|
|
4152
|
+
await fsp__default.default.rm(dirPath, {
|
|
4153
|
+
recursive: true,
|
|
4154
|
+
force: true
|
|
4155
|
+
});
|
|
4156
|
+
}
|
|
4157
|
+
__name(deleteDirRecursive, "deleteDirRecursive");
|
|
4158
|
+
async function isDirectory(pathStr) {
|
|
4159
|
+
try {
|
|
4160
|
+
const stat = await fsp__default.default.stat(pathStr);
|
|
4161
|
+
return stat.isDirectory();
|
|
4162
|
+
} catch {
|
|
4163
|
+
return false;
|
|
3819
4164
|
}
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
4165
|
+
}
|
|
4166
|
+
__name(isDirectory, "isDirectory");
|
|
4167
|
+
async function copyDir(src, dest) {
|
|
4168
|
+
await ensureDir(dest);
|
|
4169
|
+
const entries = await fsp__default.default.readdir(src, {
|
|
4170
|
+
withFileTypes: true
|
|
4171
|
+
});
|
|
4172
|
+
for (const entry of entries) {
|
|
4173
|
+
const srcPath = path__default.default.join(src, entry.name);
|
|
4174
|
+
const destPath = path__default.default.join(dest, entry.name);
|
|
4175
|
+
if (entry.isDirectory()) {
|
|
4176
|
+
await copyDir(srcPath, destPath);
|
|
4177
|
+
} else {
|
|
4178
|
+
await fsp__default.default.copyFile(srcPath, destPath);
|
|
4179
|
+
}
|
|
3826
4180
|
}
|
|
3827
|
-
}
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
4181
|
+
}
|
|
4182
|
+
__name(copyDir, "copyDir");
|
|
4183
|
+
async function moveDir(src, dest) {
|
|
4184
|
+
await copyDir(src, dest);
|
|
4185
|
+
await deleteDirRecursive(src);
|
|
4186
|
+
}
|
|
4187
|
+
__name(moveDir, "moveDir");
|
|
4188
|
+
async function emptyDir(dirPath) {
|
|
4189
|
+
const entries = await fsp__default.default.readdir(dirPath, {
|
|
4190
|
+
withFileTypes: true
|
|
4191
|
+
});
|
|
4192
|
+
for (const entry of entries) {
|
|
4193
|
+
const entryPath = path__default.default.join(dirPath, entry.name);
|
|
4194
|
+
if (entry.isDirectory()) {
|
|
4195
|
+
await fsp__default.default.rm(entryPath, {
|
|
4196
|
+
recursive: true,
|
|
4197
|
+
force: true
|
|
4198
|
+
});
|
|
4199
|
+
} else {
|
|
4200
|
+
await fsp__default.default.unlink(entryPath);
|
|
4201
|
+
}
|
|
3831
4202
|
}
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
4203
|
+
}
|
|
4204
|
+
__name(emptyDir, "emptyDir");
|
|
4205
|
+
async function getDirSize(dirPath) {
|
|
4206
|
+
let total = 0;
|
|
4207
|
+
const entries = await fsp__default.default.readdir(dirPath, {
|
|
4208
|
+
withFileTypes: true
|
|
4209
|
+
});
|
|
4210
|
+
for (const entry of entries) {
|
|
4211
|
+
const entryPath = path__default.default.join(dirPath, entry.name);
|
|
4212
|
+
if (entry.isDirectory()) {
|
|
4213
|
+
total += await getDirSize(entryPath);
|
|
4214
|
+
} else {
|
|
4215
|
+
const stat = await fsp__default.default.stat(entryPath);
|
|
4216
|
+
total += stat.size;
|
|
4217
|
+
}
|
|
3838
4218
|
}
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
4219
|
+
return total;
|
|
4220
|
+
}
|
|
4221
|
+
__name(getDirSize, "getDirSize");
|
|
4222
|
+
function watchDir(dirPath, callback) {
|
|
4223
|
+
const watcher = fs__default.default.watch(dirPath, (eventType, filename) => {
|
|
4224
|
+
callback(eventType, filename);
|
|
4225
|
+
});
|
|
4226
|
+
return () => watcher.close();
|
|
4227
|
+
}
|
|
4228
|
+
__name(watchDir, "watchDir");
|
|
4229
|
+
async function findFilesByPattern(pattern, options = {}) {
|
|
4230
|
+
const matchPattern = /* @__PURE__ */ __name((name, pattern2) => {
|
|
4231
|
+
let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
4232
|
+
escaped = escaped.replaceAll("*", ".*").replaceAll("?", ".");
|
|
4233
|
+
const regex = new RegExp(`^${escaped}$`);
|
|
4234
|
+
return regex.test(name);
|
|
4235
|
+
}, "matchPattern");
|
|
4236
|
+
const { cwd = process.cwd(), dot = false } = options;
|
|
4237
|
+
const segments = pattern.split("/");
|
|
4238
|
+
async function walk(dir, segIndex) {
|
|
4239
|
+
if (segIndex >= segments.length) return [];
|
|
4240
|
+
const segment = segments[segIndex];
|
|
4241
|
+
const entries = await fs__default.default.promises.readdir(dir, {
|
|
4242
|
+
withFileTypes: true
|
|
4243
|
+
});
|
|
4244
|
+
let matchedFiles = [];
|
|
4245
|
+
for (const entry of entries) {
|
|
4246
|
+
const entryName = entry.name;
|
|
4247
|
+
if (!dot && entryName.startsWith(".")) continue;
|
|
4248
|
+
const fullPath = path__default.default.join(dir, entryName);
|
|
4249
|
+
const isLastSegment = segIndex === segments.length - 1;
|
|
4250
|
+
if (isLastSegment) {
|
|
4251
|
+
if (matchPattern(entryName, segment) && entry.isFile()) {
|
|
4252
|
+
matchedFiles.push(fullPath);
|
|
4253
|
+
}
|
|
4254
|
+
} else if (entry.isDirectory()) {
|
|
4255
|
+
if (matchPattern(entryName, segment)) {
|
|
4256
|
+
matchedFiles.push(...await walk(fullPath, segIndex + 1));
|
|
4257
|
+
}
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
return matchedFiles;
|
|
3843
4261
|
}
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
4262
|
+
__name(walk, "walk");
|
|
4263
|
+
return walk(cwd, 0);
|
|
4264
|
+
}
|
|
4265
|
+
__name(findFilesByPattern, "findFilesByPattern");
|
|
4266
|
+
async function getSubdirectories(dirPath, recursive = false) {
|
|
4267
|
+
const entries = await fsp__default.default.readdir(dirPath, {
|
|
4268
|
+
withFileTypes: true
|
|
4269
|
+
});
|
|
4270
|
+
const dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => path__default.default.join(dirPath, entry.name));
|
|
4271
|
+
if (recursive && dirs.length > 0) {
|
|
4272
|
+
const nestedDirs = await Promise.all(dirs.map((dir) => getSubdirectories(dir, true)));
|
|
4273
|
+
return [
|
|
4274
|
+
...dirs,
|
|
4275
|
+
...nestedDirs.flat()
|
|
4276
|
+
];
|
|
3850
4277
|
}
|
|
3851
|
-
|
|
3852
|
-
function isHttpError(error) {
|
|
3853
|
-
return error instanceof ErrorResponse;
|
|
4278
|
+
return dirs;
|
|
3854
4279
|
}
|
|
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
|
-
|
|
4280
|
+
__name(getSubdirectories, "getSubdirectories");
|
|
4281
|
+
async function ensureEmptyDir(dirPath) {
|
|
4282
|
+
if (await isDirectory(dirPath)) {
|
|
4283
|
+
await emptyDir(dirPath);
|
|
4284
|
+
} else {
|
|
4285
|
+
try {
|
|
4286
|
+
await fsp__default.default.unlink(dirPath);
|
|
4287
|
+
} catch (error) {
|
|
4288
|
+
if (error.code !== "ENOENT") {
|
|
4289
|
+
throw error;
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4292
|
+
await ensureDir(dirPath);
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
__name(ensureEmptyDir, "ensureEmptyDir");
|
|
4296
|
+
async function createTempDir(options = {}) {
|
|
4297
|
+
const prefix = options.prefix || "tmp-";
|
|
4298
|
+
const parentDir = options.parentDir || os__default.default.tmpdir();
|
|
4299
|
+
const dirName = `${prefix}${crypto.randomBytes(6).toString("hex")}`;
|
|
4300
|
+
const tempDirPath = path__default.default.join(parentDir, dirName);
|
|
4301
|
+
await ensureDir(tempDirPath);
|
|
4302
|
+
const cleanup = /* @__PURE__ */ __name(async () => {
|
|
4303
|
+
try {
|
|
4304
|
+
await deleteDirRecursive(tempDirPath);
|
|
4305
|
+
} catch {
|
|
4306
|
+
}
|
|
4307
|
+
}, "cleanup");
|
|
4308
|
+
if (options.cleanup) {
|
|
4309
|
+
process.once("exit", () => {
|
|
4310
|
+
try {
|
|
4311
|
+
fs__default.default.rmSync(tempDirPath, {
|
|
4312
|
+
recursive: true,
|
|
4313
|
+
force: true
|
|
4314
|
+
});
|
|
4315
|
+
} catch {
|
|
4316
|
+
}
|
|
4317
|
+
});
|
|
4318
|
+
const signals = [
|
|
4319
|
+
"SIGINT",
|
|
4320
|
+
"SIGTERM",
|
|
4321
|
+
"SIGUSR1",
|
|
4322
|
+
"SIGUSR2"
|
|
4323
|
+
];
|
|
4324
|
+
for (const signal of signals) {
|
|
4325
|
+
process.once(signal, () => {
|
|
4326
|
+
cleanup().then(() => process.exit());
|
|
4327
|
+
});
|
|
4328
|
+
}
|
|
3896
4329
|
}
|
|
4330
|
+
return {
|
|
4331
|
+
path: tempDirPath,
|
|
4332
|
+
cleanup
|
|
4333
|
+
};
|
|
3897
4334
|
}
|
|
3898
|
-
__name(
|
|
3899
|
-
function
|
|
3900
|
-
|
|
4335
|
+
__name(createTempDir, "createTempDir");
|
|
4336
|
+
async function findNewestFile(dirPath, recursive = false) {
|
|
4337
|
+
const files = await listFiles(dirPath, recursive);
|
|
4338
|
+
if (files.length === 0) return null;
|
|
4339
|
+
const stats = await Promise.all(files.map(async (file) => ({
|
|
4340
|
+
path: file,
|
|
4341
|
+
mtime: (await fsp__default.default.stat(file)).mtime
|
|
4342
|
+
})));
|
|
4343
|
+
return stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0].path;
|
|
3901
4344
|
}
|
|
3902
|
-
__name(
|
|
3903
|
-
function
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
}
|
|
3910
|
-
|
|
3911
|
-
|
|
4345
|
+
__name(findNewestFile, "findNewestFile");
|
|
4346
|
+
async function findOldestFile(dirPath, recursive = false) {
|
|
4347
|
+
const files = await listFiles(dirPath, recursive);
|
|
4348
|
+
if (files.length === 0) return null;
|
|
4349
|
+
const stats = await Promise.all(files.map(async (file) => ({
|
|
4350
|
+
path: file,
|
|
4351
|
+
mtime: (await fsp__default.default.stat(file)).mtime
|
|
4352
|
+
})));
|
|
4353
|
+
return stats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime())[0].path;
|
|
4354
|
+
}
|
|
4355
|
+
__name(findOldestFile, "findOldestFile");
|
|
4356
|
+
async function findInDir(dirPath, predicate, recursive = false) {
|
|
4357
|
+
const entries = await fsp__default.default.readdir(dirPath, {
|
|
4358
|
+
withFileTypes: true
|
|
4359
|
+
});
|
|
4360
|
+
const results = [];
|
|
4361
|
+
for (const entry of entries) {
|
|
4362
|
+
const entryPath = path__default.default.join(dirPath, entry.name);
|
|
4363
|
+
const stat = await fsp__default.default.stat(entryPath);
|
|
4364
|
+
if (await predicate(entryPath, stat)) {
|
|
4365
|
+
results.push(entryPath);
|
|
4366
|
+
}
|
|
4367
|
+
if (recursive && entry.isDirectory()) {
|
|
4368
|
+
const nestedResults = await findInDir(entryPath, predicate, true);
|
|
4369
|
+
results.push(...nestedResults);
|
|
4370
|
+
}
|
|
3912
4371
|
}
|
|
3913
|
-
return
|
|
4372
|
+
return results;
|
|
3914
4373
|
}
|
|
3915
|
-
__name(
|
|
3916
|
-
function
|
|
3917
|
-
|
|
4374
|
+
__name(findInDir, "findInDir");
|
|
4375
|
+
async function watchDirRecursive(dirPath, callback, includeSubdirs = true) {
|
|
4376
|
+
const normalizedBasePath = path__default.default.normalize(dirPath);
|
|
4377
|
+
const watchers = [];
|
|
4378
|
+
const addWatcher = /* @__PURE__ */ __name((dir) => {
|
|
3918
4379
|
try {
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
4380
|
+
const watcher = fs__default.default.watch(dir, (eventType, filename) => {
|
|
4381
|
+
if (!filename) return;
|
|
4382
|
+
const fullPath = path__default.default.join(dir, filename);
|
|
4383
|
+
const relativePath = path__default.default.relative(normalizedBasePath, fullPath);
|
|
4384
|
+
callback(eventType, relativePath);
|
|
4385
|
+
if (eventType === "rename" && includeSubdirs) {
|
|
4386
|
+
setTimeout(async () => {
|
|
4387
|
+
try {
|
|
4388
|
+
if (await isDirectory(fullPath)) {
|
|
4389
|
+
addWatcher(fullPath);
|
|
4390
|
+
}
|
|
4391
|
+
} catch {
|
|
4392
|
+
}
|
|
4393
|
+
}, 100);
|
|
4394
|
+
}
|
|
4395
|
+
});
|
|
4396
|
+
watchers.push(watcher);
|
|
4397
|
+
} catch {
|
|
4398
|
+
}
|
|
4399
|
+
}, "addWatcher");
|
|
4400
|
+
addWatcher(normalizedBasePath);
|
|
4401
|
+
if (includeSubdirs) {
|
|
4402
|
+
const subdirs = await getSubdirectories(normalizedBasePath, true);
|
|
4403
|
+
for (const subdir of subdirs) {
|
|
4404
|
+
addWatcher(subdir);
|
|
4405
|
+
}
|
|
4406
|
+
}
|
|
4407
|
+
return () => {
|
|
4408
|
+
for (const watcher of watchers) {
|
|
4409
|
+
watcher.close();
|
|
4410
|
+
}
|
|
4411
|
+
};
|
|
4412
|
+
}
|
|
4413
|
+
__name(watchDirRecursive, "watchDirRecursive");
|
|
4414
|
+
async function getDirStats(dirPath) {
|
|
4415
|
+
let fileCount = 0;
|
|
4416
|
+
let dirCount = 0;
|
|
4417
|
+
let totalSize = 0;
|
|
4418
|
+
async function processDir(currentPath) {
|
|
4419
|
+
const entries = await fsp__default.default.readdir(currentPath, {
|
|
4420
|
+
withFileTypes: true
|
|
4421
|
+
});
|
|
4422
|
+
for (const entry of entries) {
|
|
4423
|
+
const entryPath = path__default.default.join(currentPath, entry.name);
|
|
4424
|
+
if (entry.isDirectory()) {
|
|
4425
|
+
dirCount++;
|
|
4426
|
+
await processDir(entryPath);
|
|
4427
|
+
} else if (entry.isFile()) {
|
|
4428
|
+
fileCount++;
|
|
4429
|
+
const stat = await fsp__default.default.stat(entryPath);
|
|
4430
|
+
totalSize += stat.size;
|
|
3930
4431
|
}
|
|
3931
|
-
throw createHttpError(status, getErrorMessage(err));
|
|
3932
4432
|
}
|
|
4433
|
+
}
|
|
4434
|
+
__name(processDir, "processDir");
|
|
4435
|
+
await processDir(dirPath);
|
|
4436
|
+
return {
|
|
4437
|
+
fileCount,
|
|
4438
|
+
dirCount,
|
|
4439
|
+
totalSize
|
|
3933
4440
|
};
|
|
3934
4441
|
}
|
|
3935
|
-
__name(
|
|
4442
|
+
__name(getDirStats, "getDirStats");
|
|
4443
|
+
async function walkDir(dirPath, options) {
|
|
4444
|
+
const traversalOrder = options.traversalOrder || "pre";
|
|
4445
|
+
const entries = await fsp__default.default.readdir(dirPath, {
|
|
4446
|
+
withFileTypes: true
|
|
4447
|
+
});
|
|
4448
|
+
for (const entry of entries) {
|
|
4449
|
+
const entryPath = path__default.default.join(dirPath, entry.name);
|
|
4450
|
+
const stats = await fsp__default.default.stat(entryPath);
|
|
4451
|
+
const entryInfo = {
|
|
4452
|
+
path: entryPath,
|
|
4453
|
+
name: entry.name,
|
|
4454
|
+
isDirectory: entry.isDirectory(),
|
|
4455
|
+
stats
|
|
4456
|
+
};
|
|
4457
|
+
if (entry.isDirectory()) {
|
|
4458
|
+
if (traversalOrder === "pre") {
|
|
4459
|
+
const shouldContinue = await options.visitorFn(entryInfo);
|
|
4460
|
+
if (shouldContinue !== false) {
|
|
4461
|
+
await walkDir(entryPath, options);
|
|
4462
|
+
}
|
|
4463
|
+
} else {
|
|
4464
|
+
await walkDir(entryPath, options);
|
|
4465
|
+
await options.visitorFn(entryInfo);
|
|
4466
|
+
}
|
|
4467
|
+
} else {
|
|
4468
|
+
await options.visitorFn(entryInfo);
|
|
4469
|
+
}
|
|
4470
|
+
}
|
|
4471
|
+
if (traversalOrder === "post") {
|
|
4472
|
+
const stats = await fsp__default.default.stat(dirPath);
|
|
4473
|
+
const entryInfo = {
|
|
4474
|
+
path: dirPath,
|
|
4475
|
+
name: path__default.default.basename(dirPath),
|
|
4476
|
+
isDirectory: true,
|
|
4477
|
+
stats
|
|
4478
|
+
};
|
|
4479
|
+
await options.visitorFn(entryInfo);
|
|
4480
|
+
}
|
|
4481
|
+
}
|
|
4482
|
+
__name(walkDir, "walkDir");
|
|
3936
4483
|
async function fileExists(path3) {
|
|
3937
4484
|
try {
|
|
3938
4485
|
await fsp__default.default.access(path3);
|
|
@@ -4259,6 +4806,202 @@ function healthCheck(options) {
|
|
|
4259
4806
|
}
|
|
4260
4807
|
__name(healthCheck, "healthCheck");
|
|
4261
4808
|
|
|
4809
|
+
// src/utils/performance.utils.ts
|
|
4810
|
+
function timeSync(fn, options = {}) {
|
|
4811
|
+
const { label = fn.name || "anonymous function", log = false, logLevel = "debug" } = options;
|
|
4812
|
+
const startTime = performance.now();
|
|
4813
|
+
const result = fn();
|
|
4814
|
+
const endTime = performance.now();
|
|
4815
|
+
const durationMs = endTime - startTime;
|
|
4816
|
+
const durationSec = durationMs / 1e3;
|
|
4817
|
+
const timing = {
|
|
4818
|
+
durationMs,
|
|
4819
|
+
durationSec,
|
|
4820
|
+
startTime,
|
|
4821
|
+
endTime,
|
|
4822
|
+
label
|
|
4823
|
+
};
|
|
4824
|
+
if (log) {
|
|
4825
|
+
const logger2 = getLogger();
|
|
4826
|
+
const message = `${label} completed in ${durationMs.toFixed(2)}ms`;
|
|
4827
|
+
switch (logLevel) {
|
|
4828
|
+
case "trace":
|
|
4829
|
+
logger2.trace({
|
|
4830
|
+
timing
|
|
4831
|
+
}, message);
|
|
4832
|
+
break;
|
|
4833
|
+
case "debug":
|
|
4834
|
+
logger2.debug({
|
|
4835
|
+
timing
|
|
4836
|
+
}, message);
|
|
4837
|
+
break;
|
|
4838
|
+
case "info":
|
|
4839
|
+
logger2.info({
|
|
4840
|
+
timing
|
|
4841
|
+
}, message);
|
|
4842
|
+
break;
|
|
4843
|
+
case "warn":
|
|
4844
|
+
logger2.warn({
|
|
4845
|
+
timing
|
|
4846
|
+
}, message);
|
|
4847
|
+
break;
|
|
4848
|
+
case "error":
|
|
4849
|
+
logger2.error({
|
|
4850
|
+
timing
|
|
4851
|
+
}, message);
|
|
4852
|
+
break;
|
|
4853
|
+
default:
|
|
4854
|
+
logger2.debug({
|
|
4855
|
+
timing
|
|
4856
|
+
}, message);
|
|
4857
|
+
break;
|
|
4858
|
+
}
|
|
4859
|
+
}
|
|
4860
|
+
return {
|
|
4861
|
+
result,
|
|
4862
|
+
timing
|
|
4863
|
+
};
|
|
4864
|
+
}
|
|
4865
|
+
__name(timeSync, "timeSync");
|
|
4866
|
+
async function timeAsync(fn, options = {}) {
|
|
4867
|
+
const { label = fn.name || "anonymous async function", log = false, logLevel = "debug" } = options;
|
|
4868
|
+
const startTime = performance.now();
|
|
4869
|
+
const result = await fn();
|
|
4870
|
+
const endTime = performance.now();
|
|
4871
|
+
const durationMs = endTime - startTime;
|
|
4872
|
+
const durationSec = durationMs / 1e3;
|
|
4873
|
+
const timing = {
|
|
4874
|
+
durationMs,
|
|
4875
|
+
durationSec,
|
|
4876
|
+
startTime,
|
|
4877
|
+
endTime,
|
|
4878
|
+
label
|
|
4879
|
+
};
|
|
4880
|
+
if (log) {
|
|
4881
|
+
const logger2 = getLogger();
|
|
4882
|
+
const message = `${label} completed in ${durationMs.toFixed(2)}ms`;
|
|
4883
|
+
switch (logLevel) {
|
|
4884
|
+
case "trace":
|
|
4885
|
+
logger2.trace({
|
|
4886
|
+
timing
|
|
4887
|
+
}, message);
|
|
4888
|
+
break;
|
|
4889
|
+
case "debug":
|
|
4890
|
+
logger2.debug({
|
|
4891
|
+
timing
|
|
4892
|
+
}, message);
|
|
4893
|
+
break;
|
|
4894
|
+
case "info":
|
|
4895
|
+
logger2.info({
|
|
4896
|
+
timing
|
|
4897
|
+
}, message);
|
|
4898
|
+
break;
|
|
4899
|
+
case "warn":
|
|
4900
|
+
logger2.warn({
|
|
4901
|
+
timing
|
|
4902
|
+
}, message);
|
|
4903
|
+
break;
|
|
4904
|
+
case "error":
|
|
4905
|
+
logger2.error({
|
|
4906
|
+
timing
|
|
4907
|
+
}, message);
|
|
4908
|
+
break;
|
|
4909
|
+
default:
|
|
4910
|
+
logger2.debug({
|
|
4911
|
+
timing
|
|
4912
|
+
}, message);
|
|
4913
|
+
break;
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
return {
|
|
4917
|
+
result,
|
|
4918
|
+
timing
|
|
4919
|
+
};
|
|
4920
|
+
}
|
|
4921
|
+
__name(timeAsync, "timeAsync");
|
|
4922
|
+
function timed(options = {}) {
|
|
4923
|
+
return function(target, propertyKeyOrContext, descriptor) {
|
|
4924
|
+
let propertyKey;
|
|
4925
|
+
let actualDescriptor;
|
|
4926
|
+
if (typeof propertyKeyOrContext === "object" && propertyKeyOrContext !== null && "name" in propertyKeyOrContext) {
|
|
4927
|
+
propertyKey = propertyKeyOrContext.name;
|
|
4928
|
+
actualDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey);
|
|
4929
|
+
} else {
|
|
4930
|
+
propertyKey = propertyKeyOrContext;
|
|
4931
|
+
actualDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey);
|
|
4932
|
+
}
|
|
4933
|
+
const originalMethod = actualDescriptor.value;
|
|
4934
|
+
actualDescriptor.value = function(...args) {
|
|
4935
|
+
const methodOptions = {
|
|
4936
|
+
...options,
|
|
4937
|
+
label: options.label || `${target.constructor.name}.${String(propertyKey)}`
|
|
4938
|
+
};
|
|
4939
|
+
if (originalMethod.constructor.name === "AsyncFunction") {
|
|
4940
|
+
return timeAsync(() => originalMethod.apply(this, args), methodOptions).then(({ result }) => result);
|
|
4941
|
+
} else {
|
|
4942
|
+
return timeSync(() => originalMethod.apply(this, args), methodOptions).result;
|
|
4943
|
+
}
|
|
4944
|
+
};
|
|
4945
|
+
if (descriptor) {
|
|
4946
|
+
descriptor.value = actualDescriptor.value;
|
|
4947
|
+
} else {
|
|
4948
|
+
Object.defineProperty(target, propertyKey, actualDescriptor);
|
|
4949
|
+
}
|
|
4950
|
+
};
|
|
4951
|
+
}
|
|
4952
|
+
__name(timed, "timed");
|
|
4953
|
+
function memoize(fn, options = {}) {
|
|
4954
|
+
const { ttl, maxSize, autoCleanupMs, cacheKey = /* @__PURE__ */ __name((...args) => JSON.stringify(args), "cacheKey") } = options;
|
|
4955
|
+
const cache = new TTLCache({
|
|
4956
|
+
ttlMs: ttl,
|
|
4957
|
+
maxSize,
|
|
4958
|
+
autoCleanupMs
|
|
4959
|
+
});
|
|
4960
|
+
return function(...args) {
|
|
4961
|
+
const key = cacheKey(...args);
|
|
4962
|
+
const cachedValue = cache.get(key);
|
|
4963
|
+
if (cachedValue !== void 0) {
|
|
4964
|
+
return cachedValue;
|
|
4965
|
+
}
|
|
4966
|
+
const value = fn(...args);
|
|
4967
|
+
cache.set(key, value);
|
|
4968
|
+
return value;
|
|
4969
|
+
};
|
|
4970
|
+
}
|
|
4971
|
+
__name(memoize, "memoize");
|
|
4972
|
+
function trackMemoryUsage(fn, options = {}) {
|
|
4973
|
+
const { log = false, label = fn.name || "anonymous function" } = options;
|
|
4974
|
+
if (global.gc) {
|
|
4975
|
+
global.gc();
|
|
4976
|
+
}
|
|
4977
|
+
const beforeMemory = process.memoryUsage();
|
|
4978
|
+
const result = fn();
|
|
4979
|
+
const afterMemory = process.memoryUsage();
|
|
4980
|
+
const diff = {};
|
|
4981
|
+
for (const key in afterMemory) {
|
|
4982
|
+
if (Object.prototype.hasOwnProperty.call(afterMemory, key)) {
|
|
4983
|
+
diff[key] = afterMemory[key] - beforeMemory[key];
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
if (log) {
|
|
4987
|
+
getLogger().info({
|
|
4988
|
+
label,
|
|
4989
|
+
memoryBefore: beforeMemory,
|
|
4990
|
+
memoryAfter: afterMemory,
|
|
4991
|
+
memoryDiff: diff
|
|
4992
|
+
}, `Memory usage for ${label}`);
|
|
4993
|
+
}
|
|
4994
|
+
return {
|
|
4995
|
+
result,
|
|
4996
|
+
memoryUsage: {
|
|
4997
|
+
before: beforeMemory,
|
|
4998
|
+
after: afterMemory,
|
|
4999
|
+
diff
|
|
5000
|
+
}
|
|
5001
|
+
};
|
|
5002
|
+
}
|
|
5003
|
+
__name(trackMemoryUsage, "trackMemoryUsage");
|
|
5004
|
+
|
|
4262
5005
|
// src/utils/request.utils.ts
|
|
4263
5006
|
var getPaginationParams = /* @__PURE__ */ __name((req) => {
|
|
4264
5007
|
const query = req.query;
|
|
@@ -4417,6 +5160,120 @@ function extractFilterParams(query, allowedFilters) {
|
|
|
4417
5160
|
return filters;
|
|
4418
5161
|
}
|
|
4419
5162
|
__name(extractFilterParams, "extractFilterParams");
|
|
5163
|
+
function bufferToStream(data) {
|
|
5164
|
+
const readable = new stream.Readable();
|
|
5165
|
+
readable.push(data);
|
|
5166
|
+
readable.push(null);
|
|
5167
|
+
return readable;
|
|
5168
|
+
}
|
|
5169
|
+
__name(bufferToStream, "bufferToStream");
|
|
5170
|
+
async function streamToBuffer(stream) {
|
|
5171
|
+
return new Promise((resolve2, reject) => {
|
|
5172
|
+
const chunks = [];
|
|
5173
|
+
stream.on("data", (chunk2) => chunks.push(Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2)));
|
|
5174
|
+
stream.on("end", () => resolve2(Buffer.concat(chunks)));
|
|
5175
|
+
stream.on("error", reject);
|
|
5176
|
+
});
|
|
5177
|
+
}
|
|
5178
|
+
__name(streamToBuffer, "streamToBuffer");
|
|
5179
|
+
async function streamToString(stream, encoding = "utf8") {
|
|
5180
|
+
const buffer = await streamToBuffer(stream);
|
|
5181
|
+
return buffer.toString(encoding);
|
|
5182
|
+
}
|
|
5183
|
+
__name(streamToString, "streamToString");
|
|
5184
|
+
function createThrottleStream(bytesPerSecond) {
|
|
5185
|
+
let bytesSent = 0;
|
|
5186
|
+
let startTime = Date.now();
|
|
5187
|
+
return new stream.Transform({
|
|
5188
|
+
transform(chunk2, _encoding, callback) {
|
|
5189
|
+
const elapsedSeconds = (Date.now() - startTime) / 1e3;
|
|
5190
|
+
const targetBytes = bytesPerSecond * elapsedSeconds;
|
|
5191
|
+
const chunkSize = chunk2.length;
|
|
5192
|
+
if (bytesSent + chunkSize <= targetBytes) {
|
|
5193
|
+
bytesSent += chunkSize;
|
|
5194
|
+
callback(null, chunk2);
|
|
5195
|
+
return;
|
|
5196
|
+
}
|
|
5197
|
+
const delay = ((bytesSent + chunkSize) / bytesPerSecond - elapsedSeconds) * 1e3;
|
|
5198
|
+
setTimeout(() => {
|
|
5199
|
+
bytesSent += chunkSize;
|
|
5200
|
+
callback(null, chunk2);
|
|
5201
|
+
}, delay);
|
|
5202
|
+
}
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5205
|
+
__name(createThrottleStream, "createThrottleStream");
|
|
5206
|
+
function createBatchStream(size, options = {}) {
|
|
5207
|
+
const objectMode = options.objectMode !== false;
|
|
5208
|
+
let batch = [];
|
|
5209
|
+
let buffers = [];
|
|
5210
|
+
let bufferSize = 0;
|
|
5211
|
+
return new stream.Transform({
|
|
5212
|
+
objectMode,
|
|
5213
|
+
transform(chunk2, _encoding, callback) {
|
|
5214
|
+
if (objectMode) {
|
|
5215
|
+
batch.push(chunk2);
|
|
5216
|
+
if (batch.length >= size) {
|
|
5217
|
+
this.push(batch);
|
|
5218
|
+
batch = [];
|
|
5219
|
+
}
|
|
5220
|
+
} else {
|
|
5221
|
+
const buffer = Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2);
|
|
5222
|
+
buffers.push(buffer);
|
|
5223
|
+
bufferSize += buffer.length;
|
|
5224
|
+
let combined = Buffer.concat(buffers, bufferSize);
|
|
5225
|
+
while (combined.length >= size) {
|
|
5226
|
+
this.push(combined.slice(0, size));
|
|
5227
|
+
combined = combined.slice(size);
|
|
5228
|
+
}
|
|
5229
|
+
buffers = combined.length > 0 ? [
|
|
5230
|
+
combined
|
|
5231
|
+
] : [];
|
|
5232
|
+
bufferSize = combined.length;
|
|
5233
|
+
}
|
|
5234
|
+
callback();
|
|
5235
|
+
},
|
|
5236
|
+
flush(callback) {
|
|
5237
|
+
if (objectMode && batch.length > 0) {
|
|
5238
|
+
this.push(batch);
|
|
5239
|
+
} else if (!objectMode && buffers.length > 0 && bufferSize > 0) {
|
|
5240
|
+
let combined = Buffer.concat(buffers, bufferSize);
|
|
5241
|
+
while (combined.length >= size) {
|
|
5242
|
+
this.push(combined.slice(0, size));
|
|
5243
|
+
combined = combined.slice(size);
|
|
5244
|
+
}
|
|
5245
|
+
if (combined.length > 0) {
|
|
5246
|
+
this.push(combined);
|
|
5247
|
+
}
|
|
5248
|
+
}
|
|
5249
|
+
callback();
|
|
5250
|
+
}
|
|
5251
|
+
});
|
|
5252
|
+
}
|
|
5253
|
+
__name(createBatchStream, "createBatchStream");
|
|
5254
|
+
function createLineStream(options = {}) {
|
|
5255
|
+
const { encoding = "utf8", includeNewlines = false } = options;
|
|
5256
|
+
let buffer = "";
|
|
5257
|
+
return new stream.Transform({
|
|
5258
|
+
objectMode: true,
|
|
5259
|
+
transform(chunk2, _encoding, callback) {
|
|
5260
|
+
const str = buffer + (Buffer.isBuffer(chunk2) ? chunk2.toString(encoding) : chunk2);
|
|
5261
|
+
const lines = str.split(/\r?\n/);
|
|
5262
|
+
buffer = lines.pop() || "";
|
|
5263
|
+
for (const line of lines) {
|
|
5264
|
+
this.push(includeNewlines ? line + "\n" : line);
|
|
5265
|
+
}
|
|
5266
|
+
callback();
|
|
5267
|
+
},
|
|
5268
|
+
flush(callback) {
|
|
5269
|
+
if (buffer) {
|
|
5270
|
+
this.push(buffer);
|
|
5271
|
+
}
|
|
5272
|
+
callback();
|
|
5273
|
+
}
|
|
5274
|
+
});
|
|
5275
|
+
}
|
|
5276
|
+
__name(createLineStream, "createLineStream");
|
|
4420
5277
|
|
|
4421
5278
|
// src/utils/string.utils.ts
|
|
4422
5279
|
function capitalize(str) {
|
|
@@ -4476,6 +5333,84 @@ function countOccurrences(str, substring, caseSensitive = true) {
|
|
|
4476
5333
|
return str.split(substring).length - 1;
|
|
4477
5334
|
}
|
|
4478
5335
|
__name(countOccurrences, "countOccurrences");
|
|
5336
|
+
|
|
5337
|
+
// src/utils/type.utils.ts
|
|
5338
|
+
function isPrimitiveType(value, type) {
|
|
5339
|
+
if (type === "array") {
|
|
5340
|
+
return Array.isArray(value);
|
|
5341
|
+
}
|
|
5342
|
+
if (type === "null") {
|
|
5343
|
+
return value === null;
|
|
5344
|
+
}
|
|
5345
|
+
if (type === "undefined") {
|
|
5346
|
+
return value === void 0;
|
|
5347
|
+
}
|
|
5348
|
+
if (type === "object") {
|
|
5349
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5350
|
+
}
|
|
5351
|
+
return typeof value === type;
|
|
5352
|
+
}
|
|
5353
|
+
__name(isPrimitiveType, "isPrimitiveType");
|
|
5354
|
+
function getTypeOf(value) {
|
|
5355
|
+
if (value === null) return "null";
|
|
5356
|
+
if (value === void 0) return "undefined";
|
|
5357
|
+
if (Array.isArray(value)) return "array";
|
|
5358
|
+
return typeof value;
|
|
5359
|
+
}
|
|
5360
|
+
__name(getTypeOf, "getTypeOf");
|
|
5361
|
+
function isArrayOf(value, itemTypeGuard) {
|
|
5362
|
+
if (!Array.isArray(value)) return false;
|
|
5363
|
+
return value.every((item) => itemTypeGuard(item));
|
|
5364
|
+
}
|
|
5365
|
+
__name(isArrayOf, "isArrayOf");
|
|
5366
|
+
function toStr(value, defaultValue = "") {
|
|
5367
|
+
if (value === null || value === void 0) return defaultValue;
|
|
5368
|
+
try {
|
|
5369
|
+
if (typeof value === "object") {
|
|
5370
|
+
return JSON.stringify(value);
|
|
5371
|
+
}
|
|
5372
|
+
return String(value);
|
|
5373
|
+
} catch {
|
|
5374
|
+
return defaultValue;
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
__name(toStr, "toStr");
|
|
5378
|
+
function toNum(value, defaultValue = 0) {
|
|
5379
|
+
if (value === null || value === void 0) return defaultValue;
|
|
5380
|
+
if (typeof value === "number") return value;
|
|
5381
|
+
try {
|
|
5382
|
+
const num = Number(value);
|
|
5383
|
+
return isNaN(num) ? defaultValue : num;
|
|
5384
|
+
} catch {
|
|
5385
|
+
return defaultValue;
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
__name(toNum, "toNum");
|
|
5389
|
+
function toBool(value, defaultValue = false) {
|
|
5390
|
+
if (value === null || value === void 0) return defaultValue;
|
|
5391
|
+
if (typeof value === "boolean") return value;
|
|
5392
|
+
if (typeof value === "string") {
|
|
5393
|
+
const lowercased = value.toLowerCase();
|
|
5394
|
+
if (lowercased === "true" || lowercased === "yes" || lowercased === "y" || lowercased === "1") {
|
|
5395
|
+
return true;
|
|
5396
|
+
}
|
|
5397
|
+
if (lowercased === "false" || lowercased === "no" || lowercased === "n" || lowercased === "0") {
|
|
5398
|
+
return false;
|
|
5399
|
+
}
|
|
5400
|
+
}
|
|
5401
|
+
if (typeof value === "number") {
|
|
5402
|
+
return value !== 0;
|
|
5403
|
+
}
|
|
5404
|
+
return defaultValue;
|
|
5405
|
+
}
|
|
5406
|
+
__name(toBool, "toBool");
|
|
5407
|
+
function ensureType(value, expectedType, defaultValue) {
|
|
5408
|
+
if (getTypeOf(value) === expectedType) {
|
|
5409
|
+
return value;
|
|
5410
|
+
}
|
|
5411
|
+
return defaultValue;
|
|
5412
|
+
}
|
|
5413
|
+
__name(ensureType, "ensureType");
|
|
4479
5414
|
function appendQueryParams(url$1, params) {
|
|
4480
5415
|
const urlObj = new url.URL(url$1);
|
|
4481
5416
|
for (const [key, value] of Object.entries(params)) {
|
|
@@ -6380,6 +7315,10 @@ exports.RateLimit = RateLimit;
|
|
|
6380
7315
|
exports.Redirect = Redirect;
|
|
6381
7316
|
exports.RedirectResponse = RedirectResponse;
|
|
6382
7317
|
exports.Req = Req;
|
|
7318
|
+
exports.ReqCookie = ReqCookie;
|
|
7319
|
+
exports.ReqHeader = ReqHeader;
|
|
7320
|
+
exports.ReqId = ReqId;
|
|
7321
|
+
exports.ReqLogger = ReqLogger;
|
|
6383
7322
|
exports.RequestTimeoutException = RequestTimeoutException;
|
|
6384
7323
|
exports.Res = Res;
|
|
6385
7324
|
exports.Roles = Roles;
|
|
@@ -6402,8 +7341,10 @@ exports._globalThis = _globalThis;
|
|
|
6402
7341
|
exports.abortable = abortable;
|
|
6403
7342
|
exports.addRedactFields = addRedactFields;
|
|
6404
7343
|
exports.addSensitiveFields = addSensitiveFields;
|
|
7344
|
+
exports.addToDate = addToDate;
|
|
6405
7345
|
exports.appendQueryParams = appendQueryParams;
|
|
6406
7346
|
exports.appendTextFile = appendTextFile;
|
|
7347
|
+
exports.bufferToStream = bufferToStream;
|
|
6407
7348
|
exports.capitalize = capitalize;
|
|
6408
7349
|
exports.chunk = chunk;
|
|
6409
7350
|
exports.circuitBreaker = circuitBreaker;
|
|
@@ -6412,20 +7353,27 @@ exports.copyDir = copyDir;
|
|
|
6412
7353
|
exports.copyFile = copyFile;
|
|
6413
7354
|
exports.countBy = countBy;
|
|
6414
7355
|
exports.countOccurrences = countOccurrences;
|
|
7356
|
+
exports.createBatchStream = createBatchStream;
|
|
6415
7357
|
exports.createChildLogger = createChildLogger;
|
|
6416
7358
|
exports.createDeferred = createDeferred;
|
|
6417
7359
|
exports.createDirectory = createDirectory;
|
|
6418
7360
|
exports.createErrorResponse = createErrorResponse;
|
|
6419
7361
|
exports.createFinalErrorResponse = createFinalErrorResponse;
|
|
6420
7362
|
exports.createHttpError = createHttpError;
|
|
7363
|
+
exports.createLineStream = createLineStream;
|
|
6421
7364
|
exports.createPaginatedResponse = createPaginatedResponse;
|
|
7365
|
+
exports.createParamDecorator = createParamDecorator;
|
|
7366
|
+
exports.createParamDecoratorWithoutParam = createParamDecoratorWithoutParam;
|
|
6422
7367
|
exports.createRequestLogger = createRequestLogger;
|
|
6423
7368
|
exports.createSignedToken = createSignedToken;
|
|
6424
7369
|
exports.createSuccessResponse = createSuccessResponse;
|
|
6425
7370
|
exports.createTaskQueue = createTaskQueue;
|
|
6426
7371
|
exports.createTempDir = createTempDir;
|
|
6427
7372
|
exports.createTempFile = createTempFile;
|
|
7373
|
+
exports.createThrottleStream = createThrottleStream;
|
|
6428
7374
|
exports.createUrlBuilder = createUrlBuilder;
|
|
7375
|
+
exports.dateDiff = dateDiff;
|
|
7376
|
+
exports.daysInMonth = daysInMonth;
|
|
6429
7377
|
exports.debounce = debounce;
|
|
6430
7378
|
exports.decrypt = decrypt;
|
|
6431
7379
|
exports.deepFreeze = deepFreeze;
|
|
@@ -6436,8 +7384,10 @@ exports.deleteFileIfExists = deleteFileIfExists;
|
|
|
6436
7384
|
exports.difference = difference;
|
|
6437
7385
|
exports.emptyDir = emptyDir;
|
|
6438
7386
|
exports.encrypt = encrypt;
|
|
7387
|
+
exports.endOf = endOf;
|
|
6439
7388
|
exports.ensureDir = ensureDir;
|
|
6440
7389
|
exports.ensureEmptyDir = ensureEmptyDir;
|
|
7390
|
+
exports.ensureType = ensureType;
|
|
6441
7391
|
exports.equalsIgnoreCase = equalsIgnoreCase;
|
|
6442
7392
|
exports.errorHandler = errorHandler;
|
|
6443
7393
|
exports.extractFilterParams = extractFilterParams;
|
|
@@ -6452,6 +7402,8 @@ exports.findNewestFile = findNewestFile;
|
|
|
6452
7402
|
exports.findOldestFile = findOldestFile;
|
|
6453
7403
|
exports.flattenDeep = flattenDeep;
|
|
6454
7404
|
exports.flattenObject = flattenObject;
|
|
7405
|
+
exports.formatDate = formatDate;
|
|
7406
|
+
exports.formatRelativeTime = formatRelativeTime;
|
|
6455
7407
|
exports.generateApiKey = generateApiKey;
|
|
6456
7408
|
exports.generateRandomBytes = generateRandomBytes;
|
|
6457
7409
|
exports.generateRandomBytesAsString = generateRandomBytesAsString;
|
|
@@ -6470,6 +7422,7 @@ exports.getPaginationParams = getPaginationParams;
|
|
|
6470
7422
|
exports.getRedactCensor = getRedactCensor;
|
|
6471
7423
|
exports.getRequestId = getRequestId;
|
|
6472
7424
|
exports.getSubdirectories = getSubdirectories;
|
|
7425
|
+
exports.getTypeOf = getTypeOf;
|
|
6473
7426
|
exports.getValueByPath = getValueByPath;
|
|
6474
7427
|
exports.groupBy = groupBy;
|
|
6475
7428
|
exports.hasErrorShape = hasErrorShape;
|
|
@@ -6477,11 +7430,14 @@ exports.hasRequiredProps = hasRequiredProps;
|
|
|
6477
7430
|
exports.hash = hash;
|
|
6478
7431
|
exports.healthCheck = healthCheck;
|
|
6479
7432
|
exports.hmac = hmac;
|
|
7433
|
+
exports.inject = inject;
|
|
6480
7434
|
exports.intersect = intersect;
|
|
6481
7435
|
exports.isAlpha = isAlpha;
|
|
6482
7436
|
exports.isAlphanumeric = isAlphanumeric;
|
|
6483
7437
|
exports.isArray = isArray;
|
|
7438
|
+
exports.isArrayOf = isArrayOf;
|
|
6484
7439
|
exports.isBase64 = isBase64;
|
|
7440
|
+
exports.isBetween = isBetween;
|
|
6485
7441
|
exports.isCreditCard = isCreditCard;
|
|
6486
7442
|
exports.isDateInRange = isDateInRange;
|
|
6487
7443
|
exports.isDirectory = isDirectory;
|
|
@@ -6493,6 +7449,7 @@ exports.isHttpError = isHttpError;
|
|
|
6493
7449
|
exports.isIPv4 = isIPv4;
|
|
6494
7450
|
exports.isIPv6 = isIPv6;
|
|
6495
7451
|
exports.isISODate = isISODate;
|
|
7452
|
+
exports.isLeapYear = isLeapYear;
|
|
6496
7453
|
exports.isLengthBetween = isLengthBetween;
|
|
6497
7454
|
exports.isNumberBetween = isNumberBetween;
|
|
6498
7455
|
exports.isNumeric = isNumeric;
|
|
@@ -6501,6 +7458,7 @@ exports.isObject = isObject;
|
|
|
6501
7458
|
exports.isPhone = isPhone;
|
|
6502
7459
|
exports.isPlainObject = isPlainObject;
|
|
6503
7460
|
exports.isPort = isPort;
|
|
7461
|
+
exports.isPrimitiveType = isPrimitiveType;
|
|
6504
7462
|
exports.isStrongPassword = isStrongPassword;
|
|
6505
7463
|
exports.isURL = isURL;
|
|
6506
7464
|
exports.isUUID = isUUID;
|
|
@@ -6514,6 +7472,7 @@ exports.mapObject = mapObject;
|
|
|
6514
7472
|
exports.mask = mask;
|
|
6515
7473
|
exports.matchesPattern = matchesPattern;
|
|
6516
7474
|
exports.md5 = md5;
|
|
7475
|
+
exports.memoize = memoize;
|
|
6517
7476
|
exports.memoizeAsync = memoizeAsync;
|
|
6518
7477
|
exports.mergeSort = mergeSort;
|
|
6519
7478
|
exports.moveDir = moveDir;
|
|
@@ -6522,6 +7481,7 @@ exports.nanoId = nanoId;
|
|
|
6522
7481
|
exports.normalizeUrl = normalizeUrl;
|
|
6523
7482
|
exports.omit = omit;
|
|
6524
7483
|
exports.parseBooleanParam = parseBooleanParam;
|
|
7484
|
+
exports.parseDate = parseDate;
|
|
6525
7485
|
exports.parseNumberParam = parseNumberParam;
|
|
6526
7486
|
exports.parseQueryString = parseQueryString;
|
|
6527
7487
|
exports.parseTypedQueryParams = parseTypedQueryParams;
|
|
@@ -6565,16 +7525,26 @@ exports.shuffle = shuffle;
|
|
|
6565
7525
|
exports.singletonAsync = singletonAsync;
|
|
6566
7526
|
exports.sleep = sleep;
|
|
6567
7527
|
exports.slugify = slugify;
|
|
7528
|
+
exports.startOf = startOf;
|
|
6568
7529
|
exports.streamFile = streamFile;
|
|
7530
|
+
exports.streamToBuffer = streamToBuffer;
|
|
7531
|
+
exports.streamToString = streamToString;
|
|
6569
7532
|
exports.stripHtml = stripHtml;
|
|
6570
7533
|
exports.take = take;
|
|
6571
7534
|
exports.takeWhile = takeWhile;
|
|
6572
7535
|
exports.throttle = throttle;
|
|
7536
|
+
exports.timeAsync = timeAsync;
|
|
7537
|
+
exports.timeSync = timeSync;
|
|
7538
|
+
exports.timed = timed;
|
|
6573
7539
|
exports.timeout = timeout;
|
|
7540
|
+
exports.toBool = toBool;
|
|
6574
7541
|
exports.toCamelCase = toCamelCase;
|
|
6575
7542
|
exports.toKebabCase = toKebabCase;
|
|
7543
|
+
exports.toNum = toNum;
|
|
6576
7544
|
exports.toPascalCase = toPascalCase;
|
|
6577
7545
|
exports.toSnakeCase = toSnakeCase;
|
|
7546
|
+
exports.toStr = toStr;
|
|
7547
|
+
exports.trackMemoryUsage = trackMemoryUsage;
|
|
6578
7548
|
exports.truncate = truncate;
|
|
6579
7549
|
exports.unique = unique;
|
|
6580
7550
|
exports.uuid = uuid;
|