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